Newer
Older
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
char *in;
size_t out;
if(!cachedirlen) {
strcpy(cachedir,"file:");
get_syncterm_filename(cachedir+5, sizeof(cachedir)-5, SYNCTERM_PATH_CACHE, FALSE);
cachedirlen=strlen(cachedir);
html_cleanup();
}
if(!memcmp(uri, cachedir, cachedirlen)) {
/* Reading from the cache... no redirect */
return(URL_ACTION_ISGOOD);
}
strncpy(buf, cachedir, bufsize);
buf[bufsize-1]=0;
backslash(buf);
/* Append mangledname */
in=(char *)uri;
out=strlen(buf);
while(*in && out < bufsize-1) {
char ch;
ch=*(in++);
if(ch < ' ')
ch='^';
if(ch > 126)
ch='~';
switch(ch) {
case '*':
case '?':
case ':':
case '[':
case ']':
case '"':
case '<':
case '>':
case '|':
case '(':
case ')':
case '{':
case '}':
case '/':
case '\\':
buf[out++]='_';
break;
default:
buf[out++]=ch;
}
}
buf[out]=0;
/* We now have the cache filename... does it already exist? */
if(fexist(buf+5))
return(URL_ACTION_REDIRECT);
/* If not, we need to fetch it... convert relative URIs */
if(strstr(uri,"://")) {
/* Good URI */
strncpy(uribuf, uri, uribufsize);
uribuf[uribufsize-1]=0;
return(URL_ACTION_DOWNLOAD);
}
strcpy(uribuf, "http://");
if(html_addr)
strcat(uribuf, html_addr);
if(uri[0]!='/')
strcat(uribuf, "/");
strcat(uribuf,uri);
return(URL_ACTION_DOWNLOAD);
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
#define OUTBUF_SIZE 2048
#ifdef WITH_WXWIDGETS
#define WRITE_OUTBUF() \
if(outbuf_size > 0) { \
cterm_write(outbuf, outbuf_size, prn, sizeof(prn), &speed); \
outbuf_size=0; \
if(html_mode==HTML_MODE_RAISED) { \
if(html_startx != wherex() || html_starty != wherey()) { \
iconize_html(); \
html_mode=HTML_MODE_ICONIZED; \
} \
} \
if(prn[0]) \
conn_send(prn, strlen(prn), 0); \
updated=TRUE; \
}
#else
#define WRITE_OUTBUF() \
if(outbuf_size > 0) { \
cterm_write(outbuf, outbuf_size, prn, sizeof(prn), &speed); \
outbuf_size=0; \
if(prn[0]) \
conn_send(prn, strlen(prn), 0); \
updated=TRUE; \
}
#endif
BOOL doterm(struct bbslist *bbs)
{
unsigned char ch[2];
unsigned char outbuf[OUTBUF_SIZE];
size_t outbuf_size=0;
unsigned char prn[ANSI_REPLY_BUFSIZE];
int key;
int i,j;
unsigned char *p,*p2;
BYTE zrqinit[] = { ZDLE, ZHEX, '0', '0', 0 }; /* for Zmodem auto-downloads */
BYTE zrinit[] = { ZDLE, ZHEX, '0', '1', 0 }; /* for Zmodem auto-uploads */
#ifdef GUTS_BUILTIN
BYTE gutsinit[] = { ESC, '[', '{' }; /* For GUTS auto-transfers */
#ifdef WITH_WXWIDGETS
BYTE htmldetect[]="\2\2?HTML?";
BYTE htmlresponse[]="\2\2!HTML!";
BYTE htmlstart[]="\2\2<HTML>";
BYTE htmldet[sizeof(htmldetect)];
int html_startx;
int html_starty;
long double nextchar=0;
long double lastchar=0;
long double thischar=0;
int speed;
#ifndef WITHOUT_OOII
BYTE ooii_buf[256];
BYTE ooii_init1[] = "\xdb\b \xdb\b \xdb\b[\xdb\b[\xdb\b \xdb\bM\xdb\ba\xdb\bi\xdb\bn\xdb\bt\xdb\be\xdb\bn\xdb\ba\xdb\bn\xdb\bc\xdb\be\xdb\b \xdb\bC\xdb\bo\xdb\bm\xdb\bp\xdb\bl\xdb\be\xdb\bt\xdb\be\xdb\b \xdb\b]\xdb\b]\xdb\b \b\r\n\r\n\r\n\x1b[0;0;36mDo you have the Overkill Ansiterm installed? (y/N) \xe9 "; /* for OOII auto-enable */
BYTE ooii_init2[] = "\xdb\b \xdb\b \xdb\b[\xdb\b[\xdb\b \xdb\bM\xdb\ba\xdb\bi\xdb\bn\xdb\bt\xdb\be\xdb\bn\xdb\ba\xdb\bn\xdb\bc\xdb\be\xdb\b \xdb\bC\xdb\bo\xdb\bm\xdb\bp\xdb\bl\xdb\be\xdb\bt\xdb\be\xdb\b \xdb\b]\xdb\b]\xdb\b \b\r\n\r\n\x1b[0m\x1b[2J\r\n\r\n\x1b[0;1;30mHX Force retinal scan in progress ... \x1b[0;0;30m"; /* for OOII auto-enable */
recv_byte_buffer_len=recv_byte_buffer_pos=0;
if(bbs->conn_type == CONN_TYPE_SERIAL)
log_level = bbs->xfer_loglevel;
conn_api.log_level = bbs->telnet_loglevel;
p=(unsigned char *)realloc(scrollback_buf, term.width*2*settings.backlines);
if(p != NULL) {
scrollback_buf=p;
memset(scrollback_buf,0,term.width*2*settings.backlines);
}
else
FREE_AND_NULL(scrollback_buf);
scrollback_lines=0;
scrollback_mode=txtinfo.currmode;
switch(bbs->screen_mode) {
case SCREEN_MODE_C64:
case SCREEN_MODE_C128_40:
case SCREEN_MODE_C128_80:
emulation = CTERM_EMULATION_PETASCII;
break;
case SCREEN_MODE_ATARI:
case SCREEN_MODE_ATARI_XEP80:
emulation = CTERM_EMULATION_ATASCII;
break;
cterm_init(term.height,term.width,term.x-1,term.y-1,settings.backlines,scrollback_buf, emulation);
ch[1]=0;
#ifndef WITHOUT_OOII
ooii_buf[0]=0;
#endif
#ifdef GUTS_BUILTIN
gutsbuf[0]=0;
#endif
#ifdef WITH_WXWIDGETS
/* Main input loop */
for(;;) {
update_status(bbs, (bbs->conn_type == CONN_TYPE_SERIAL)?bbs->bpsrate:speed, ooii_mode);
for(remain=count_data_waiting() /* Hack for connection check */ + (!is_connected(NULL)); remain; remain--) {
if(speed)
thischar=xp_timer();
if((!speed) || thischar < lastchar /* Wrapped */ || thischar >= nextchar) {
/* Get remote input */
inch=recv_byte(NULL, 0);
switch(inch) {
case -1:
#ifdef WITH_WXWIDGETS
if(html_mode != HTML_MODE_HIDDEN) {
html_mode=HTML_MODE_HIDDEN;
uifcmsg("Disconnected","`Disconnected`\n\nRemote host dropped connection");
cterm_clearscreen(cterm.attr); /* Clear screen into scrollback */
scrollback_lines=cterm.backpos;
cterm_end();
conn_close();
hidemouse();
return(FALSE);
}
break;
default:
if(speed) {
lastchar = xp_timer();
nextchar = lastchar + 1/(long double)(speed/10);
}
j=strlen(gutsbuf);
if(inch == gutsinit[j]) {
gutsbuf[j]=inch;
gutsbuf[++j]=0;
if(j==sizeof(gutsinit)) { /* Have full sequence */
#ifdef WITH_WXWIDGETS
html_startx=wherex();
html_starty=wherey();
j=strlen(htmldet);
if(inch == htmldetect[j] || toupper(inch)==htmlstart[j]) {
htmldet[j]=inch;
htmldet[++j]=0;
if(j==sizeof(htmldetect)-1) {
if(!strcmp(htmldet, htmldetect)) {
if(html_supported==HTML_SUPPORT_UNKNOWN) {
int width,height,xpos,ypos;
html_addr=bbs->addr;
get_window_info(&width, &height, &xpos, &ypos);
if(!run_html(width, height, xpos, ypos, html_send, html_urlredirect))
html_supported=HTML_SUPPORTED;
else
html_supported=HTML_NOTSUPPORTED;
if(html_supported==HTML_SUPPORTED) {
conn_send(htmlresponse, sizeof(htmlresponse)-1, 0);
hide_html();
else {
show_html("");
html_mode=HTML_MODE_READING;
}
htmldet[0]=0;
j=strlen(zrqbuf);
if(inch == zrqinit[j] || inch == zrinit[j]) {
zrqbuf[j]=inch;
zrqbuf[++j]=0;
if(j==sizeof(zrqinit)-1) { /* Have full sequence (Assumes zrinit and zrqinit are same length */
if(!strcmp(zrqbuf, zrqinit))
zmodem_download(bbs);
else
begin_upload(bbs, TRUE, inch);
zrqbuf[0]=0;
remain=1;
#ifndef WITHOUT_OOII
if(ooii_mode) {
if(ooii_buf[0]==0) {
if(inch == 0xab) {
ooii_buf[0]=inch;
ooii_buf[1]=0;
continue;
}
}
else { /* Already have the start of the sequence */
j=strlen(ooii_buf);
if(j+1 >= sizeof(ooii_buf))
j--;
ooii_buf[j++]=inch;
ooii_buf[j]=0;
if(inch == '|') {
if(handle_ooii_code(ooii_buf, &ooii_mode, prn, sizeof(prn))) {
xptone_close();
}
ooii_buf[0]=0;
}
continue;
}
}
else {
j=strlen(ooii_buf);
if(inch==ooii_init1[j]) {
ooii_buf[j++]=inch;
ooii_buf[j]=0;
if(ooii_init1[j]==0) {
if(strcmp(ooii_buf, ooii_init1)==0) {
xptone_open();
}
ooii_buf[0]=0;
}
}
else if(inch==ooii_init2[j]) {
ooii_buf[j++]=inch;
ooii_buf[j]=0;
if(strcmp(ooii_buf, ooii_init2)==0) {
xptone_open();
}
if(outbuf_size >= sizeof(outbuf))
WRITE_OUTBUF();
outbuf[outbuf_size++]=inch;
continue;
}
}
else {
if (speed)
sleep=FALSE;
break;
/* Get local input */
gotoxy(wherex(), wherey());
key=getch();
key|=getch()<<8;
if(cterm.doorway_mode && ((key & 0xff) == 0) && key != 0x2c00 /* ALT-Z */) {
ch[0]=0;
ch[1]=key>>8;
conn_send(ch,2,0);
/* These keys are SyncTERM control keys */
/* key is set to zero if consumed */
switch(key) {
case CIO_KEY_MOUSE:
getmouse(&mevent);
switch(mevent.event) {
case CIOLIB_BUTTON_1_DRAG_START:
break;
case CIOLIB_BUTTON_2_CLICK:
case CIOLIB_BUTTON_3_CLICK:
p=getcliptext();
if(p!=NULL) {
for(p2=p; *p2; p2++) {
if(*p2=='\n') {
/* If previous char was not \r, send a \r */
if(p2==p || *(p2-1)!='\r')
conn_send("\r",1,0);
}
else
conn_send(p2,1,0);
}
free(p);
}
break;
case 0x3000: /* ALT-B - Scrollback */
viewscroll();
break;
case 0x2e00: /* ALT-C - Capture */
capture_control(bbs);
break;
case 0x2000: /* ALT-D - Download */
case 0x1200: /* ALT-E */
{
p=(char *)malloc(txtinfo.screenheight*txtinfo.screenwidth*2);
if(p) {
gettext(1,1,txtinfo.screenwidth,txtinfo.screenheight,p);
puttext(1,1,txtinfo.screenwidth,txtinfo.screenheight,p);
free(p);
showmouse();
_setcursortype(_NORMALCURSOR);
case 0x2100: /* ALT-F */
font_control(bbs);
case 0x2600: /* ALT-L */
if(bbs->conn_type != CONN_TYPE_RLOGIN && bbs->conn_type != CONN_TYPE_RLOGIN_REVERSED && bbs->conn_type != CONN_TYPE_SSH) {
if(bbs->user[0]) {
conn_send(bbs->user,strlen(bbs->user),0);
conn_send(cterm.emulation==CTERM_EMULATION_ATASCII?"\x9b":"\r",1,0);
SLEEP(10);
}
if(bbs->password[0]) {
conn_send(bbs->password,strlen(bbs->password),0);
conn_send(cterm.emulation==CTERM_EMULATION_ATASCII?"\x9b":"\r",1,0);
SLEEP(10);
}
}
if(bbs->syspass[0]) {
conn_send(bbs->syspass,strlen(bbs->syspass),0);
conn_send(cterm.emulation==CTERM_EMULATION_ATASCII?"\x9b":"\r",1,0);
case 0x3200: /* ALT-M */
music_control(bbs);
case 0x1600: /* ALT-U - Upload */
begin_upload(bbs, FALSE, inch);
if(cio_api.mode!=CIOLIB_MODE_CURSES
&& cio_api.mode!=CIOLIB_MODE_CURSES_IBM
&& cio_api.mode!=CIOLIB_MODE_ANSI) {
break;
}
/* FALLTHROUGH for curses/ansi modes */
case 0x2d00: /* Alt-X - Exit */
case 0x2300: /* Alt-H - Hangup */
{
char *opts[3]={
"Yes"
,"No"
,""
};
char *buf;
buf=(char *)alloca(txtinfo.screenheight*txtinfo.screenwidth*2);
gettext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf);
i=0;
init_uifc(FALSE, FALSE);
uifc.helpbuf="Selecting Yes closes the connection\n";
if(uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,NULL,"Disconnect... Are you sure?",opts)==0) {
#ifdef WITH_WXWIDGETS
if(html_mode != HTML_MODE_HIDDEN) {
html_mode=HTML_MODE_HIDDEN;
cterm_clearscreen(cterm.attr); /* Clear screen into scrollback */
scrollback_lines=cterm.backpos;
return(key==0x2d00 /* Alt-X? */);
puttext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf);
window(txtinfo.winleft,txtinfo.wintop,txtinfo.winright,txtinfo.winbottom);
textattr(txtinfo.attribute);
gotoxy(txtinfo.curx,txtinfo.cury);
case 19: /* CTRL-S */
if(cio_api.mode!=CIOLIB_MODE_CURSES
&& cio_api.mode!=CIOLIB_MODE_CURSES_IBM
&& cio_api.mode!=CIOLIB_MODE_ANSI) {
break;
}
/* FALLTHROUGH for curses/ansi modes */
i=wherex();
j=wherey();
case -1:
#ifdef WITH_WXWIDGETS
if(html_mode != HTML_MODE_HIDDEN) {
html_mode=HTML_MODE_HIDDEN;
cterm_clearscreen(cterm.attr); /* Clear screen into scrollback */
scrollback_lines=cterm.backpos;
cterm_end();
begin_upload(bbs, FALSE, inch);
zmodem_download(bbs);
capture_control(bbs);
break;
case 8:
font_control(bbs);
break;
case 10:
cterm.doorway_mode=!cterm.doorway_mode;
break;
#ifdef WITHOUT_OOII
if(ooii_mode > MAX_OOII_MODE) {
xptone_close();
}
else
xptone_open();
break;
case 12:
#endif
#ifdef WITH_WXWIDGETS
if(html_mode != HTML_MODE_HIDDEN) {
html_mode=HTML_MODE_HIDDEN;
cterm_clearscreen(cterm.attr); /* Clear screen into scrollback */
scrollback_lines=cterm.backpos;
cterm_end();
conn_close();
#else
case 13:
#endif
{
p=(char *)malloc(txtinfo.screenheight*txtinfo.screenwidth*2);
if(p) {
gettext(1,1,txtinfo.screenwidth,txtinfo.screenheight,p);
puttext(1,1,txtinfo.screenwidth,txtinfo.screenheight,p);
free(p);
}
}
break;
gotoxy(i,j);
case 0x9800: /* ALT-Up */
if(bbs->conn_type != CONN_TYPE_SERIAL) {
if(speed)
speed=rates[get_rate_num(speed)+1];
else
speed=rates[0];
key = 0;
}
break;
case 0xa000: /* ALT-Down */
if(bbs->conn_type != CONN_TYPE_SERIAL) {
i=get_rate_num(speed);
if(i==0)
speed=0;
else
speed=rates[i-1];
key = 0;
}
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
if(key && cterm.emulation == CTERM_EMULATION_ATASCII) {
/* Translate keys to ATASCII */
switch(key) {
case '\r':
case '\n':
ch[0]=155;
conn_send(ch,1,0);
break;
case CIO_KEY_DOWN:
ch[0]=29;
conn_send(ch,1,0);
break;
case CIO_KEY_DC: /* "Delete" key */
case '\b': /* Backspace */
ch[0]=126;
conn_send(ch,1,0);
break;
case CIO_KEY_RIGHT:
ch[0]=31;
conn_send(ch,1,0);
break;
case CIO_KEY_UP:
ch[0]=28;
conn_send(ch,1,0);
break;
case CIO_KEY_LEFT:
ch[0]=30;
conn_send(ch,1,0);
break;
case '\t':
ch[0]=127;
conn_send(ch,1,0);
break;
default:
if(key<256) {
/* ASCII Translation */
if(key<32) {
break;
}
else if(key<123) {
conn_send(ch,1,0);
}
}
break;
}
}
else if(key && cterm.emulation == CTERM_EMULATION_PETASCII) {
/* Translate keys to PETSCII */
switch(key) {
case '\r':
case '\n':
ch[0]=13;
conn_send(ch,1,0);
break;
case CIO_KEY_DOWN:
ch[0]=17;
conn_send(ch,1,0);
break;
case CIO_KEY_HOME:
ch[0]=19;
conn_send(ch,1,0);
break;
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
case CIO_KEY_DC: /* "Delete" key */
ch[0]=20;
conn_send(ch,1,0);
break;
case CIO_KEY_RIGHT:
ch[0]=29;
conn_send(ch,1,0);
break;
case CIO_KEY_F(1):
ch[0]=133;
conn_send(ch,1,0);
break;
case CIO_KEY_F(3):
ch[0]=134;
conn_send(ch,1,0);
break;
case CIO_KEY_F(5):
ch[0]=135;
conn_send(ch,1,0);
break;
case CIO_KEY_F(7):
ch[0]=136;
conn_send(ch,1,0);
break;
case CIO_KEY_F(2):
ch[0]=137;
conn_send(ch,1,0);
break;
case CIO_KEY_F(4):
ch[0]=138;
conn_send(ch,1,0);
break;
case CIO_KEY_F(6):
ch[0]=139;
conn_send(ch,1,0);
break;
case CIO_KEY_F(8):
ch[0]=140;
conn_send(ch,1,0);
break;
case CIO_KEY_UP:
ch[0]=145;
conn_send(ch,1,0);
break;
case CIO_KEY_IC:
ch[0]=148;
conn_send(ch,1,0);
break;
case CIO_KEY_LEFT:
ch[0]=157;
conn_send(ch,1,0);
break;
default:
if(key<256) {
/* ASCII Translation */
if(key<32) {
break;
}
else if(key<65) {
ch[0]=key;
conn_send(ch,1,0);
}
else if(key<91) {
ch[0]=tolower(key);
conn_send(ch,1,0);
}
else if(key<96) {
ch[0]=key;
conn_send(ch,1,0);
}
else if(key==96) {
break;
}
else if(key<123) {
ch[0]=toupper(key);
conn_send(ch,1,0);
}
}
break;
}
}
else if(key) {
switch(key) {
case CIO_KEY_LEFT:
conn_send("\033[D",3,0);
break;
case CIO_KEY_RIGHT:
conn_send("\033[C",3,0);
break;
case CIO_KEY_UP:
conn_send("\033[A",3,0);
break;
case CIO_KEY_DOWN:
conn_send("\033[B",3,0);
break;
case CIO_KEY_HOME:
conn_send("\033[H",3,0);
break;
case CIO_KEY_END:
#ifdef CIO_KEY_SELECT
case CIO_KEY_SELECT: /* Some terminfo/termcap entries use KEY_SELECT as the END key! */
#endif
conn_send("\033[K",3,0);
break;
case CIO_KEY_DC: /* "Delete" key, send ASCII 127 (DEL) */
conn_send("\x7f",1,0);
break;
case CIO_KEY_NPAGE: /* Page down */
conn_send("\033[U",3,0);
break;
case CIO_KEY_PPAGE: /* Page up */
conn_send("\033[V",3,0);
break;
case CIO_KEY_F(1):
conn_send("\033OP",3,0);
break;
case CIO_KEY_F(2):
conn_send("\033OQ",3,0);
break;
case CIO_KEY_F(3):
conn_send("\033OR",3,0);
break;
case CIO_KEY_F(4):
conn_send("\033OS",3,0);
break;
case CIO_KEY_F(5):
conn_send("\033Ot",3,0);
break;
case CIO_KEY_F(6):
conn_send("\033[17~",5,0);
break;
case CIO_KEY_F(7):
conn_send("\033[18~",5,0);
break;
case CIO_KEY_F(8):
conn_send("\033[19~",5,0);
break;
case CIO_KEY_F(9):
conn_send("\033[20~",5,0);
break;
case CIO_KEY_F(10):
conn_send("\033[21~",5,0);
break;
case CIO_KEY_F(11):
conn_send("\033[23~",5,0);
break;
case CIO_KEY_F(12):
conn_send("\033[24~",5,0);
break;
case CIO_KEY_IC:
conn_send("\033[@",3,0);
break;
case 17: /* CTRL-Q */
ch[0]=key;
break;
case 19: /* CTRL-S */
ch[0]=key;
conn_send(ch,1,0);
break;
case '\b':
key='\b';
/* FALLTHROUGH to default */
default:
if(key<256) {
ch[0]=key;
conn_send(ch,1,0);
}
}
}
}