diff --git a/src/syncterm/GNUmakefile b/src/syncterm/GNUmakefile index 934f0d4153af9a32d600b5546a80f12a43e05c1e..e142d4b41e29f63d2e842d61e7dadc35ab4233d1 100644 --- a/src/syncterm/GNUmakefile +++ b/src/syncterm/GNUmakefile @@ -10,10 +10,15 @@ ifdef CHANNEL_CLIPPY CFLAGS += -DPCM endif +ifdef USE_GUTS + CFLAGS += -I../guts -DGUTS_BUILTIN + OBJS += $(MTOBJODIR)$(DIRSEP)gutsz$(OFILE) +endif + CFLAGS += $(UIFC-MT_CFLAGS) $(CIOLIB-MT_CFLAGS) $(XPDEV-MT_CFLAGS) -I../sbbs3 -I../smblib LDFLAGS += $(UIFC-MT_LDFLAGS) $(CIOLIB-MT_LDFLAGS) $(XPDEV-MT_LDFLAGS) -vpath %.c ../sbbs3 ../smblib ../uifc +vpath %.c ../sbbs3 ../smblib ../uifc ../guts $(SYNCTERM): $(EXEODIR) $(OBJS) $(BUILD_DEPENDS) @echo Linking $@ diff --git a/src/syncterm/bbslist.c b/src/syncterm/bbslist.c index 4e2ec93362e3a44d7c0709252bb05bd754eef415..261fc1f2c0e217f28e4850d30a27022129f9dd33 100644 --- a/src/syncterm/bbslist.c +++ b/src/syncterm/bbslist.c @@ -302,9 +302,11 @@ int edit_list(struct bbslist *item,char *listpath,int isdefault) if(!confirm("Quit editing?", NULL)) continue; #endif - if((listfile=fopen(listpath,"w"))!=NULL) { - iniWriteFile(listfile,inifile); - fclose(listfile); + if(!safe_mode) { + if((listfile=fopen(listpath,"w"))!=NULL) { + iniWriteFile(listfile,inifile); + fclose(listfile); + } } strListFreeStrings(inifile); return(changed); @@ -534,6 +536,8 @@ void add_bbs(char *listpath, struct bbslist *bbs) FILE *listfile; str_list_t inifile; + if(safe_mode) + return; if((listfile=fopen(listpath,"r"))!=NULL) { inifile=iniReadFile(listfile); fclose(listfile); @@ -574,6 +578,8 @@ void del_bbs(char *listpath, struct bbslist *bbs) FILE *listfile; str_list_t inifile; + if(safe_mode) + return; if((listfile=fopen(listpath,"r"))!=NULL) { inifile=iniReadFile(listfile); fclose(listfile); @@ -657,9 +663,11 @@ void change_settings(void) } } write_ini: - if((inifile=fopen(inipath,"w"))!=NULL) { - iniWriteFile(inifile,inicontents); - fclose(inifile); + if(!safe_mode) { + if((inifile=fopen(inipath,"w"))!=NULL) { + iniWriteFile(inifile,inicontents); + fclose(inifile); + } } } @@ -800,6 +808,13 @@ struct bbslist *show_bbslist(int mode) uifc.msg("Max List size reached!"); break; } + if(safe_mode) { + uifc.helpbuf= "`Cannot edit list in safe mode`\n\n" + "SyncTERM is currently running in safe mode. This means you cannot add to the\n" + "BBS list."; + uifc.msg("Cannot edit list in safe mode"); + break; + } #ifdef PCM if(!confirm("Add new Entry?",NULL)) continue; @@ -851,6 +866,13 @@ struct bbslist *show_bbslist(int mode) uifc.msg("It's gone, calm down man!"); break; } + if(safe_mode) { + uifc.helpbuf= "`Cannot edit list in safe mode`\n\n" + "SyncTERM is currently running in safe mode. This means you cannot remove from the\n" + "BBS list."; + uifc.msg("Cannot edit list in safe mode"); + break; + } sprintf(str,"Delete %s?",list[opt]->name); i=1; if(uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,NULL,str,YesNo)!=0) @@ -867,6 +889,13 @@ struct bbslist *show_bbslist(int mode) oldopt=-1; break; case MSK_EDIT: + if(safe_mode) { + uifc.helpbuf= "`Cannot edit list in safe mode`\n\n" + "SyncTERM is currently running in safe mode. This means you cannot edit the\n" + "BBS list."; + uifc.msg("Cannot edit list in safe mode"); + break; + } #ifdef PCM if(!confirm("Edit this entry?",NULL)) continue; @@ -885,6 +914,13 @@ struct bbslist *show_bbslist(int mode) } else { if(mode==BBSLIST_EDIT) { + if(safe_mode) { + uifc.helpbuf= "`Cannot edit list in safe mode`\n\n" + "SyncTERM is currently running in safe mode. This means you cannot edit the\n" + "BBS list."; + uifc.msg("Cannot edit list in safe mode"); + break; + } #ifdef PCM if(!confirm("Edit this entry?",NULL)) continue; @@ -996,7 +1032,7 @@ struct bbslist *show_bbslist(int mode) } break; case 3: /* Font management */ - font_management(); + if(!safe_mode) font_management(); break; case 4: /* Program settings */ change_settings(); diff --git a/src/syncterm/fonts.c b/src/syncterm/fonts.c index 5a77941588012e2a44878bd0c5c9febf8409f512..14acc9711a71239fef34e576aab8877f56dfb65d 100644 --- a/src/syncterm/fonts.c +++ b/src/syncterm/fonts.c @@ -40,6 +40,8 @@ void save_font_files(struct font_files *fonts) str_list_t fontnames; int i; + if(safe_mode) + return; get_syncterm_filename(inipath, sizeof(inipath), SYNCTERM_PATH_INI, FALSE); if((inifile=fopen(inipath,"r"))!=NULL) { ini_file=iniReadFile(inifile); @@ -316,7 +318,7 @@ void font_management(void) show_filepick=1; break; } - if(show_filepick) { + if(show_filepick && !safe_mode) { int result; struct file_pick fpick; char *savbuf; diff --git a/src/syncterm/syncterm.c b/src/syncterm/syncterm.c index b0fe63f1519d24208eac398c97cd33194f9afd0d..4b053c76e9362dbe4dda374ba12f855629df9a02 100644 --- a/src/syncterm/syncterm.c +++ b/src/syncterm/syncterm.c @@ -39,6 +39,7 @@ struct syncterm_settings settings; char *font_names[sizeof(conio_fontdata)/sizeof(struct conio_font_data_struct)]; unsigned char *scrollback_buf=NULL; unsigned int scrollback_lines=0; +int safe_mode=0; #ifdef _WINSOCKAPI_ @@ -355,6 +356,9 @@ int main(int argc, char **argv) case 'T': conn_type=CONN_TYPE_TELNET; break; + case 'S': + safe_mode=1; + break; default: goto USAGE; } @@ -533,6 +537,7 @@ int main(int argc, char **argv) "-l# = set screen lines to # (default=auto-detect)\n" "-t = use telnet mode if URL does not include the scheme\n" "-r = use rlogin mode if URL does not include the scheme\n" + "-s = enable \"Safe Mode\" which prevents writing/browsing local files\n" "\n" "URL format is: [(rlogin|telnet)://][user[:password]@]domainname[:port]\n" "examples: rlogin://deuce:password@nix.synchro.net:5885\n" diff --git a/src/syncterm/syncterm.h b/src/syncterm/syncterm.h index b82d002714740bae7309f9489893bb876dfbe3f3..ecbc56c3fdb446a7926e1b7f23e04625528a8b43 100644 --- a/src/syncterm/syncterm.h +++ b/src/syncterm/syncterm.h @@ -23,6 +23,7 @@ extern struct syncterm_settings settings; void parse_url(char *url, struct bbslist *bbs, int dflt_conn_type, int force_defaults); extern int default_font; extern char *font_names[]; +extern int safe_mode; char *get_syncterm_filename(char *fn, int fnlen, int type, int shared); void load_settings(struct syncterm_settings *set); diff --git a/src/syncterm/term.c b/src/syncterm/term.c index 2071a5bf76692fd010577e9de26c5d49bcf52c2a..0452e7ee39317965476ea3b4990d7771e21cc8eb 100644 --- a/src/syncterm/term.c +++ b/src/syncterm/term.c @@ -16,7 +16,15 @@ #include "zmodem.h" #include "crc32.h" +#ifdef GUTS_BUILTIN +#include "gutsz.h" +#endif + +#ifdef GUTS_BUILTIN +#define BUFSIZE 1 +#else #define BUFSIZE 2048 +#endif static char recvbuf[BUFSIZE]; #define DUMP @@ -119,6 +127,7 @@ void update_status(struct bbslist *bbs, int speed) { char buf[160]; char nbuf[LIST_NAME_MAX+10+11+1]; /* Room for "Name (Logging) (115300)" and terminator */ + /* SAFE and Logging should me be possible. */ int oldscroll; int olddmc; struct text_info txtinfo; @@ -143,6 +152,8 @@ void update_status(struct bbslist *bbs, int speed) gotoxy(1,1); _wscroll=0; strcpy(nbuf, bbs->name); + if(safe_mode) + strcat(nbuf, " (SAFE)"); if(cterm.log) strcat(nbuf, " (Logging)"); if(speed) @@ -535,6 +546,9 @@ void begin_upload(char *uldir, BOOL autozm) ,"" }; + if(safe_mode) + return; + init_uifc(FALSE, FALSE); result=filepick(&uifc, "Upload", &fpick, uldir, NULL, UIFC_FP_ALLOWENTRY); @@ -570,6 +584,191 @@ void begin_upload(char *uldir, BOOL autozm) uifcbail(); } +#ifdef GUTS_BUILTIN +static int guts_lputs(void* cbdata, int level, const char* str) +{ + struct GUTS_info *gi=cbdata; + /* ToDo: Do something usefull here. */ + /* fprintf(stderr,"%s\n",str); */ + return(0); +} + +void guts_zmodem_progress(void* cbdata, ulong current_pos) +{ + struct GUTS_info *gi=cbdata; + /* ToDo: Do something usefull here. */ + return; +} + +static int guts_send_byte(void* cbdata, uchar ch, unsigned timeout) +{ + int i; + struct GUTS_info *gi=cbdata; + + if(!socket_check(gi->oob_socket, NULL, &i, timeout*1000)) + return(-1); + + if(!i) + return(-1); + + if(send(gi->oob_socket,&ch,1,0)==-1) + return(-1); + + return(0); +} + +static int guts_recv_byte(void* cbdata, unsigned timeout) +{ + BOOL data_waiting; + BYTE ch; + struct GUTS_info *gi=cbdata; + + if(!socket_check(gi->oob_socket, &data_waiting, NULL, timeout*1000)) + return(-1); + + if(!data_waiting) + return(-1); + + if(recv(gi->oob_socket,&ch,1,0)!=1) + return(-1); + + return(ch); +} + +static BOOL guts_is_connected(void* cbdata) +{ + struct GUTS_info *gi=cbdata; + return socket_check(gi->oob_socket,NULL,NULL,0); +} + +BOOL guts_data_waiting(void* cbdata, unsigned timeout) +{ + BOOL rd; + struct GUTS_info *gi=cbdata; + + if(!socket_check(gi->oob_socket,&rd,NULL,timeout*1000)) + return(FALSE); + return(rd); +} + +void zmodem_download(char *download_dir); + +void guts_background_download(void *cbdata) +{ + struct GUTS_info gi=*(struct GUTS_info *)cbdata; + + zmodem_t zm; + ulong bytes_received; + + zmodem_init(&zm + ,&gi + ,guts_lputs, guts_zmodem_progress + ,guts_send_byte,guts_recv_byte,guts_is_connected + ,guts_data_waiting); + + /* ToDo: This would be a good time to detach or something. */ + zmodem_recv_files(&zm,gi.files[0],&bytes_received); + + oob_close(&gi); +} + +void guts_background_upload(void *cbdata) +{ + struct GUTS_info gi=*(struct GUTS_info *)cbdata; + + zmodem_t zm; + ulong fsize; + FILE* fp; + + if((fp=fopen(gi.files[0],"rb"))==NULL) { + fprintf(stderr,"Error %d opening %s for read",errno,gi.files[0]); + return; + } + + setvbuf(fp,NULL,_IOFBF,0x10000); + + zmodem_init(&zm + ,&gi + ,guts_lputs, guts_zmodem_progress + ,guts_send_byte,guts_recv_byte,guts_is_connected + ,guts_data_waiting); + + zm.current_file_num = zm.total_files = 1; /* ToDo: support multi-file/batch uploads */ + + fsize=filelength(fileno(fp)); + + if(zmodem_send_file(&zm, gi.files[0], fp + ,/* ZRQINIT? */TRUE, /* start_time */NULL, /* sent_bytes */ NULL)) + zmodem_get_zfin(&zm); + + fclose(fp); + + oob_close(&gi); +} + +void guts_transfer(struct bbslist *bbs) +{ + struct GUTS_info gi; + + if(safe_mode) + return; + setup_defaults(&gi); + gi.socket=conn_socket; + gi.telnet=bbs->conn_type==CONN_TYPE_TELNET; + gi.server=FALSE; + gi.use_daemon=FALSE; + gi.orig=FALSE; + + if(negotiation(&gi)) { + oob_close(&gi); + return; + } + + /* Authentication Phase */ + if(!gi.inband) { + if(authenticate(&gi)) { + oob_close(&gi); + return; + } + } + + if(gi.inband) { + if(gi.direction==UPLOAD) + begin_upload(bbs->uldir, TRUE); + else + zmodem_download(bbs->dldir); + oob_close(&gi); + } + else { + if(gi.direction==UPLOAD) { + int result; + struct file_pick fpick; + + init_uifc(FALSE, FALSE); + result=filepick(&uifc, "Upload", &fpick, bbs->uldir, NULL, UIFC_FP_ALLOWENTRY); + + if(result==-1 || fpick.files<1) { + filepick_free(&fpick); + uifcbail(); + return; + } + strListPush(&gi.files, fpick.selected[0]); + filepick_free(&fpick); + + uifcbail(); + + _beginthread(guts_background_upload, 0, &gi); + } + else { + strListPush(&gi.files, bbs->dldir); + _beginthread(guts_background_download, 0, &gi); + } + } + + return; +} +#endif + void ascii_upload(FILE *fp, char *path) { char linebuf[1024+2]; /* One extra for terminator, one extra for added CR */ @@ -645,6 +844,8 @@ void zmodem_download(char *download_dir) int files_received; ulong bytes_received; + if(safe_mode) + return; #if 0 bufbot=buftop=0; /* purge our receive buffer */ #endif @@ -720,6 +921,8 @@ void font_control(struct bbslist *bbs) struct text_info txtinfo; int i,j,k; + if(safe_mode) + return; gettextinfo(&txtinfo); buf=(char *)malloc(txtinfo.screenheight*txtinfo.screenwidth*2); gettext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf); @@ -755,6 +958,8 @@ void capture_control(struct bbslist *bbs) struct text_info txtinfo; int i,j; + if(safe_mode) + return; gettextinfo(&txtinfo); buf=(char *)malloc(txtinfo.screenheight*txtinfo.screenwidth*2); gettext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf); @@ -835,13 +1040,21 @@ void capture_control(struct bbslist *bbs) BOOL doterm(struct bbslist *bbs) { unsigned char ch[2]; +#ifdef GUTS_BUILTIN + unsigned char prn[1024]; +#else unsigned char prn[BUFSIZE]; +#endif int key; int i,j,k; unsigned char *p; BYTE zrqinit[] = { ZDLE, ZHEX, '0', '0', 0 }; /* for Zmodem auto-downloads */ BYTE zrinit[] = { ZDLE, ZHEX, '0', '1', 0 }; /* for Zmodem auto-uploads */ BYTE zrqbuf[5]; +#ifdef GUTS_BUILTIN + BYTE gutsinit[] = { ESC, '[', '{' }; /* For GUTS auto-transfers */ + BYTE gutsbuf[3]; +#endif int inch; long double nextchar=0; long double lastchar=0; @@ -865,6 +1078,9 @@ BOOL doterm(struct bbslist *bbs) cterm.music_enable=bbs->music; ch[1]=0; zrqbuf[0]=0; +#ifdef GUTS_BUILTIN + gutsbuf[0]=0; +#endif /* Main input loop */ oldmc=hold_update; @@ -899,6 +1115,35 @@ BOOL doterm(struct bbslist *bbs) lastchar = xp_timer(); nextchar = lastchar + 1/(long double)(speed/10); } + +#ifdef GUTS_BUILTIN + if(!gutsbuf[0]) { + if(inch == gutsinit[0]) { + gutsbuf[0]=inch; + gutsbuf[1]=0; + continue; + } + } + else { /* Already have the start of the sequence */ + j=strlen(gutsbuf); + if(inch == gutsinit[j]) { + gutsbuf[j]=inch; + gutsbuf[++j]=0; + if(j==sizeof(gutsinit)) /* Have full sequence */ + guts_transfer(bbs); + } + else { + gutsbuf[j++]=inch; + cterm_write(gutsbuf, j, prn, sizeof(prn), &speed); + if(prn[0]) + conn_send(prn,strlen(prn),0); + updated=TRUE; + gutsbuf[0]=0; + } + continue; + } +#endif + if(!zrqbuf[0]) { if(inch == zrqinit[0] || inch == zrinit[0]) { zrqbuf[0]=inch; @@ -911,7 +1156,7 @@ BOOL doterm(struct bbslist *bbs) 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(j==sizeof(zrqinit)) { /* Have full sequence (Assumes zrinit and zrqinit are same length */ if(!strcmp(zrqbuf, zrqinit)) zmodem_download(bbs->dldir); else