Newer
Older
#include <genwrap.h>
#include <keys.h>
#include "threadwrap.h"
#include "filewrap.h"
#include "syncterm.h"
#include "term.h"
#include "uifcinit.h"
#include "menu.h"
#include "telnet_io.h"
#ifdef WITH_WXWIDGETS
#ifdef GUTS_BUILTIN
#include "gutsz.h"
#endif
#ifndef WITHOUT_OOII
#include "ooii.h"
#endif
#define ANSI_REPLY_BUFSIZE 2048
struct terminal term;
#define TRANSFER_WIN_WIDTH 66
#define TRANSFER_WIN_HEIGHT 18
static char winbuf[(TRANSFER_WIN_WIDTH + 2) * (TRANSFER_WIN_HEIGHT + 1) * 2]; /* Save buffer for transfer window */
static struct text_info trans_ti;
static struct text_info log_ti;
#ifdef WITH_WXWIDGETS
enum html_mode {
HTML_MODE_HIDDEN
,HTML_MODE_RAISED
};
static enum html_mode html_mode=HTML_MODE_HIDDEN;
enum {
HTML_SUPPORT_UNKNOWN
,HTML_NOTSUPPORTED
,HTML_SUPPORTED
};
static int html_supported=HTML_SUPPORT_UNKNOWN;
#if defined(__BORLANDC__)
#pragma argsused
#endif
void mousedrag(unsigned char *scrollback)
{
int key;
struct mouse_event mevent;
unsigned char *screen;
unsigned char *sbuffer;
int pos, startpos,endpos, lines;
int outpos;
char *copybuf;
sbufsize=term.width*2*term.height;
screen=(unsigned char*)alloca(sbufsize);
sbuffer=(unsigned char*)alloca(sbufsize);
gettext(term.x-1,term.y-1,term.x+term.width-2,term.y+term.height-2,screen);
while(1) {
key=getch();
if(key==0 || key==0xff)
key|=getch()<<8;
switch(key) {
case CIO_KEY_MOUSE:
getmouse(&mevent);
startpos=((mevent.starty-1)*term.width)+(mevent.startx-1);
endpos=((mevent.endy-1)*term.width)+(mevent.endx-1);
if(startpos>=term.width*term.height)
startpos=term.width*term.height-1;
if(endpos>=term.width*term.height)
endpos=term.width*term.height-1;
if(endpos<startpos) {
pos=endpos;
endpos=startpos;
startpos=pos;
}
switch(mevent.event) {
case CIOLIB_BUTTON_1_DRAG_MOVE:
memcpy(sbuffer,screen,sbufsize);
for(pos=startpos;pos<=endpos;pos++) {
else
if(((sbuffer[pos*2+1]&0x70)>>4) == (sbuffer[pos*2+1]&0x0F)) {
sbuffer[pos*2+1]|=0x08;
}
}
puttext(term.x-1,term.y-1,term.x+term.width-2,term.y+term.height-2,sbuffer);
break;
default:
lines=abs(mevent.endy-mevent.starty)+1;
copybuf=alloca(endpos-startpos+4+lines*2);
outpos=0;
for(pos=startpos;pos<=endpos;pos++) {
copybuf[outpos++]=screen[pos*2];
if(screen[pos*2]!=' ' && screen[pos*2])
lastchar=outpos;
if((pos+1)%term.width==0) {
#ifdef _WIN32
copybuf[outpos++]='\r';
#endif
copybuf[outpos++]='\n';
}
}
copybuf[outpos]=0;
copytext(copybuf, strlen(copybuf));
puttext(term.x-1,term.y-1,term.x+term.width-2,term.y+term.height-2,screen);
return;
}
break;
default:
puttext(term.x-1,term.y-1,term.x+term.width-2,term.y+term.height-2,screen);
ungetch(key);
return;
}
}
}
void update_status(struct bbslist *bbs, int speed, BOOL ooii_mode)
char nbuf[LIST_NAME_MAX+10+11+1]; /* Room for "Name (Logging) (115300)" and terminator */
/* SAFE and Logging should me be possible. */
struct text_info txtinfo;
int now;
static int lastupd=0;
static int oldspeed=0;
if(now==lastupd && speed==oldspeed)
oldspeed=speed;
timeon=now - bbs->connected;
gettextinfo(&txtinfo);
oldscroll=_wscroll;
textattr(YELLOW|(BLUE<<4));
/* Move to status line thinger */
window(term.x-1,term.y+term.height-1,term.x+term.width-2,term.y+term.height-1);
gotoxy(1,1);
_wscroll=0;
if(safe_mode)
strcat(nbuf, " (SAFE)");
if(cterm.log)
strcat(nbuf, " (Logging)");
if(speed)
sprintf(strchr(nbuf,0)," (%d)", speed);
if(cterm.doorway_mode)
strcat(nbuf, " (DrWy)");
if(ooii_mode)
strcat(nbuf, " (OO][)");
switch(cio_api.mode) {
case CIOLIB_MODE_CURSES:
case CIOLIB_MODE_CURSES_IBM:
case CIOLIB_MODE_ANSI:
if(timeon>359999)
cprintf(" %-29.29s \263 %-6.6s \263 Connected: Too Long \263 CTRL-S for menu ",nbuf,conn_types[bbs->conn_type]);
cprintf(" %-29.29s \263 %-6.6s \263 Connected: %02d:%02d:%02d \263 CTRL-S for menu ",nbuf,conn_types[bbs->conn_type],timeon/3600,(timeon/60)%60,timeon%60);
break;
default:
if(timeon>359999)
cprintf(" %-30.30s \263 %-6.6s \263 Connected: Too Long \263 ALT-Z for menu ",nbuf,conn_types[bbs->conn_type]);
cprintf(" %-30.30s \263 %-6.6s \263 Connected: %02d:%02d:%02d \263 ALT-Z for menu ",nbuf,conn_types[bbs->conn_type],timeon/3600,(timeon/60)%60,timeon%60);
break; /* 1+29 +3 +6 +3 +11 +3+3+2 +3 +6 +4 +5 */
if(wherex()>=80)
clreol();
_wscroll=oldscroll;
textattr(txtinfo.attribute);
window(txtinfo.winleft,txtinfo.wintop,txtinfo.winright,txtinfo.winbottom);
gotoxy(txtinfo.curx,txtinfo.cury);
#if defined(_WIN32) && defined(_DEBUG) && defined(DUMP)
void dump(BYTE* buf, int len)
{
char str[128];
int i,j;
size_t slen=0;
slen=sprintf(str,"RX: ");
for(i=0;i<len;i+=j) {
for(j=0;i+j<len && j<32;j++)
slen+=sprintf(str+slen,"%02X ",buf[i+j]);
OutputDebugString(str);
slen=sprintf(str,"RX: ");
}
}
#endif
/* Zmodem Stuff */
int log_level = LOG_INFO;
struct zmodem_cbdata {
zmodem_t *zm;
struct bbslist *bbs;
};
enum { ZMODEM_MODE_SEND, ZMODEM_MODE_RECV } zmodem_mode;
static BOOL zmodem_check_abort(void* vp)
struct zmodem_cbdata *zcb=(struct zmodem_cbdata *)vp;
zmodem_t* zm=zcb->zm;
if(zm!=NULL && kbhit()) {
switch(getch()) {
case ESC:
case CTRL_C:
case CTRL_X:
zm->cancelled=TRUE;
zm->local_abort=TRUE;
break;
}
}
return(zm->cancelled);
extern FILE* log_fp;
extern char *log_levels[];
#if defined(__BORLANDC__)
#pragma argsused
#endif
static int lputs(void* cbdata, int level, const char* str)
#if defined(_WIN32) && defined(_DEBUG) && FALSE
sprintf(msg,"SyncTerm: %s\n",str);
OutputDebugString(msg);
if(log_fp!=NULL && level <= log_level)
fprintf(log_fp,"Xfer %s: %s\n",log_levels[level], str);
if(level > LOG_INFO)
/* Assumes the receive window has been drawn! */
window(log_ti.winleft, log_ti.wintop, log_ti.winright, log_ti.winbottom);
gotoxy(log_ti.curx, log_ti.cury);
switch(level) {
case LOG_DEBUG:
textcolor(LIGHTCYAN);
SAFEPRINTF(msg,"%s\r\n",str);
break;
textcolor(WHITE);
SAFEPRINTF(msg,"%s\r\n",str);
break;
case LOG_NOTICE:
textcolor(YELLOW);
SAFEPRINTF(msg,"%s\r\n",str);
break;
case LOG_WARNING:
textcolor(LIGHTMAGENTA);
SAFEPRINTF(msg,"Warning: %s\r\n",str);
break;
default:
textcolor(LIGHTRED);
SAFEPRINTF(msg,"!ERROR: %s\r\n",str);
break;
}
}
static int lprintf(int level, const char *fmt, ...)
{
char sbuf[1024];
va_list argptr;
va_start(argptr,fmt);
vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
sbuf[sizeof(sbuf)-1]=0;
va_end(argptr);
return(lputs(NULL,level,sbuf));
}
#if defined(__BORLANDC__)
#pragma argsused
#endif
void zmodem_progress(void* cbdata, uint32_t current_pos)
{
char orig[128];
unsigned cps;
time_t l;
time_t t;
time_t now;
static time_t last_progress;
struct zmodem_cbdata *zcb=(struct zmodem_cbdata *)cbdata;
zmodem_t* zm=zcb->zm;
zmodem_check_abort(cbdata);
now=time(NULL);
if(now-last_progress>0 || current_pos >= zm->current_file_size) {
hold_update = TRUE;
window(((trans_ti.screenwidth-TRANSFER_WIN_WIDTH)/2)+2
, ((trans_ti.screenheight-TRANSFER_WIN_HEIGHT)/2)+1
, ((trans_ti.screenwidth-TRANSFER_WIN_WIDTH)/2) + TRANSFER_WIN_WIDTH - 2
, ((trans_ti.screenheight-TRANSFER_WIN_HEIGHT)/2)+5);
gotoxy(1,1);
textattr(LIGHTCYAN | (BLUE<<4));
t=now-zm->transfer_start_time;
if(t<=0)
t=1;
if(zm->transfer_start_pos>current_pos)
zm->transfer_start_pos=0;
if((cps=(current_pos-zm->transfer_start_pos)/t)==0)
cps=1; /* cps so far */
l=zm->current_file_size/cps; /* total transfer est time */
l-=t; /* now, it's est time left */
if(l<0) l=0;
cprintf("File (%u of %u): %-.*s"
,zm->current_file_num, zm->total_files, TRANSFER_WIN_WIDTH - 20, zm->current_file_name);
if(zm->transfer_start_pos)
sprintf(orig,"From: %lu ", zm->transfer_start_pos);
else
orig[0]=0;
cprintf("%sByte: %lu of %lu (%lu KB)"
,orig, current_pos, zm->current_file_size, zm->current_file_size/1024);
cprintf("Time: %lu:%02lu ETA: %lu:%02lu Block: %u/CRC-%u %u cps"
,t/60L
,t%60L
,l/60L
,l%60L
,zm->block_size
,zmodem_mode==ZMODEM_MODE_RECV ? (zm->receive_32bit_data ? 32:16) :
(zm->can_fcs_32 && !zm->want_fcs_16) ? 32:16
,cps
);
clreol();
cprintf("%*s%3d%%\r\n", TRANSFER_WIN_WIDTH/2-5, ""
,(long)(((float)current_pos/(float)zm->current_file_size)*100.0));
l = (long)(60*((float)current_pos/(float)zm->current_file_size));
cprintf("[%*.*s%*s]", l, l,
"\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1"
"\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1"
"\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1"
"\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1"
"\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1"
"\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1\xb1"
, 60-l, "");
last_progress=now;
hold_update = FALSE;
gotoxy(wherex(), wherey());
hold_update = old_hold;
#if defined(__BORLANDC__)
#pragma argsused
#endif
static int send_byte(void* unused, uchar ch, unsigned timeout /* seconds */)
return(conn_send(&ch,sizeof(ch),timeout*1000)!=1);
#if defined(__BORLANDC__)
#pragma argsused
#endif
static int recv_byte(void* unused, unsigned timeout /* seconds */)
if(conn_recv(&ch, sizeof(ch), timeout*1000))
return(ch);
return(-1);
}
#if defined(__BORLANDC__)
#pragma argsused
#endif
BOOL data_waiting(void* unused, unsigned timeout)
{
return(conn_data_waiting()!=0);
}
void draw_transfer_window(char* title)
char outline[TRANSFER_WIN_WIDTH*2];
char shadow[TRANSFER_WIN_WIDTH*2]; /* Assumes that width*2 > height * 2 */
old_hold = hold_update;
hold_update=TRUE;
gettextinfo(&trans_ti);
top=(trans_ti.screenheight-TRANSFER_WIN_HEIGHT)/2;
left=(trans_ti.screenwidth-TRANSFER_WIN_WIDTH)/2;
gettext(left, top, left + TRANSFER_WIN_WIDTH + 1, top + TRANSFER_WIN_HEIGHT, winbuf);
memset(outline, YELLOW | (BLUE<<4), sizeof(outline));
for(i=2;i < sizeof(outline) - 2; i+=2) {
outline[i] = (char)0xcd; /* Double horizontal line */
outline[0]=(char)0xc9;
outline[sizeof(outline)-2]=(char)0xbb;
puttext(left, top, left + TRANSFER_WIN_WIDTH - 1, top, outline);\
/* Title */
gotoxy(left+4,top);
textattr(YELLOW|(BLUE<<4));
cprintf("\xb5 %*s \xc6",strlen(title),"");
gotoxy(left+6,top);
textattr(WHITE|(BLUE<<4));
cprintf("%s",title);
for(i=2;i < sizeof(outline) - 2; i+=2) {
outline[i] = (char)0xc4; /* Single horizontal line */
outline[0] = (char)0xc7; /* 0xcc */
outline[sizeof(outline)-2]=(char)0xb6; /* 0xb6 */
puttext(left, top+6, left + TRANSFER_WIN_WIDTH - 1, top+6, outline);
for(i=2;i < sizeof(outline) - 2; i+=2) {
outline[i] = (char)0xcd; /* Double horizontal line */
outline[0]=(char)0xc8;
outline[sizeof(outline)-2]=(char)0xbc;
puttext(left, top + TRANSFER_WIN_HEIGHT - 1, left+TRANSFER_WIN_WIDTH - 1, top + TRANSFER_WIN_HEIGHT - 1, outline);
outline[0]=(char)0xba;
outline[sizeof(outline)-2]=(char)0xba;
for(i=2;i < sizeof(outline) - 2; i+=2) {
outline[i] = ' ';
}
for(i=1; i<6; i++) {
puttext(left, top + i, left + TRANSFER_WIN_WIDTH - 1, top+i, outline);
}
/* for(i=3;i < sizeof(outline) - 2; i+=2) { */
/* outline[i] = LIGHTGRAY | (BLACK << 8); */
/* } */
for(i=7; i<TRANSFER_WIN_HEIGHT-1; i++) {
puttext(left, top + i, left + TRANSFER_WIN_WIDTH - 1, top+i, outline);
}
/* Title */
gotoxy(left + TRANSFER_WIN_WIDTH - 20, top + i);
textattr(YELLOW|(BLUE<<4));
cprintf("\xb5 \xc6");
textattr(WHITE|(BLUE<<4));
gotoxy(left + TRANSFER_WIN_WIDTH - 18, top + i);
cprintf("ESC to Abort");
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
/* Shadow */
if(uifc.bclr==BLUE) {
gettext(left + TRANSFER_WIN_WIDTH
, top+1
, left + TRANSFER_WIN_WIDTH + 1
, top + (TRANSFER_WIN_HEIGHT - 1)
, shadow);
for(i=1;i<sizeof(shadow);i+=2)
shadow[i]=DARKGRAY;
puttext(left + TRANSFER_WIN_WIDTH
, top+1
, left + TRANSFER_WIN_WIDTH + 1
, top + (TRANSFER_WIN_HEIGHT - 1)
, shadow);
gettext(left + 2
, top + TRANSFER_WIN_HEIGHT
, left + TRANSFER_WIN_WIDTH + 1
, top + TRANSFER_WIN_HEIGHT
, shadow);
for(i=1;i<sizeof(shadow);i+=2)
shadow[i]=DARKGRAY;
puttext(left + 2
, top + TRANSFER_WIN_HEIGHT
, left + TRANSFER_WIN_WIDTH + 1
, top + TRANSFER_WIN_HEIGHT
, shadow);
}
window(left+2, top + 7, left + TRANSFER_WIN_WIDTH - 3, top + TRANSFER_WIN_HEIGHT - 2);
puttext(
((trans_ti.screenwidth-TRANSFER_WIN_WIDTH)/2)
, ((trans_ti.screenheight-TRANSFER_WIN_HEIGHT)/2)
, ((trans_ti.screenwidth-TRANSFER_WIN_WIDTH)/2) + TRANSFER_WIN_WIDTH + 1
, ((trans_ti.screenheight-TRANSFER_WIN_HEIGHT)/2) + TRANSFER_WIN_HEIGHT
, winbuf);
window(trans_ti.winleft, trans_ti.wintop, trans_ti.winright, trans_ti.winbottom);
gotoxy(trans_ti.curx, trans_ti.cury);
textattr(trans_ti.attribute);
#define XMODEM_128B (1<<10) /* Use 128 byte block size (ick!) */
void zmodem_upload(struct bbslist *bbs, FILE *fp, char *path);
void xmodem_upload(struct bbslist *bbs, FILE *fp, char *path, long mode, int lastch);
void xmodem_download(struct bbslist *bbs, long mode, char *path);
void zmodem_download(struct bbslist *bbs);
void begin_upload(struct bbslist *bbs, BOOL autozm, int lastch)
char str[MAX_PATH*2+1];
char *opts[5]={
"ZMODEM"
,"ASCII"
,""
};
struct text_info txtinfo;
char *buf;
gettextinfo(&txtinfo);
buf=(char *)alloca(txtinfo.screenheight*txtinfo.screenwidth*2);
gettext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf);
init_uifc(FALSE, FALSE);
result=filepick(&uifc, "Upload", &fpick, bbs->uldir, NULL, UIFC_FP_ALLOWENTRY);
if(result==-1 || fpick.files<1) {
filepick_free(&fpick);
puttext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf);
gotoxy(txtinfo.curx, txtinfo.cury);
return;
}
SAFECOPY(path,fpick.selected[0]);
filepick_free(&fpick);
puttext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf);
if((fp=fopen(path,"rb"))==NULL) {
SAFEPRINTF2(str,"Error %d opening %s for read",errno,path);
uifcmsg("ERROR",str);
puttext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf);
gotoxy(txtinfo.curx, txtinfo.cury);
return;
}
setvbuf(fp,NULL,_IOFBF,0x10000);
zmodem_upload(bbs, fp, path);
else {
i=0;
uifc.helpbuf="Select Protocol";
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,NULL,"Protocol",opts)) {
zmodem_upload(bbs, fp, path);
break;
case 1:
xmodem_upload(bbs, fp, path, YMODEM|SEND, lastch);
xmodem_upload(bbs, fp, path, XMODEM|SEND, lastch);
}
uifcbail();
puttext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf);
gotoxy(txtinfo.curx, txtinfo.cury);
void begin_download(struct bbslist *bbs)
{
char path[MAX_PATH+1];
int i;
char *opts[5]={
,""
};
struct text_info txtinfo;
char *buf;
if(safe_mode)
return;
gettextinfo(&txtinfo);
buf=(char *)alloca(txtinfo.screenheight*txtinfo.screenwidth*2);
gettext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf);
init_uifc(FALSE, FALSE);
i=0;
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,NULL,"Protocol",opts)) {
case 0:
zmodem_download(bbs);
break;
case 1:
xmodem_download(bbs, YMODEM|CRC|GMODE|RECV, NULL);
if(uifc.input(WIN_MID|WIN_SAV,0,0,"Filename",path,sizeof(path),0)!=-1)
xmodem_download(bbs, XMODEM|CRC|RECV,path);
break;
uifcbail();
puttext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf);
gotoxy(txtinfo.curx, txtinfo.cury);
}
#if defined(__BORLANDC__)
#pragma argsused
#endif
static BOOL is_connected(void* unused)
{
return(conn_connected());
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
#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 guts_background_download(void *cbdata)
{
struct GUTS_info gi=*(struct GUTS_info *)cbdata;
zmodem_t zm;
ulong bytes_received;
zmodem_mode=ZMODEM_MODE_RECV;
zmodem_init(&zm
,&gi
,guts_lputs, guts_zmodem_progress
,guts_send_byte,guts_recv_byte,guts_is_connected
,NULL /* is_cancelled */
,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_mode=ZMODEM_MODE_SEND;
zmodem_init(&zm
,&gi
,guts_lputs, guts_zmodem_progress
,guts_send_byte,guts_recv_byte,guts_is_connected
,NULL /* is_cancelled */
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
,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, TRUE);
zmodem_download(bbs);
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
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
{
char linebuf[1024+2]; /* One extra for terminator, one extra for added CR */
char *p;
char ch[2];
int inch;
ch[1]=0;
while(!feof(fp)) {
if(fgets(linebuf, 1025, fp)!=NULL) {
if((p=strrchr(linebuf,'\n'))!=NULL) {
if((p==linebuf && !lastwascr) || (p>linebuf && *(p-1)!='\n')) {
*p='\r';
p++;
*p='\n';
p++;
*p=0;
}
}
if(p!=NULL && p>linebuf) {
if(*(p-1)=='\r')
lastwascr=TRUE;
}
conn_send(linebuf,strlen(linebuf),0);
}
/* Note, during ASCII uploads, do NOT send ANSI responses and don't
* allow speed changes. */
while((inch=recv_byte(NULL, 0))>=0) {
ch[0]=inch;
cterm_write(ch, 1, NULL, 0, NULL);
}
}
fclose(fp);
}
void zmodem_upload(struct bbslist *bbs, FILE *fp, char *path)
{
zmodem_t zm;
ulong fsize;
draw_transfer_window("ZMODEM Upload");
zmodem_mode=ZMODEM_MODE_SEND;
conn_binary_mode_on();
zmodem_init(&zm
,/* cbdata */&zm
,lputs, zmodem_progress
,send_byte,recv_byte
,is_connected
,zmodem_check_abort
,data_waiting);
zm.current_file_num = zm.total_files = 1; /* ToDo: support multi-file/batch uploads */
fsize=filelength(fileno(fp));
lprintf(LOG_INFO,"Sending %s (%lu KB) via ZMODEM"
,path,fsize/1024);
if(zmodem_send_file(&zm, path, fp
,/* ZRQINIT? */TRUE, /* start_time */NULL, /* sent_bytes */ NULL))
zmodem_get_zfin(&zm);
fclose(fp);
conn_binary_mode_off();
lprintf(LOG_NOTICE,"Hit any key to continue...");
if(log_fp!=NULL)
fflush(log_fp);
getch();
erase_transfer_window();
}
BOOL zmodem_duplicate_callback(void *cbdata, void *zm_void)
{
struct text_info txtinfo;
char *buf;
BOOL ret=FALSE;
int i;
char *opts[4]={
"Overwrite"
,"Choose New Name"
,"Cancel Download"
,NULL
};
struct zmodem_cbdata *cb=(struct zmodem_cbdata *)cbdata;
zmodem_t *zm=(zmodem_t *)zm_void;
char fpath[MAX_PATH+1];
gettextinfo(&txtinfo);
buf=(char *)alloca(txtinfo.screenheight*txtinfo.screenwidth*2);
gettext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf);
init_uifc(FALSE, FALSE);
while(loop) {
loop=FALSE;
i=0;
uifc.helpbuf="Duplicate file... choose action\n";
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,NULL,"Duplicate File Name",opts)) {
case 0: /* Overwrite */
sprintf(fpath,"%s/%s",cb->bbs->dldir,zm->current_file_name);
unlink(fpath);
ret=TRUE;
break;
case 1: /* Choose new name */
uifc.changes=0;
uifc.helpbuf="Duplicate Filename... enter new name";
if(uifc.input(WIN_MID|WIN_SAV,0,0,"New Filename: ",zm->current_file_name,sizeof(zm->current_file_name)-1,K_EDIT)==-1) {
loop=TRUE;
}
else {
if(uifc.changes)
ret=TRUE;
else
loop=TRUE;
}
break;
}
}
uifcbail();
puttext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf);
return(ret);
}
void zmodem_download(struct bbslist *bbs)