/* * User FTP * 6/8/87 **************************************************************************** * * * by Tim Krauskopf and Swami Natarajan * * * * National Center for Supercomputing Applications * * 152 Computing Applications Building * * 605 E. Springfield Ave. * * Champaign, IL 61820 * * * * * **************************************************************************** */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "wind.h" #include "configrec.h" #include "hostform.h" #include "whatami.h" #include "VSkeys.h" #include "prefs.h" #include "user.h" #include "util.h" #include "bkgr.h" #include "maclook.h" #include "netevent.h" #include "vsinterf.h" #include "menu.h" #include "rsmac.h" #include "macbinary.h" #include "binsubs.h" #include "ser.h" /* BYU 2.4.15 */ #include "ftppi.h" /* list of commands, help strings */ #define MACBINARY #define FASCII 0 #define FIMAGE 1 /* This is different than the definition in bkgr.c */ #define FAMODE 0 #define FIMODE 1 #define FMMODE 2 /* Mac Binary, when ready */ #define HFTP 21 #define FALSE 0 #define TRUE 1 #define SUCCESS 2 #define ERROR -1 #define NONE -2 #define ABORT -3 #define INCOMPLETE -4 #define AMBIGUOUS -5 #define HAVEDATA 4 #define BUFFERS 8000 /* size of buffer */ #define PATHLEN 256 #define READSIZE 128 /* how much to read */ #define HELPRESID 23229 long filelen=0, /* file transfer length */ start=0L, /* timing var */ towrite=0, /* file transfer pointer */ translen=0, /* length of file transfered */ transtime; int xp=0, /* general pointer */ ftpfh, /* file handle for ftp */ fcnt = 0, /* counter for ftpd */ ftpfilemode=0, /* file open mode for transfer */ hash=0, /* hash mark printing */ sendport=1, /* to send ports or not */ verbose=1, /* informative messages */ bell=0, /* sound bell */ autologin=1, /* login on connect */ prompt=1, /* check on multiple commands */ glob=1, /* expand wildcards */ slashflip=1, /* change \ to / */ fromtty=1; /* default input from tty */ static int ftpdata; #ifdef PC #define RCPSEGSIZE 1024 #define EOLCHAR 10 #ifdef MSC #define O_RAW O_BINARY #endif #else extern char *firstname(), *nextname(); extern unsigned char SLIP_ip_number[]; /* BYU 2.4.15 */ extern int defaultv, /* BYU 2.4.18 */ ftpenable, MacBinary, chgdir(), ftpdo(), netputuev(), Sfread(), Sfwrite(), WindByPort(); extern MBFile *MBopen(); extern void GetFileInfo(), setupport(); #define RCPSEGSIZE 512 #define O_RAW O_RDONLY #define EOLCHAR 13 #endif FILE *fromfp=NULL; /* file pointer for input */ MBFile *ftp_mbfp; FileParam iop; #define captlistsize 2001L unsigned char *captlist = 0L, *newfile = 0L, *transfile = 0L, /* name of file being sent/received */ *xs = 0L; /* response string */ unsigned int curftpprt = 0; /* port to use */ unsigned char *neterrstring(); static char bellchar = { 7 }; static char backspace = { 8 }; static char poundsign = { '#' }; char response_data[20][4]; /* BYU 2.4.12 - first 4 characters of each response */ unsigned char response_count[20]; /* BYU 2.4.12 - non-zero indicates waiting for response */ extern long JuggTicks; /* How many ticks to wait when Juggling */ extern int debug,ev,Juggling,scrn; extern WindRec *screens; extern char Sptypes[]; /* BYU 2.4.16 - flags for port #'s */ extern int netlisten(); /* Beginning of Macintosh Routines created at BYU, 1988 */ /************************************************************************/ /* putstring: display string using vt100 emulation routines /************************************************************************/ putstring(ftpscrn,string) int ftpscrn; char *string; { for (; *string; string++) parse( &screens[ftpscrn],string,1); } nputs(line) char *line; { putln(line); } char *stpblkp(mystring) char *mystring; { /* Return pointer to first non blank in string */ int mycnt; char *p; mycnt = 0; p = mystring; while (((*p == ' ') || (*p == '\t')) && (mycnt < 256)) { p++; mycnt++; } return(p); } char *stptok(mystring,myword,mylen,myterms) char *mystring,*myword,*myterms; int mylen; { /* Return pointer to first non blank in string */ int done,i; char *p,*q; p = stpblkp(mystring); /* skip leading blanks */ i = 0; done = 0; while (*(p+i) && (i <= mylen) && (done == 0)) { q = myterms; while ((*q) && (*q != *(p+i))) q++; if (!(*q)) { *(myword+i) = *(p+i); i++; } else done = 1; } *(myword+i) = '\0'; q = p+i; return(q); } int ftpopen(name) char *name; { int myerr; short myvrefnum,myrefnum; char volname[256]; GetVol(volname,&myvrefnum); myerr = FSOpen(name,myvrefnum,&myrefnum); return(myrefnum); } int ftpcreate(name) char *name; { int myerr; short myvrefnum,myrefnum; char volname[256]; GetVol(volname,&myvrefnum); myerr = Create(name,myvrefnum,'????','TEXT'); myerr = FSOpen(name,myvrefnum,&myrefnum); return(myrefnum); } /* End of Macintosh Routines created at BYU, 1988 */ /************************************************************************/ /* ftpgets - read a line from the keyboard /* returns ABORT if aborted, non-zero on success /************************************************************************/ ftpgets(s,lim,echo) char *s; /* where to put the line */ short lim,echo; /* max chars to read, echo? */ { int count,i,cmd_status; unsigned char c; char *save, *ret; Boolean gotOne; /* Did we get an event */ EventRecord myEvent; /* Event Record for this loop */ count = 0; /* none read */ save = s; /* beginning of line */ if (!fromtty) { if (fromfp==NULL) { ret = fgets(s,lim,stdin); } else { ret = fgets(s,lim,fromfp); } if (ret==NULL) { nputs("EOF or error on read from file\012"); cmd_status = ftpdo(scrn,"QUIT",""); netclose(screens[scrn].port); destroyport( scrn); exit(1); } s[strlen(s)-1] = '\0'; /* remove newline */ if (echo && fromfp) nputs(s); return (strlen(s)); } while (1) { if (Juggling) gotOne = WaitNextEvent(everyEvent, &myEvent, JuggTicks, 0L); else gotOne = GetNextEvent(everyEvent, &myEvent); if ((myEvent.what == keyDown) || (myEvent.what == autoKey)) c = myEvent.message & charCodeMask; else { DoModem(); /* BYU 2.4.15 */ Stask(); /* BYU 2.4.15 */ DoNetEvents(); /* process event queue */ c = 0; } switch (c) { /* allow certain editing chars */ case 8: /* backspace */ if (count) { if (echo) { parse( &screens[scrn],&c,1); parse( &screens[scrn]," ",1); parse( &screens[scrn],&c,1); } count--; /* one less character */ s--; /* move pointer backward */ } break; case 13: /* carriage return, = ok */ if (echo) putstring(scrn,"\015\012"); /* newline */ *s = '\0'; /* terminate the string */ return(c); /* return ok */ break; case 21: /* kill line */ for (i=0; i < s-save; i++) { /* length of line */ if (echo) { /* erase */ parse( &screens[scrn],&backspace,1); parse( &screens[scrn]," ",1); parse( &screens[scrn],&backspace,1); } } s = save; /* reset line */ break; case 0: /* do nothing */ break; default: /* not special char */ if (c > 31 && c < 127) { /* printable */ if (echo) parse( &screens[scrn],&c,1); /* display */ *s++ = c; /* add to string */ count++; /* length of string */ } else /* acts as eol */ return(c); /* value of special char */ if (count == lim) { /* to length limit */ *s = '\0'; /* terminate */ return(c); } break; } } } /************************************************************************/ /* captcon * capture everything from a connection into the capture list * return -1 on closed connection, else 0, 1 if paused /************************************************************************/ captcon(cnum,mywindow) int cnum,mywindow; { int capturesize,cnt = 0; unsigned char s[80]; /* temporary string */ /* if (fromtty && n_scrlck()) return(TRUE); /* if paused, nothing to do */ capturesize = screens[mywindow].capturesize; do { cnt = netread(cnum,&s[0],64); /* get some from queue */ if ((cnt + capturesize) < captlistsize) { BlockMove(&s[0],&captlist[capturesize],(long)cnt); capturesize += cnt; } /* demux all packets */ } while ((cnt > 0) && ((cnt + capturesize) < captlistsize)); captlist[capturesize] = 0; screens[mywindow].capturesize = capturesize; return(cnt); /* 0 normally, -1 if connection closed */ } /************************************************************************/ /* telnet * filter telnet options on incoming data /************************************************************************/ telnet(port,cnt,s) int port,cnt; unsigned char *s; { register int i,mylen,myport; char printline[256]; /* line to display */ myport = WindByPort(port); for (i=0; i < cnt; i++) { /* put on screen */ if (*(s+i) & 128) { /* if over ASCII 128 */ sprintf(printline," %d ",*(s+i)); /* show as number */ mylen = strlen(printline); parse( &screens[myport],&printline[0],mylen); } else parse( &screens[myport],(s+i),1); } return(TRUE); } /************************************************************************/ /* dumpcon * take everything from a connection and send it to the screen * return -1 on closed connection, else 0, 1 if paused /************************************************************************/ int dumpcon(cnum,mywindow) int cnum,mywindow; { /* BYU 2.4.12 */ short i1,i2,cnt = 0,result=0; /* BYU 2.4.12 */ unsigned char s1[64],s2[128]; /* temporary strings */ /* if (fromtty && n_scrlck()) return(TRUE); /* if paused, nothing to do */ do { cnt = netread(cnum,&s1[0],64); /* get some from queue */ /* Search the incoming data for status codes and newlines */ i1 = 0; i2 = 0; while (i1 < cnt) { /* Check for 3 digit codes beginning with "5" at the beginning of each line. */ if (s1[i1] == '\012' || s1[i1] == '\015') { /* BYU 2.4.12 */ response_count[mywindow] = 0; /* BYU 2.4.12 */ } else if (response_count[mywindow] < 4) { /* BYU 2.4.12 */ response_data[mywindow][response_count[mywindow]++] = s1[i1]; /* BYU 2.4.12 */ if (response_count[mywindow] == 4) { /* BYU 2.4.12 */ if (response_data[mywindow][0] == '5' && /* BYU 2.4.12 */ response_data[mywindow][1] >= '0' && /* BYU 2.4.12 */ response_data[mywindow][1] <= '9' && /* BYU 2.4.12 */ response_data[mywindow][2] == '0' && /* BYU 2.4.12 */ response_data[mywindow][2] <= '9' && /* BYU 2.4.12 */ response_data[mywindow][3] == ' ') /* BYU 2.4.12 */ result = -1; /* BYU 2.4.12 - Abort indicated by other host */ } } /* If a "newline" is found then force a "carriage return" immediately. */ if ('\012' == (s2[i2++] = s1[i1++])) s2[i2++] = '\015'; } telnet(cnum,i2,&s2[0]); /* display on screen, etc.*/ /* demux all packets */ } while (cnt > 0); return(result); /* BYU 2.4.12 - 0 normally, -1 if connection closed */ } /************************************************************************/ /* getword: remove a word from a string. Things within quotes are * assumed to be one word. * return TRUE on success, FALSE on end of string /************************************************************************/ getword(string,word) char *string,*word; { char *p,*q; int i=0; p = stpblkp(string); /* skip leading blanks */ if (!(*p)) { /* no words in string */ word[0] = '\0'; return(FALSE); } if (*p=='!') { /* ! is a word */ word[0] = *p; word[1] = '\0'; strcpy(string,++p); return(TRUE); } if (*p=='\"') { /* word delimited by quotes */ while (p[++i] && p[i]!='\"') word[i-1] = p[i]; word[i-1] = '\0'; if (!p[i]) nputs("Missing \". Assumed at end of string."); else i++; q = p+i; } else q = stptok(p, word, 50, " \t\015\012"); /* get word, max len 50 */ p = stpblkp(q); /* remove trailing blanks */ strcpy(string,p); /* remove extracted stuff */ return(TRUE); } /************************************************************************/ /* lowercase: convert a string to lowercase * /************************************************************************/ lowercase(word) char *word; { int i; for (i=0; word[i]=tolower(word[i]); i++); return(TRUE); } /************************************************************************/ /* finduniq: find name that is a unique prefix of one of the entries in * a list. Return position of the entry, NONE if none, AMBIGUOUS if more * than one. * /************************************************************************/ int finduniq(name,listsize) unsigned char *name; int listsize; { int i,j=NONE,len; unsigned char *p,cmdstring[256]; len = strlen(name); for (i=0; i, assume a filename follows and extract it. Remove the redirection * from the original command. * Also change \ to / * return TRUE if redirection specified, FALSE otherwise /************************************************************************/ checkoredir(command,filename,slashflip) char *command,*filename; int slashflip; { int i; filename[0] = '\0'; for (i=0; (command[i]!='>'); i++) { /* process command part */ if (slashflip && command[i] == '\\') command[i] = '/'; if (!command[i]) return(FALSE); /* no redirection */ } getword(&command[i+1],filename); /* get redirected filename */ command[i] = '\0'; return(TRUE); } /************************************************************************/ /* getnname: get next name from captured list * names delimited by newlines - or /************************************************************************/ getnname(string,word) char *string,*word; { char *s; s = string; while ((*string=='\012') || (*string=='\015')) string++; /* skip initial newlines */ if (!(*string)) return(FALSE); /* end of captlist */ while ((*string!='\012') && (*string!='\015') && (*string)) *(word++) = *(string++); while ((*string=='\012') || (*string=='\015')) string++; /* skip trailing newline */ *word = '\0'; strcpy(s,string); return(TRUE); } /********************************************************************/ /* FTP PI * Protocol interpreter for user interface commands * Will permit any command to be abbreviated uniquely. * Recognizes commands, translates them to the protocol commands to be * sent to the other server, and uses userftpd, the daemon, to do data * transfers. /************************************************************************/ ftppi(command) char *command; { Boolean needanswer; int cmdno,i,cmd_status; char cmdname[20],word[PATHLEN],line[MAXFTP],answer[20],ofilename[PATHLEN]; char *p,*getWDname(); unsigned char destname[50]; /* who to connect to */ char printline[256]; /* line to display */ if (captlist == 0) { captlist = NewPtr( (long) captlistsize); /* newfile = NewPtr( (long) PATHLEN); /* Pointer, no allocation necessary */ transfile = NewPtr( (long) PATHLEN); xs = NewPtr( (long) (BUFFERS+10)); } /* Indicates waiting for response */ /* BYU 2.4.12 */ response_count[scrn] = 0; /* BYU 2.4.12 */ /* get command number */ if (!getword(command,cmdname)) return(FALSE); /* get command name */ /* removes first word from command */ lowercase(cmdname); cmdno = finduniq(cmdname,NCMDS); /* search cmdlist for prefix */ if (cmdno==AMBIGUOUS) { /* not unique abbreviation */ putstring(scrn,"?Ambiguous command\015\012"); return(FALSE); } if (cmdno==NONE) { /* not a prefix of any command */ putstring(scrn,"?Invalid command\015\012"); return(FALSE); } /* change \ to / and check if command output redirected */ if (cmdno!=BANG) { /* don't alter shell escape */ if (cmdno!=LLS) /* do not flip slashes for LLS */ checkoredir(command,ofilename,slashflip); /* check redirection, flip \ */ else checkoredir(command,ofilename,FALSE); /* check redirection */ } /* process commands */ switch (cmdno) { case QMARK: case HELP: if (!command[0]) { /* no argument */ putstring(scrn,"Commands may be abbreviated:\015\012"); /* display command list */ printline[0] = '\0'; for (i=2; i (ftpfh = open(&name[0],ftpfilemode))) { putstring(ftpscrn,"Could not open file\015\012"); return(-1); } #endif c2pstr(&name[0]); GetFileInfo(0,&name[0],&iop); filelen = iop.ioFlLgLen; if (MacBinary && (ftpfilemode == FIMODE)) filelen += iop.ioFlRLgLen; ftpport(ftpscrn); /* open data connection */ screens[ftpscrn].ftpstate = 2; screens[ftpscrn].ftpnext = 20; strcpy(screens[ftpscrn].ftpbuf,commandbuf); strcat(screens[ftpscrn].ftpbuf,"\015\012"); return(1); } else if (!strncmp(commandbuf,"RETR",4)) { /* get file */ getword(&commandbuf[5],name); /* remote file */ if (commandbuf[5]) { /* two args present */ getword(&commandbuf[5],name2); /* local file */ #ifdef MACBINARY if ((ftp_mbfp = MBopen(&name2[0], defaultv, MB_WRITE + /* BYU 2.4.18 */ (((!MacBinary) || (ftpfilemode == FAMODE)) ? MB_DISABLE : 0 ))) == 0L) { putstring(ftpscrn,"Cannot open file to receive\015\012"); return(-1); } else ftpfh = 12; #else if (0 > (ftpfh = creat(&name2[0],ftpfilemode))) { putstring(ftpscrn,"Cannot open file to receive\015\012"); return(-1); } #endif } else { #ifdef MACBINARY if ((ftp_mbfp = MBopen(&name[0], defaultv, MB_WRITE + /* BYU 2.4.18 */ (((!MacBinary) || (ftpfilemode == FAMODE)) ? MB_DISABLE : 0 ))) == 0L) { putstring(ftpscrn,"Cannot open file to receive\015\012"); return(-1); } else ftpfh = 12; #else if (0 > (ftpfh = creat(&name[0],ftpfilemode))) { putstring(ftpscrn,"Cannot open file to receive\015\012"); return(-1); } #endif } strcpy(&commandbuf[5],name); /* Put remote name back into command */ ftpport(ftpscrn); /* open data connection */ screens[ftpscrn].ftpstate = 2; screens[ftpscrn].ftpnext = 30; strcpy(screens[ftpscrn].ftpbuf,commandbuf); strcat(screens[ftpscrn].ftpbuf,"\015\012"); return(1); } else if (!strncmp(commandbuf,"LIST",4) || !strncmp(commandbuf,"NLST",4)) { if ((screens[ftpscrn].clientflags & CAPTURE_DATA) != 0) screens[ftpscrn].capturesize = 0; /* Size of captured data */ ftpport(ftpscrn); /* data connection */ screens[ftpscrn].ftpstate = 2; screens[ftpscrn].ftpnext = 40; strcpy(screens[ftpscrn].ftpbuf,commandbuf); strcat(screens[ftpscrn].ftpbuf,"\015\012"); return(1); } else if (!strncmp(commandbuf,"TYPE",4)) { if (toupper(commandbuf[5]) == 'I') ftpfilemode = FIMAGE; /* Remember mode */ else if (toupper(commandbuf[5]) == 'A') ftpfilemode = FASCII; } netpush(screens[ftpscrn].port); strcat(commandbuf,"\015\012"); /* BYU 2.4.11 */ netwrite(screens[ftpscrn].port,commandbuf,strlen(commandbuf)); /* BYU 2.4.11 - send command */ if (((screens[ftpscrn].clientflags & CAPTURE_DATA) == 0) && ofile[0]) { /* command redirected */ if ((screens[ftpscrn].ftpstate != 20) && (screens[ftpscrn].ftpstate != 30)) { /* not get or put */ if (0 > (ftpfh = ftpopen(ofile))) nputs(" Cannot open output file."); else if (ftpdata > -1) { screens[ftpscrn].ftpstate = 30; /* act as get, since data goes into file */ } else { close(ftpfh); ftpfh = 0; } } } #if 0 if (debug) { sprintf(printline,"---> %s",commandbuf); /* show command sent */ nputs(printline); } #endif return(FALSE); } /************************************************************************/ /* userftpd * FTP receive and send file functions /************************************************************************/ userftpd(code,myport) int code,myport; { Boolean needanswer; long mytime; int cmd_status,connection_status,ftpstate,i,mycode,myftpdata,mytelport,mywindow; char command[MAXFTP],printline[MAXFTP],word[MAXFTP]; #if 0 char answer[20]; #endif mycode = code; connection_status = 0; /* BYU 2.4.12 - assume good connection status */ ftpstate = 1; mywindow = WindByPort(myport); if (mywindow >= 0) { if (myport == screens[mywindow].port) { ftpstate = screens[mywindow].ftpstate; myftpdata = -1; } else { ftpstate = screens[mywindow].ftpstate; myftpdata = screens[mywindow].ftpport; } } if (mywindow < 0) return(0); #if 0 if (debug) { sprintf(printline," %d %d %u twin: %d\015\012",ftpstate,mycode,myport,mywindow); putstring(mywindow,printline); } #endif mytelport = screens[mywindow].port; switch (ftpstate) { default: /* unknown */ break; case 1: if ((mycode == CONDATA) && (myport == mytelport)) connection_status = dumpcon(myport,mywindow); break; /* Wait for response from "PORT" command, then send ftp command */ case 2: if (mycode == CONDATA) { connection_status = dumpcon(myport,mywindow); netpush(screens[mywindow].port); netwrite(screens[mywindow].port,screens[mywindow].ftpbuf,strlen(screens[mywindow].ftpbuf)); /* send command */ screens[mywindow].ftpstate = screens[mywindow].ftpnext; #if 0 if (debug) { sprintf(printline,"---> %s",screens[mywindow].ftpbuf); /* show command sent */ nputs(printline); } #endif } break; /* Wait for response from "TYPE" command, then send ftp command */ case 3: if (mycode == CONDATA) { connection_status = dumpcon(myport,mywindow); cmd_status = ftpdo(mywindow,screens[mywindow].ftpbuf,""); #if 0 if (debug) { sprintf(printline,"---> %s",screens[mywindow].ftpbuf); /* show command sent */ nputs(printline); } #endif } break; case 5: /* Get the next file of an MGET. */ if ((screens[mywindow].clientflags & CAPTURE_DATA) != 0) { screens[mywindow].clientflags &= ~CAPTURE_DATA; } /* After capturing the data, initiate the file transfer(s) */ if ((screens[mywindow].clientflags & MGET_STATE) != 0) { if (screens[mywindow].capturesize > 0) { screens[mywindow].ftpstate = 6; netputuev(CONCLASS,CONDATA,mytelport); /* Stay alive to transfer file */ } else { screens[mywindow].clientflags &= ~MGET_STATE; screens[mywindow].ftpstate = 1; } } break; /* Receive one MGET file. */ case 6: connection_status = dumpcon(myport,mywindow); if (getnname(captlist,word)) { /* for each name */ #if 0 if (prompt) { /* check */ sprintf(printline,"mget %s? ",word); putstring(mywindow,printline); if (ftpgets(answer,20,1)==ABORT) { /* abort */ command[0] = '\0'; /* no more processing */ break; /* quit immediately */ } if (tolower(*(stpblkp(answer)))!='y') continue; } else { #endif sprintf(printline,"Receiving %s\015\013",word); putstring(mywindow,printline); #if 0 } #endif sprintf(command,"RETR \"%s\"",word); if ((cmd_status = ftpdo(mywindow,command,"")) < 0) { screens[mywindow].clientflags &= ~MGET_STATE; screens[mywindow].ftpstate = 1; } } else { screens[mywindow].clientflags &= ~MGET_STATE; screens[mywindow].ftpstate = 1; } break; /* Send a file to the remote connection */ case 20: if (mycode == CONFAIL) mycode = CONCLOSE; /* something went wrong */ if (mycode == CONOPEN) { screens[mywindow].ftpstate = 21; transtime = TickCount(); translen = 0; towrite = 0; xp = 0; netputuev(CONCLASS,CONDATA,myport); } else if ((mycode == CONDATA) && (myport == mytelport)) { connection_status = dumpcon(myport,mywindow); } break; case 21: /* * transfer file(s) to the other host via ftp request * file is already open = ftpfh */ if (mycode == CONDATA) { if (myport == mytelport) { connection_status = dumpcon(myport,mywindow); } else if (myport == myftpdata) { netputuev(CONCLASS,CONDATA,myport); /* Stay alive */ if (towrite <= xp) { i = BUFFERS; #ifdef MACBINARY towrite = MBread( ftp_mbfp, xs, i); #else /* towrite = read(ftpfh,xs,i); /* */ towrite = BUFFERS; FSRead(ftpfh,&towrite,&xs[0]); #endif xp = 0; } if ((towrite <= 0) || netest(myftpdata)) { /* we are done */ if (ftp_mbfp->fd != 0) MBclose( ftp_mbfp ); /* BYU - close input file */ screens[mywindow].ftpstate = 22; break; } if (ftpfilemode == FAMODE) i = Sfwrite(myftpdata,&xs[xp],(int) towrite-xp); else i = netwrite(myftpdata,&xs[xp],(int) towrite-xp); if (i > 0) { xp += i; translen += i; } mytime = TickCount(); if ((transtime + 800) < mytime) { transtime = mytime; sprintf(printline,"%ld/%ld bytes sent.\015\013",translen,filelen); i = strlen(printline); parse( &screens[mywindow],&printline[0],i); } } } break; case 22: /* wait for data to be accepted */ netputuev(CONCLASS,CONDATA,myport); /* Stay alive */ fcnt = netpush(myftpdata); /* will go negative on err */ if (!fcnt || netest(myftpdata)) { mycode = CONCLOSE; sprintf(printline,"%ld/%ld bytes sent.\015\013",translen,filelen); parse( &screens[mywindow],&printline[0],strlen(printline)); } if ((mycode == CONDATA) && (myport == mytelport)) connection_status = dumpcon(myport,mywindow); break; /* Get a file from the remote connection */ case 30: if (mycode == CONFAIL) mycode = CONCLOSE; /* something went wrong */ if (mycode == CONOPEN) { screens[mywindow].ftpstate = 31; filelen = xp = 0; transtime = TickCount(); translen = 0L; } else if ((mycode == CONDATA) && (myport == mytelport)) { connection_status = dumpcon(myport,mywindow); } break; /* * file has already been opened, take everything from the connection * and place into the open file: ftpfh */ case 31: if (mycode == CONDATA) { if (myport == mytelport) { connection_status = dumpcon(myport,mywindow); } else if (myport == myftpdata) { /* wait until xs is full before writing to disk */ if (filelen <= 2000) { if (xp) { #ifdef MACBINARY if (0 > MBwrite(ftp_mbfp, xs, xp)) mycode = CONCLOSE; #else if (0 > write(ftpfh,xs,xp)) /* disk full err */ mycode = CONCLOSE; #endif xp = 0; } filelen = BUFFERS; /* expected or desired len to go */ } if (mycode == CONDATA) { if (ftpfilemode == FAMODE) fcnt = Sfread(myftpdata,&xs[xp],(int)filelen); else fcnt = netread(myftpdata,&xs[xp],(int)filelen); if (fcnt >= 0) { filelen -= fcnt; xp += fcnt; translen += fcnt; } mytime = TickCount(); if ((transtime + 800) < mytime) { transtime = mytime; if ((screens[mywindow].clientflags & MGET_STATE) == 0) { sprintf(printline,"%ld bytes received.\015\013",translen); i = strlen(printline); parse( &screens[mywindow],&printline[0],i); } } /* printf(" %d %d %d \012",filelen,xp,fcnt); n_row(); */ if (fcnt < 0) { #ifdef MACBINARY if (0 > MBwrite( ftp_mbfp, xs, xp)) { break; } if (ftp_mbfp->fd != 0) { MBclose( ftp_mbfp ); } #else if (0 > write(ftpfh,xs,xp)) { /* disk full check */ break; } close(ftpfh); #endif ftpfh = 0; } netputuev(CONCLASS,CONDATA,myport); } } } /* Ouput any remaining data before closing */ if (mycode == CONCLOSE) { if (xp) { #ifdef MACBINARY if (0 > MBwrite(ftp_mbfp, xs, xp)) netclose(myftpdata); #else if (0 > write(ftpfh,xs,xp)) /* disk full err */ netclose(myftpdata); #endif } if ((screens[mywindow].clientflags & MGET_STATE) == 0) { sprintf(printline,"%ld bytes received.\015\013",translen); i = strlen(printline); parse( &screens[mywindow],&printline[0],i); } } break; /* Waiting for "ftpdata" connection to open, display any communication from the telnet port. */ case 40: if (mycode == CONOPEN) screens[mywindow].ftpstate = 41; if ((myport == myftpdata) && ((screens[mywindow].clientflags & CAPTURE_DATA) != 0)) { captcon(myport,mywindow); } else { connection_status = dumpcon(myport,mywindow); } break; /* If the "ftpdata" port is open, then postpone reading and displaying any data from other ports once data has been received. Otherwise, read and display data from anywhere. */ case 41: if (mycode == CONDATA) { if ((myport == myftpdata) && ((screens[mywindow].clientflags & CAPTURE_DATA) != 0)) { captcon(myport,mywindow); } else { connection_status = dumpcon(myport,mywindow); } if (myport == myftpdata) screens[mywindow].ftpstate = 42; netputuev(CONCLASS,CONDATA,myport); } else if (mycode == CONCLOSE) { screens[mywindow].ftpstate = 40; } break; /* Only data from "ftpdata" */ case 42: if (mycode == CONDATA) { if (myport == myftpdata) { if ((screens[mywindow].clientflags & CAPTURE_DATA) != 0) { captcon(myport,mywindow); } else { connection_status = dumpcon(myport,mywindow); } } netputuev(CONCLASS,CONDATA,myport); /* Keep port monitoring alive */ } else if (mycode == CONCLOSE) { screens[mywindow].ftpstate = 40; } break; } /* end of switch */ /* * After reading from connection, if the connection is closed, * reset up shop. */ if ((mycode == CONCLOSE) || (connection_status < 0)) { /* BYU 2.4.12 */ if (connection_status < 0) /* BYU 2.4.12 */ screens[mywindow].clientflags &= ~MPUT_STATE; if (ftpfh > 0) { close(ftpfh); ftpfh = 0; } if (ftp_mbfp->fd != 0) MBclose( ftp_mbfp ); screens[mywindow].ftpstate = 1; fcnt = 0; if (myftpdata == myport) { netclose(myftpdata); Sptypes[myftpdata] = -1; screens[mywindow].ftpport = -1; } if ((screens[mywindow].clientflags & TYPE_I_ON_CLOSE) != 0) { screens[mywindow].clientflags = 0; cmd_status = ftpdo(mywindow,"TYPE I",""); } /* Send the next file of an MPUT */ if ((screens[mywindow].clientflags & MPUT_STATE) != 0) { needanswer = TRUE; while (needanswer) { needanswer = FALSE; if (glob) { /* local wildcard expansion */ newfile = nextname(transfile); /* get next name */ if (newfile == NULL) { /* if no expansions yet */ if (getword(captlist,transfile)) { newfile = firstname(transfile); /* get first name */ if (newfile == NULL) { /* if no expansions */ sprintf(printline,"No match for %s",transfile); nputs(printline); } } } } else if (getword(captlist,transfile)) { newfile = transfile; } else newfile = NULL; if (newfile == NULL) { screens[mywindow].clientflags &= ~MPUT_STATE; screens[mywindow].ftpstate = 1; } else { #if 1 /* When prompting is fixed switch to the code below */ sprintf(screens[mywindow].ftpbuf,"STOR \"%s\"",newfile); cmd_status = ftpdo(mywindow,screens[mywindow].ftpbuf,""); #else if (prompt) { /* check */ sprintf(printline,"mput %s? ",newfile); putstring(mywindow,printline); if (ftpgets(answer,20,1) == ABORT) { /* abort */ screens[mywindow].clientflags &= ~MPUT_STATE; screens[mywindow].ftpstate = 1; } else if (tolower(*(stpblkp(answer))) != 'y') { needanswer = TRUE; } else { sprintf(screens[mywindow].ftpbuf,"STOR \"%s\"",newfile); cmd_status = ftpdo(mywindow,screens[mywindow].ftpbuf,""); } } else { /* The Mac file may have special characters, so quote the whole thing */ sprintf(screens[mywindow].ftpbuf,"STOR \"%s\"",newfile); cmd_status = ftpdo(mywindow,screens[mywindow].ftpbuf,""); } #endif } } } if ((screens[mywindow].clientflags & MGET_STATE) != 0) { screens[mywindow].ftpstate = 5; /* BYU 3 */ netputuev(CONCLASS,CONDATA,mytelport); /* BYU 3 - Stay alive to transfer file */ } } return(TRUE); } #if 0 /************************************************************************/ /* getdir: get current directory. Finds current drive and current path * on drive, returns a string. * /************************************************************************/ getdir(drive,path) int drive; char *path; { char partpath[64]; if (!drive) drive = getdsk(); /* current disk */ getcd(drive+1,partpath); /* current dir */ sprintf(path,"%c:\\%s",'A'+drive,partpath); return(TRUE); } finduniq(name,list,listsize) char *name, *list[]; int listsize; { int i,j=NONE,len; len = strlen(name); for (i=0; i