void sbbs_t::cursor_home(void) { if(term_supports(ANSI)) rputs("\x1b[H"); else outchar(FF); /* this will clear some terminals, do nothing with others */ }
void sbbs_t::mnemonics(char *str) { char *ctrl_a_codes; long l; if(!strchr(str,'~')) { mnestr=str; bputs(str); return; } ctrl_a_codes=strchr(str,1); if(!ctrl_a_codes) { if(str[0]=='@' && str[strlen(str)-1]=='@' && !strchr(str,' ')) { mnestr=str; bputs(str); return; } attr(cfg.color[clr_mnelow]); } l=0L; while(str[l]) { if(str[l]=='~' && str[l+1]!=0) { if(!term_supports(ANSI)) outchar('('); l++; if(!ctrl_a_codes) attr(cfg.color[clr_mnehigh]); outchar(str[l]); l++; if(!term_supports(ANSI)) outchar(')'); if(!ctrl_a_codes) attr(cfg.color[clr_mnelow]); } else { if(str[l]==CTRL_A /* ctrl-a */ && str[l+1]!=0) { /* valid */ ctrl_a(str[++l]); /* skip the ctrl-a */ l++; /* skip the attribute code */ } else outchar(str[l++]); } } if(!ctrl_a_codes) attr(cfg.color[clr_mnecmd]); }
void sbbs_t::attr(int atr) { char str[16]; if(!term_supports(ANSI)) return; rputs(ansi(atr,curatr,str)); curatr=atr; }
void sbbs_t::cursor_down(int count) { if(count<1) return; if(!term_supports(ANSI)) return; if(count>1) rprintf("\x1b[%dB",count); else rputs("\x1b[B"); }
void sbbs_t::cleartoeol(void) { int i,j; if(term_supports(ANSI)) rputs("\x1b[K"); else { i=j=column; while(++i<cols) outcom(' '); while(++j<cols) outcom(BS); } }
void sbbs_t::cursor_right(int count) { if(count<1) return; if(term_supports(ANSI)) { if(count>1) rprintf("\x1b[%dC",count); else rputs("\x1b[C"); } else { for(int i=0;i<count;i++) outcom(' '); } column+=count; }
void sbbs_t::cursor_left(int count) { if(count<1) return; if(term_supports(ANSI)) { if(count>1) rprintf("\x1b[%dD",count); else rputs("\x1b[D"); } else { for(int i=0;i<count;i++) outcom('\b'); } if(column > count) column-=count; else column=0; }
void sbbs_t::outchar(char ch) { int i; if(console&CON_ECHO_OFF) return; if(ch==ESC) outchar_esc=1; else if(outchar_esc==1) { if(ch=='[') outchar_esc++; else outchar_esc=0; } else if(outchar_esc==2) { if(ch>='@' && ch<='~') outchar_esc++; } else outchar_esc=0; if(term_supports(NO_EXASCII) && ch&0x80) ch=exascii_to_ascii_char(ch); /* seven bit table */ if(ch==FF && lncntr>1 && !tos) { lncntr=0; CRLF; if(!(sys_status&SS_PAUSEOFF)) { pause(); while(lncntr && online && !(sys_status&SS_ABORT)) pause(); } } if(online==ON_REMOTE && console&CON_R_ECHO) { if(console&CON_R_ECHOX && (uchar)ch>=' ' && !outchar_esc) { ch=text[YN][3]; if(text[YN][2]==0 || ch==0) ch='X'; } if(ch==FF && term_supports(ANSI)) { putcom("\x1b[2J\x1b[H"); /* clear screen, home cursor */ } else { if(ch==(char)TELNET_IAC && !(telnet_mode&TELNET_MODE_OFF)) outcom(TELNET_IAC); /* Must escape Telnet IAC char (255) */ i=0; while(outcom(ch)&TXBOF && i<1440) { /* 3 minute pause delay */ if(!online) break; i++; if(sys_status&SS_SYSPAGE) sbbs_beep(i,80); else mswait(80); } if(i==1440) { /* timeout - beep flush outbuf */ i=rioctl(TXBC); lprintf(LOG_NOTICE,"timeout(outchar) %04X %04X\r\n",i,rioctl(IOFO)); outcom(BEL); rioctl(IOCS|PAUSE); } } } if(!outchar_esc) { if((uchar)ch>=' ') column++; else if(ch=='\r') column=0; else if(ch=='\b') { if(column) column--; } } if(ch==LF || column>=cols) { lncntr++; lbuflen=0; tos=0; column=0; } else if(ch==FF) { lncntr=0; lbuflen=0; tos=1; column=0; } else { if(!lbuflen) latr=curatr; if(lbuflen<LINE_BUFSIZE) lbuf[lbuflen++]=ch; } if(outchar_esc==3) outchar_esc=0; if(lncntr==rows-1 && ((useron.misc&UPAUSE) || sys_status&SS_PAUSEON) && !(sys_status&SS_PAUSEOFF)) { lncntr=0; pause(); } }
size_t sbbs_t::gettmplt(char *strout,char *templt, long mode) { char ch,str[256]; char tmplt[128]; uint t=strlen(templt),c=0; sys_status&=~SS_ABORT; SAFECOPY(tmplt, templt); strupr(tmplt); if(term_supports(ANSI)) { if(mode&K_LINE) { if(term_supports(COLOR)) attr(cfg.color[clr_inputline]); else attr(BLACK|BG_LIGHTGRAY); } while(c<t) { if(tmplt[c]=='N' || tmplt[c]=='A' || tmplt[c]=='!') outchar(' '); else outchar(tmplt[c]); c++; } cursor_left(t); } c=0; if(mode&K_EDIT) { strcpy(str,strout); bputs(str); c=strlen(str); } while((ch=getkey(mode))!=CR && online && !(sys_status&SS_ABORT)) { if(ch==BS || ch==DEL) { if(!c) continue; for(ch=1,c--;c;c--,ch++) if(tmplt[c]=='N' || tmplt[c]=='A' || tmplt[c]=='!') break; cursor_left(ch); bputs(" \b"); continue; } if(ch==CTRL_X) { for(;c;c--) { outchar(BS); if(tmplt[c-1]=='N' || tmplt[c-1]=='A' || tmplt[c-1]=='!') bputs(" \b"); } } else if(c<t) { if(tmplt[c]=='N' && !isdigit(ch)) continue; if(tmplt[c]=='A' && !isalpha(ch)) continue; outchar(ch); str[c++]=ch; while(c<t && tmplt[c]!='N' && tmplt[c]!='A' && tmplt[c]!='!'){ str[c]=tmplt[c]; outchar(tmplt[c++]); } } } str[c]=0; attr(LIGHTGRAY); CRLF; if(!(sys_status&SS_ABORT)) strcpy(strout,str); return(c); }
void sbbs_t::sof(char *fname, char *answers, long len) { char str[256],*buf,max,min,cr; int file; long length,l=0,m,a=0; sprintf(str,"%s%s.sif",cfg.text_dir,fname); if((file=nopen(str,O_RDONLY))==-1) { errormsg(WHERE,ERR_OPEN,str,O_RDONLY); answers[0]=0; return; } length=filelength(file); if((buf=(char *)malloc(length))==0) { close(file); errormsg(WHERE,ERR_ALLOC,str,length); answers[0]=0; return; } if(lread(file,buf,length)!=length) { close(file); errormsg(WHERE,ERR_READ,str,length); answers[0]=0; return; } close(file); while(l<length && online) { min=max=cr=0; while(l<length && buf[l++]!=STX); for(m=l;m<length;m++) if(buf[m]==ETX || !buf[m]) { buf[m]=0; break; } if(l>=length) break; if(online==ON_REMOTE) { rioctl(IOCM|ABORT); rioctl(IOCS|ABORT); } putmsg(buf+l,P_SAVEATR); m++; if(toupper(buf[m])!='C' && toupper(buf[m])!='S') continue; SYNC; if(online==ON_REMOTE) rioctl(IOSM|ABORT); if(a>=len) { bprintf("\r\nSOF: %s defined more data than buffer size " "(%lu bytes)\r\n",fname,len); break; } if((buf[m]&0xdf)=='C') { if((buf[m+1]&0xdf)=='U') /* Uppercase only */ m++; else if((buf[m+1]&0xdf)=='N') /* Numbers only */ m++; if((buf[m+1]&0xdf)=='L') { /* Draw line */ if(term_supports(COLOR)) attr(cfg.color[clr_inputline]); else attr(BLACK|BG_LIGHTGRAY); bputs(" \b"); m++; } if((buf[m+1]&0xdf)=='R') { /* Add CRLF */ cr=1; m++; } outchar(answers[a++]); attr(LIGHTGRAY); CRLF; if(cr) a+=2; } else if((buf[m]&0xdf)=='S') { /* String */ if((buf[m+1]&0xdf)=='U') m++; else if((buf[m+1]&0xdf)=='F') m++; else if((buf[m+1]&0xdf)=='N') /* Numbers only */ m++; if((buf[m+1]&0xdf)=='L') { if(term_supports(COLOR)) attr(cfg.color[clr_inputline]); else attr(BLACK|BG_LIGHTGRAY); m++; } if((buf[m+1]&0xdf)=='R') { cr=1; m++; } if(isdigit(buf[m+1])) { max=buf[++m]&0xf; if(isdigit(buf[m+1])) max=max*10+(buf[++m]&0xf); } if(buf[m+1]=='.' && isdigit(buf[m+2])) { m++; min=buf[++m]&0xf; if(isdigit(buf[m+1])) min=min*10+(buf[++m]&0xf); } if(buf[m+1]=='"') { max=0; m++; while(buf[++m]!='"' && max<80) max++; } if(!max) continue; getrec(answers,a,max,str); bputs(str); attr(LIGHTGRAY); CRLF; if(!cr) a+=max; else a+=max+2; } } free((char *)buf); }
void sbbs_t::sif(char *fname, char *answers, long len) { char str[256],tmplt[256],*buf; uint t,max,min,mode,cr; int file; long length,l=0,m,top,a=0; sprintf(str,"%s%s.sif",cfg.text_dir,fname); if((file=nopen(str,O_RDONLY))==-1) { errormsg(WHERE,ERR_OPEN,str,O_RDONLY); answers[0]=0; return; } length=filelength(file); if((buf=(char *)malloc(length))==0) { close(file); errormsg(WHERE,ERR_ALLOC,str,length); answers[0]=0; return; } if(lread(file,buf,length)!=length) { close(file); errormsg(WHERE,ERR_READ,str,length); answers[0]=0; return; } close(file); while(l<length && online) { mode=min=max=t=cr=0; top=l; while(l<length && buf[l++]!=STX); for(m=l;m<length;m++) if(buf[m]==ETX || !buf[m]) { buf[m]=0; break; } if(l>=length) break; if(online==ON_REMOTE) { rioctl(IOCM|ABORT); rioctl(IOCS|ABORT); } putmsg(buf+l,P_SAVEATR); m++; if(toupper(buf[m])!='C' && toupper(buf[m])!='S') continue; SYNC; if(online==ON_REMOTE) rioctl(IOSM|ABORT); if(a>=len) { errormsg(WHERE,ERR_LEN,fname,len); break; } if((buf[m]&0xdf)=='C') { if((buf[m+1]&0xdf)=='U') { /* Uppercase only */ mode|=K_UPPER; m++; } else if((buf[m+1]&0xdf)=='N') { /* Numbers only */ mode|=K_NUMBER; m++; } if((buf[m+1]&0xdf)=='L') { /* Draw line */ if(term_supports(COLOR)) attr(cfg.color[clr_inputline]); else attr(BLACK|BG_LIGHTGRAY); bputs(" \b"); m++; } if((buf[m+1]&0xdf)=='R') { /* Add CRLF */ cr=1; m++; } if(buf[m+1]=='"') { m+=2; for(l=m;l<length;l++) if(buf[l]=='"') { buf[l]=0; break; } answers[a++]=(char)getkeys((char *)buf+m,0); } else { answers[a]=getkey(mode); outchar(answers[a++]); attr(LIGHTGRAY); CRLF; } if(cr) { answers[a++]=CR; answers[a++]=LF; } } else if((buf[m]&0xdf)=='S') { /* String */ if((buf[m+1]&0xdf)=='U') { /* Uppercase only */ mode|=K_UPPER; m++; } else if((buf[m+1]&0xdf)=='F') { /* Force Upper/Lowr case */ mode|=K_UPRLWR; m++; } else if((buf[m+1]&0xdf)=='N') { /* Numbers only */ mode|=K_NUMBER; m++; } if((buf[m+1]&0xdf)=='L') { /* Draw line */ mode|=K_LINE; m++; } if((buf[m+1]&0xdf)=='R') { /* Add CRLF */ cr=1; m++; } if(isdigit(buf[m+1])) { max=buf[++m]&0xf; if(isdigit(buf[m+1])) max=max*10+(buf[++m]&0xf); } if(buf[m+1]=='.' && isdigit(buf[m+2])) { m++; min=buf[++m]&0xf; if(isdigit(buf[m+1])) min=min*10+(buf[++m]&0xf); } if(buf[m+1]=='"') { m++; mode&=~K_NUMBER; while(buf[++m]!='"' && t<80) tmplt[t++]=buf[m]; tmplt[t]=0; max=strlen(tmplt); } if(t) { if(gettmplt(str,tmplt,mode)<min) { l=top; continue; } } else { if(!max) continue; if(getstr(str,max,mode)<min) { l=top; continue; } } if(!cr) { for(cr=0;str[cr];cr++) answers[a+cr]=str[cr]; while(cr<max) answers[a+cr++]=ETX; a+=max; } else { putrec(answers,a,max,str); putrec(answers,a+max,2,crlf); a+=max+2; } } } answers[a]=0; free((char *)buf); }