Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commit 6ebf1265 authored by rswindell's avatar rswindell

Introducing sbbs_t::term_supports(), exposed via JS as console.term_supports()

- returns true/false if the user's terminal supports all the passed flags
- returns the supported flags if no flags are passed for comparison
- automatically uses the auto-terminal-type flags if no user is logged-on
parent d1116efe
......@@ -8,7 +8,7 @@
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html *
* Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
......@@ -801,8 +801,11 @@ void sbbs_t::privchat(bool local)
if(!online || sys_status&SS_ABORT)
return;
if(useron.chat&CHAT_SPLITP && useron.misc&ANSI && rows>=24)
if(((sys_status&SS_USERON && useron.chat&CHAT_SPLITP) || !(sys_status&SS_USERON))
&& term_supports(ANSI) && rows>=24)
sys_status|=SS_SPLITP;
else
sys_status&=~SS_SPLITP;
/*
if(!(useron.misc&EXPERT))
menu("privchat");
......
......@@ -8,7 +8,7 @@
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html *
* Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
......@@ -52,7 +52,7 @@ void sbbs_t::redrwstr(char *strin, int i, int l, long mode)
bputs(str);
else
rputs(str);
if(useron.misc&ANSI) {
if(term_supports(ANSI)) {
cleartoeol();
if(i<l)
cursor_left(l-i);
......
......@@ -8,7 +8,7 @@
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html *
* Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
......@@ -174,6 +174,18 @@ void sbbs_t::backspace(void)
console=oldconsole;
}
/****************************************************************************/
/* Returns true if the user (or the yet-to-be-logged-in client) supports */
/* all of the specified terminal 'cmp_flags' (e.g. ANSI, COLOR, RIP). */
/* If no flags specified, returns all terminal flag bits supported */
/****************************************************************************/
long sbbs_t::term_supports(long cmp_flags)
{
long flags = sys_status&SS_USERON ? useron.misc : autoterm;
return(cmp_flags ? ((flags&cmp_flags)==cmp_flags) : (flags&TERM_FLAGS));
}
/****************************************************************************/
/* Outputs character locally and remotely (if applicable), preforming echo */
/* translations (X's and r0dent emulation) if applicable. */
......@@ -198,7 +210,7 @@ void sbbs_t::outchar(char ch)
}
else
outchar_esc=0;
if(useron.misc&NO_EXASCII && ch&0x80)
if(term_supports(NO_EXASCII) && ch&0x80)
ch=sbtbl[(uchar)ch^0x80]; /* seven bit table */
if(ch==FF && lncntr>1 && !tos) {
lncntr=0;
......@@ -233,7 +245,7 @@ void sbbs_t::outchar(char ch)
ch=text[YN][3];
if(text[YN][2]==0 || ch==0) ch='X';
}
if(ch==FF && useron.misc&ANSI) {
if(ch==FF && term_supports(ANSI)) {
putcom("\x1b[2J\x1b[H"); /* clear screen, home cursor */
}
else {
......@@ -300,7 +312,7 @@ void sbbs_t::clearline(void)
int i;
outchar(CR);
if(useron.misc&ANSI)
if(term_supports(ANSI))
rputs("\x1b[K");
else {
for(i=0;i<cols-1;i++)
......@@ -311,7 +323,7 @@ void sbbs_t::clearline(void)
void sbbs_t::cursor_home(void)
{
if(useron.misc&ANSI)
if(term_supports(ANSI))
rputs("\x1b[H");
else
outchar(FF);
......@@ -321,7 +333,7 @@ void sbbs_t::cursor_up(int count)
{
if(count<1)
return;
if(!(useron.misc&ANSI))
if(!term_supports(ANSI))
return;
if(count>1)
rprintf("\x1b[%dA",count);
......@@ -333,7 +345,7 @@ void sbbs_t::cursor_down(int count)
{
if(count<1)
return;
if(!(useron.misc&ANSI))
if(!term_supports(ANSI))
return;
if(count>1)
rprintf("\x1b[%dB",count);
......@@ -345,7 +357,7 @@ void sbbs_t::cursor_right(int count)
{
if(count<1)
return;
if(useron.misc&ANSI) {
if(term_supports(ANSI)) {
if(count>1)
rprintf("\x1b[%dC",count);
else
......@@ -360,7 +372,7 @@ void sbbs_t::cursor_left(int count)
{
if(count<1)
return;
if(useron.misc&ANSI) {
if(term_supports(ANSI)) {
if(count>1)
rprintf("\x1b[%dD",count);
else
......@@ -373,7 +385,7 @@ void sbbs_t::cursor_left(int count)
void sbbs_t::cleartoeol(void)
{
if(useron.misc&ANSI)
if(term_supports(ANSI))
rputs("\x1b[K");
#if 0
else {
......@@ -596,9 +608,9 @@ void sbbs_t::attr(int atr)
{
char str[16];
if(!(useron.misc&ANSI))
if(!term_supports(ANSI))
return;
if(!(useron.misc&COLOR)) { /* eliminate colors if user doesn't have them */
if(!term_supports(COLOR)) { /* eliminate colors if user doesn't have them */
if(atr&LIGHTGRAY) /* if any foreground bits set, set all */
atr|=LIGHTGRAY;
if(atr&BG_LIGHTGRAY) /* if any background bits set, set all */
......
......@@ -321,14 +321,14 @@ void sbbs_t::mnemonics(char *str)
l=0L;
while(str[l]) {
if(str[l]=='~' && str[l+1]!=0) {
if(!(useron.misc&ANSI))
if(!term_supports(ANSI))
outchar('(');
l++;
if(!ctrl_a_codes)
attr(cfg.color[clr_mnehigh]);
outchar(str[l]);
l++;
if(!(useron.misc&ANSI))
if(!term_supports(ANSI))
outchar(')');
if(!ctrl_a_codes)
attr(cfg.color[clr_mnelow]);
......
......@@ -8,7 +8,7 @@
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html *
* Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
......@@ -57,7 +57,7 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
if(!(mode&K_WRAP))
console&=~CON_INSERT;
sys_status&=~SS_ABORT;
if(mode&K_LINE && useron.misc&ANSI && !(mode&K_NOECHO)) {
if(mode&K_LINE && term_supports(ANSI) && !(mode&K_NOECHO)) {
attr(cfg.color[clr_inputline]);
for(i=0;i<maxlen;i++)
outchar(' ');
......@@ -82,7 +82,7 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
attr(i);
}
rputs(str1);
if(mode&K_EDIT && !(mode&(K_LINE|K_AUTODEL)) && useron.misc&ANSI)
if(mode&K_EDIT && !(mode&(K_LINE|K_AUTODEL)) && term_supports(ANSI))
cleartoeol(); /* destroy to eol */
}
......@@ -115,7 +115,7 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
}
}
if(console&CON_INSERT && useron.misc&ANSI && !(mode&K_NOECHO))
if(console&CON_INSERT && term_supports(ANSI) && !(mode&K_NOECHO))
insert_indicator();
while(!(sys_status&SS_ABORT) && online && input_thread_running) {
......@@ -163,7 +163,7 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
outchar(str1[i++]=1);
break;
case CTRL_B: /* Ctrl-B Beginning of Line */
if(useron.misc&ANSI && i && !(mode&K_NOECHO)) {
if(term_supports(ANSI) && i && !(mode&K_NOECHO)) {
cursor_left(i);
i=0;
}
......@@ -194,13 +194,13 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
}
break;
case CTRL_E: /* Ctrl-E End of line */
if(useron.misc&ANSI && i<l) {
if(term_supports(ANSI) && i<l) {
cursor_right(l-i); /* move cursor to eol */
i=l;
}
break;
case CTRL_F: /* Ctrl-F move cursor forewards */
if(i<l && (useron.misc&ANSI)) {
if(i<l && term_supports(ANSI)) {
cursor_right(); /* move cursor right one */
i++;
}
......@@ -330,7 +330,7 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
return(l);
case CTRL_N: /* Ctrl-N Next word */
if(i<l && (useron.misc&ANSI)) {
if(i<l && term_supports(ANSI)) {
x=i;
while(str1[i]!=' ' && i<l)
i++;
......@@ -344,7 +344,7 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
redrwstr(str1,i,l,0);
break;
case CTRL_V: /* Ctrl-V Toggles Insert/Overwrite */
if(!(useron.misc&ANSI) || mode&K_NOECHO)
if(!term_supports(ANSI) || mode&K_NOECHO)
break;
console^=CON_INSERT;
insert_indicator();
......@@ -388,7 +388,7 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
break;
case CTRL_Y: /* Ctrl-Y Delete to end of line */
if(i!=l) { /* if not at EOL */
if(useron.misc&ANSI && !(mode&K_NOECHO))
if(term_supports(ANSI) && !(mode&K_NOECHO))
cleartoeol();
l=i;
break;
......@@ -398,7 +398,7 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
if(mode&K_NOECHO)
l=0;
else {
if(useron.misc&ANSI) {
if(term_supports(ANSI)) {
cursor_left(i);
cleartoeol();
l=0;
......@@ -420,11 +420,11 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
SAFECOPY(str1,undo);
i=l=strlen(str1);
rprintf("\r%s",str1);
if(useron.misc&ANSI)
if(term_supports(ANSI))
cleartoeol(); /* destroy to eol */
break;
case 28: /* Ctrl-\ Previous word */
if(i && (useron.misc&ANSI) && !(mode&K_NOECHO)) {
if(i && term_supports(ANSI) && !(mode&K_NOECHO)) {
x=i;
while(str1[i-1]==' ' && i)
i--;
......@@ -439,7 +439,7 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
console|=CON_LEFTARROW;
break;
}
if((useron.misc&ANSI) && !(mode&K_NOECHO)) {
if(term_supports(ANSI) && !(mode&K_NOECHO)) {
cursor_left(); /* move cursor left one */
i--;
}
......
......@@ -1180,6 +1180,24 @@ js_telnet_cmd(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
return(JS_TRUE);
}
static JSBool
js_term_supports(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
sbbs_t* sbbs;
int32 flags;
if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
if(argc) {
if(!JS_ValueToInt32(cx,argv[0],&flags))
return(JS_FALSE);
*rval = BOOLEAN_TO_JSVAL(sbbs->term_supports(flags));
} else
JS_NewNumberValue(cx,sbbs->term_supports(),rval);
return(JS_TRUE);
}
static jsSyncMethodSpec js_console_functions[] = {
{"inkey", js_inkey, 0, JSTYPE_STRING, JSDOCSTR("[mode=<tt>K_NONE</tt>] [,timeout=<tt>0</tt>]")
......@@ -1367,6 +1385,12 @@ static jsSyncMethodSpec js_console_functions[] = {
,JSDOCSTR("call internal control key handler for specified control key, returns <tt>true</tt> if handled")
,311
},
{"term_supports", js_term_supports, 1, JSTYPE_BOOLEAN, JSDOCSTR("[terminal_flags]")
,JSDOCSTR("either returns <i>bool</i>, indicating whether or not the current user/client "
"supports all the specified <i>terminal_flags</i>, or returns the current user/client's "
"<i>terminal_flags</i> (numeric bit-field) if no <i>terminal_flags</i> were specified")
,314
},
{0}
};
......
......@@ -198,12 +198,12 @@ void sbbs_t::menu(const char *code)
}
strcat(str,code);
strcat(str,".");
sprintf(path,"%s%s",str,useron.misc&WIP ? "wip": useron.misc&RIP ? "rip" : "html");
if(!(useron.misc&(RIP|WIP|HTML)) || !fexistcase(path)) {
sprintf(path,"%s%s",str,term_supports(WIP) ? "wip": term_supports(RIP) ? "rip" : "html");
if(!(term_supports()&(RIP|WIP|HTML)) || !fexistcase(path)) {
sprintf(path,"%smon",str);
if((useron.misc&(COLOR|ANSI))!=ANSI || !fexistcase(path)) {
if((term_supports()&(COLOR|ANSI))!=ANSI || !fexistcase(path)) {
sprintf(path,"%sans",str);
if(!(useron.misc&ANSI) || !fexistcase(path))
if(!term_supports(ANSI) || !fexistcase(path))
sprintf(path,"%sasc",str);
}
}
......
......@@ -491,6 +491,7 @@ public:
void cursor_down(int count=1);
void cursor_left(int count=1);
void cursor_right(int count=1);
long term_supports(long cmp_flags=0);
/* getstr.cpp */
size_t getstr_offset;
......
......@@ -198,7 +198,7 @@ void sbbs_t::sif(char *fname, char *answers, long len)
m++;
}
if((buf[m+1]&0xdf)=='L') { /* Draw line */
if(useron.misc&COLOR)
if(term_supports(COLOR))
attr(cfg.color[clr_inputline]);
else
attr(BLACK|BG_LIGHTGRAY);
......@@ -361,7 +361,7 @@ void sbbs_t::sof(char *fname, char *answers, long len)
else if((buf[m+1]&0xdf)=='N') /* Numbers only */
m++;
if((buf[m+1]&0xdf)=='L') { /* Draw line */
if(useron.misc&COLOR)
if(term_supports(COLOR))
attr(cfg.color[clr_inputline]);
else
attr(BLACK|BG_LIGHTGRAY);
......@@ -386,7 +386,7 @@ void sbbs_t::sof(char *fname, char *answers, long len)
else if((buf[m+1]&0xdf)=='N') /* Numbers only */
m++;
if((buf[m+1]&0xdf)=='L') {
if(useron.misc&COLOR)
if(term_supports(COLOR))
attr(cfg.color[clr_inputline]);
else
attr(BLACK|BG_LIGHTGRAY);
......@@ -495,9 +495,9 @@ size_t sbbs_t::gettmplt(char *strout,char *templt, long mode)
sys_status&=~SS_ABORT;
SAFECOPY(tmplt, templt);
strupr(tmplt);
if(useron.misc&ANSI) {
if(term_supports(ANSI)) {
if(mode&K_LINE) {
if(useron.misc&COLOR)
if(term_supports(COLOR))
attr(cfg.color[clr_inputline]);
else
attr(BLACK|BG_LIGHTGRAY);
......
......@@ -1705,7 +1705,7 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
sigprocmask(SIG_UNBLOCK,&sigs,NULL);
if(!(mode&EX_BIN)) {
static char term_env[256];
if(useron.misc&ANSI)
if(term_supports(ANSI))
sprintf(term_env,"TERM=%s",startup->xtrn_term_ansi);
else
sprintf(term_env,"TERM=%s",startup->xtrn_term_dumb);
......
......@@ -330,8 +330,8 @@ void sbbs_t::xtrndat(char *name, char *dropdir, uchar type, ulong tleft
,cfg.sys_nodes /* Total system nodes */
,cfg.node_num /* Current node */
,tleft /* User Timeleft in seconds */
,useron.misc&ANSI /* User ANSI ? (Yes/Mono/No) */
? useron.misc&COLOR
,term_supports(ANSI) /* User ANSI ? (Yes/Mono/No) */
? term_supports(COLOR)
? "Yes":"Mono":"No"
,rows /* User Screen lines */
,useron.cdt+useron.freecdt); /* User Credits */
......@@ -451,7 +451,7 @@ void sbbs_t::xtrndat(char *name, char *dropdir, uchar type, ulong tleft
,useron.level /* User SL */
,0 /* Cosysop? */
,SYSOP /* Sysop? (1/0) */
,(useron.misc&ANSI) ? 1:0 /* ANSI ? (1/0) */
,term_supports(ANSI) /* ANSI ? (1/0) */
,online==ON_REMOTE); /* Remote (1/0) */
lfexpand(str,misc);
write(file,str,strlen(str));
......@@ -660,7 +660,7 @@ void sbbs_t::xtrndat(char *name, char *dropdir, uchar type, ulong tleft
,tmp /* User's firstname */
,p /* User's lastname */
,useron.location /* User's city */
,(useron.misc&ANSI)==ANSI /* 1=ANSI 0=ASCII */
,term_supports(ANSI) /* 1=ANSI 0=ASCII */
,useron.level /* Security level */
,tleft/60); /* Time left in minutes */
strupr(str);
......@@ -710,7 +710,7 @@ void sbbs_t::xtrndat(char *name, char *dropdir, uchar type, ulong tleft
if(useron.misc&DELETED) c|=(1<<0);
if(useron.misc&CLRSCRN) c|=(1<<1);
if(useron.misc&UPAUSE) c|=(1<<2);
if(useron.misc&ANSI) c|=(1<<3);
if(term_supports(ANSI)) c|=(1<<3);
if(useron.sex=='F') c|=(1<<7);
write(file,&c,1); /* Attrib */
write(file,&useron.flags1,4); /* Flags */
......@@ -798,7 +798,7 @@ void sbbs_t::xtrndat(char *name, char *dropdir, uchar type, ulong tleft
write(file,str,49); /* ChatReason */
c=0;
write(file,&c,1); /* ExternLogoff */
c=useron.misc&ANSI ? 1:0;
c=(char)term_supports(ANSI);
write(file,&c,1); /* ANSI_Capable */
close(file);
}
......@@ -844,7 +844,7 @@ void sbbs_t::xtrndat(char *name, char *dropdir, uchar type, ulong tleft
,useron.location /* User location */
,useron.level /* Security level */
,tleft/60 /* Time left in min */
,useron.misc&ANSI ? "COLOR":"MONO" /* ANSI ??? */
,term_supports(ANSI) ? "COLOR":"MONO" /* ANSI ??? */
,useron.pass /* Password */
,useron.number); /* User number */
lfexpand(str,misc);
......@@ -1002,7 +1002,7 @@ void sbbs_t::xtrndat(char *name, char *dropdir, uchar type, ulong tleft
,cfg.com_port /* COM Port number */
,' ' /* Reserved */
,' ' /* "" */
,(useron.misc&ANSI)==ANSI /* 1=ANSI 0=NO ANSI */
,term_supports(ANSI) /* 1=ANSI 0=NO ANSI */
,"01-01-80" /* last event date */
,0,0 /* last event minute */
,0 /* caller exited to dos */
......@@ -1158,7 +1158,7 @@ void sbbs_t::xtrndat(char *name, char *dropdir, uchar type, ulong tleft
"%s\n%s\n%lu\n%s\n%u\n%u\n%u\n%u\n%u\n%lu\n%u\n"
"%lu\n%lu\n%s\n%s\n"
,dropdir
,useron.misc&ANSI ? "TRUE":"FALSE" /* ANSI ? True or False */
,term_supports(ANSI) ? "TRUE":"FALSE" /* ANSI ? True or False */
,useron.level /* Security level */
,useron.uls /* Total uploads */
,useron.dls /* Total downloads */
......@@ -1224,8 +1224,8 @@ void sbbs_t::xtrndat(char *name, char *dropdir, uchar type, ulong tleft
sprintf(str,"%s\n%d\n%d\n%lu\n%lu\n%u\n%lu\n"
,name /* Complete name of user */
,useron.misc&ANSI ? 1:0 /* ANSI ? */
,useron.misc&NO_EXASCII ? 0:1 /* IBM characters ? */
,term_supports(ANSI) /* ANSI ? */
,term_supports(NO_EXASCII) ? 0:1 /* IBM characters ? */
,rows /* Page length */
,dte_rate /* Baud rate */
,online==ON_LOCAL ? 0:cfg.com_port /* COM port */
......@@ -1252,7 +1252,7 @@ void sbbs_t::xtrndat(char *name, char *dropdir, uchar type, ulong tleft
,useron.pass /* User's password */
,useron.level /* User's level */
,useron.misc&EXPERT ? 'Y':'N' /* Expert? */
,useron.misc&ANSI ? 'Y':'N' /* ANSI? */
,term_supports(ANSI) ? 'Y':'N' /* ANSI? */
,tleft/60 /* Minutes left */
,useron.phone /* User's phone number */
,useron.location /* User's city and state */
......@@ -1301,7 +1301,7 @@ void sbbs_t::xtrndat(char *name, char *dropdir, uchar type, ulong tleft
,name
,useron.level
,tleft/60
,useron.misc&ANSI ? 1 : 0
,term_supports(ANSI)
,cfg.node_num);
lfexpand(str,misc);
write(file,str,strlen(str));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment