home *** CD-ROM | disk | FTP | other *** search
- /*
- * User FTP
- * 6/8/87
- ****************************************************************************
- * *
- * by Tim Krauskopf and Swami Natarajan *
- * Microsoft port by Heeren Pathak *
- * *
- * National Center for Supercomputing Applications *
- * 152 Computing Applications Building *
- * 605 E. Springfield Ave. *
- * Champaign, IL 61820 *
- * *
- * *
- ****************************************************************************
- *
- */
-
- /*
- *Thanks to Jyrki Kuoppala(jkp@hutcs.hut.fi) for the basis of changes for
- * MSC 5.1
- */
-
- #define FTPMASTER
-
- #ifdef __TURBOC__
- #include "turboc.h"
- #endif
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <signal.h>
- #include <time.h>
- #include <io.h>
- #include <errno.h>
- #include <string.h>
- #include <conio.h>
-
- #ifdef MSC
- #define O_RAW O_BINARY
- #include <dos.h>
- #ifndef _TURBOC_
- #include <direct.h>
- #endif
- #include <malloc.h>
- #endif
-
- #ifdef MEMORY_DEBUG
- #include "memdebug.h"
- #endif
- #include "nkeys.h"
- #include "hostform.h"
- #include "whatami.h"
- #include "ftppi.h" /* list of commands, help strings */
- #include "externs.h"
- #include "defines.h"
-
- #define VDD_SEG 0x40
- #define VDD_ROWS_OFF 0x84 /* This points to a BYTE */
- #define VDD_COLS_OFF 0x4a /* This points to a WORD (int) */
-
- #define FASCII 0
- #define FIMAGE 1
- #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
-
- int xp=0, /* general pointer */
- towrite=0, /* file transfer pointer */
- len=0, /* file transfer length */
- ftpnum, /* current command port */
- ftpdata=-1, /* current data port */
- ftpfh, /* file handle for ftp */
- ftpstate=0, /* state for background process */
- fcnt = 0, /* counter for ftpd */
- ftpfilemode=0, /* file open mode for transfer */
- foundbreak=0, /* cntrl-break pending */
- connected=0, /* not connected */
- debug=0, /* debug level */
- bypass_passwd=0, /* whether to bypass the password check */
- hash=0, /* hash mark printing */
- sendport=1, /* to send ports or not */
- verbose=1, /* informative messages */
- redirect=1, /* check for ouput redirection */
- bell=0, /* sound bell */
- autologin=1, /* login on connect */
- prompt=1, /* check on multiple commands */
- tempprompt=0, /* temp var for Yes/No/All/Quit convenience */
- glob=1, /* expand wildcards */
- slashflip=1, /* change \ to / */
- capture=0, /* capture data or not */
- usemore=0, /* use |more */
- numlines=24, /* number of lines for |more */
- lineslft=24, /* number of lines left for |more */
- ttypass=0, /* use interactive for password */
- fromtty=1, /* default input from tty */
- f_enter_login=FALSE, /* noninteractive but ask for user and pass */
- display_init=FALSE, /* TRUE if title line has been given */
- scrsetup=0, /* FALSE if need to clear screen */
- dos_color; /* storage for the DOS color setup */
-
- FILE *fromfp=NULL; /* file pointer for input */
- unsigned int curftpprt=0; /* port to use */
- unsigned char destname[50]={0,0}, /* who to connect to */
- s[550], /* temporary string */
- path_name[_MAX_DRIVE+_MAX_DIR], /* character storage for the path name */
- captlist[2001], /* response string */
- ftpcommand[200]; /* command to execute */
- char printline[2001]; /* line to display */
-
- struct config def;
-
- char *config;
-
- #ifdef _TURBOC_
- int use_mouse=0;
- #endif
-
- #ifdef _TURBOC_
- #define BUFFERS 10000 /* size of buffer */
- #else
- #define BUFFERS 20000 /* size of buffer */
- #endif
- #define READSIZE 256 /* how much to read */
-
- static unsigned char xs[BUFFERS+10]; /* buffer space for file transfer */
-
- long start=0L, /* timing var */
- lengthfile=0L; /* length of current file for transfer */
-
- /* function prototypes for local functions */
- int main(int argc,char *argv[]);
- static char *stpblk(char *ch);
- static void breakstop(void );
- static unsigned int ftpport(void );
- static char *stptok(char *p,char *toword,int len,char *delim);
- static void nputs(char *line);
- static int printerr(void );
- static int ftppi(char *command);
- static int putstring(char *string);
- static int ftpgets(char *s,int lim,int echo);
- static int ftpdo(char *s,char *ofile);
- static int checkevent(void );
- static void nputchar(char ch);
- static int dumpcon(int cnum);
- static void telnet(int cnt);
- static int getword(char *string,char *word);
- static int finduniq(char *name,char *list[],int listsize);
- static int checkoredir(char *command,char *filename,int slashflip);
- static void flip_slashes(char *command,char *filename);
- static void getdir(int drive,char *path);
- static int ftpreplies(int cnum,int *rcode);
- static int getnname(char *string,char *word);
- static int rgetline(int cnum);
- static void userftpd(void );
- int numrows(void);
- void give_args(void);
- int domore(void);
- static char *check_file_name (char *in_fname, char *out_fname);
-
- /************************************************************************/
- /* main - main procedure. Displays opening message, parses arguments,
- /* initializes network, reads user commands and executes them, and
- /* cleans up.
- /************************************************************************/
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int i,c;
- static char Configfile[50]="config.tel";
- static char fromfile[20]="";
-
- n_window(0,0,(int)*(char far *)MK_FP(VDD_ROWS_OFF,VDD_SEG),
- *(int far *)MK_FP(VDD_COLS_OFF,VDD_SEG)); /* to correctly handle non standard screen sizes */
- #ifdef __TURBOC__
- fnsplit(argv[0],path_name,s,captlist,printline); /* split path up */
- #else
- _splitpath(argv[0],path_name,s,captlist,printline); /* split the full path name of telbin.exe into it's components */
- #endif
- strcat(path_name,s); /* append the real path name to the drive specifier */
-
- #ifdef MSC
- signal(SIGINT, breakstop);
- #else
- onbreak(&breakstop); /* break handler */
- #endif
-
-
- config=getenv("CONFIG.TEL");
- if (config) strcpy(Configfile,config);
-
- /*
- * initialize network
- */
- destname[0]='\0'; /* destination unknown */
- /* parse arguments */
- for(i=1; i<argc; i++) {
- if(argv[i][0]=='-' || argv[i][0] == '/') {
- switch(tolower(argv[i][1])) {
- case 'r': /* turn off output redirection */
- redirect=FALSE;
- break;
-
- case 'v': /* display informative messages */
- verbose=TRUE;
- break;
-
- case 'n': /* do not login on connect */
- autologin=FALSE;
- break;
-
- case 'i': /* interactive prompting off */
- prompt=FALSE;
- break;
-
- case 'g': /* wildcard expansion off */
- glob=FALSE;
- break;
-
- case 'd': /* debug, optional level */
- if(sscanf(argv[++i],"%d",&debug)<=0)
- debug=TRUE;
- break;
-
- case 's': /* do not change \ to / */
- slashflip=FALSE;
- break;
-
- case 'h': /* host file name */
- strcpy(Configfile,argv[++i]);
- break;
-
- case 'm': /* use built in |more */
- printf("\nusing more...");
- usemore=TRUE;
- numlines=numrows();
- lineslft=numlines;
- printf("\nusing more...");
- break;
-
- case 'e': /* noninteractive commands with interactive login */
- f_enter_login = TRUE;
-
- case 'p': /* noninteractive with interactive password */
- ttypass=TRUE;
-
- case 'f': /* noninteractive, optional filename */
- fromtty=FALSE; /* noninteractive input */
- strcpy(fromfile,argv[++i]);
- if(fromfile[0]) {
- fromfp=fopen(fromfile,"r");
- if(fromfp==NULL) {
- sprintf(printline,"Could not open file: %s",fromfile);
- nputs(printline);
- return(1);
- }
- }
- break;
-
- case '?':
- give_args();
-
- default: /* unknown option */
- sprintf(printline,"Unrecognized option -%c ignored",argv[i][1]);
- nputs(printline);
- break;
- }
- }
- else sscanf(argv[i],"%s",destname); /* destination host */
- }
-
- *strrchr(argv[0],'\\') == 0; /* put null at end of pathname string */
- Shostpath(argv[0]); /* and set the path */
- Shostfile(Configfile); /* open host file */
-
- if(c=Snetinit()) { /* cannot initialize network */
- printerr(); /* display TCP/IP message */
- nputs("Error initializing network");
- if(c==-3) /* check for BOOTP server not responding */
- netshut(); /* release network */
- return(1);
- }
-
- Sgetconfig(&def); /* get information provided in hosts file */
- if(destname[0])
- sprintf(ftpcommand,"open %s",destname); /* if destination specified, connect to it */
- nputs(""); /* initializes screen if not done */
- do {
- if(*ftpcommand) {
- ftppi(ftpcommand); /* if command available, execute it */
- if(debug>4) nputs("after returning from ftppi() ");
- } /* end if */
- /* if(fromtty)
- n_cur(n_row(),0); in case screen messed up */
- putstring("ftp> "); /* prompt */
- lineslft = numlines; /* for |more */
- c=ftpgets(ftpcommand,200,1); /* read cmd from user */
- }while(c!=ABORT); /* Alt-F3 aborts */
- netclose(ftpnum); /* close command connection */
- netshut(); /* terminate network stuff */
-
- return(0);
- }
-
- void give_args(void) {
- nputs("FTP [-dfghimnprsv?] [hostname]");
- nputs(" d - Debug [level]");
- nputs(" f - input File <filename>");
- nputs(" g - Global wildcard expansion off");
- nputs(" h - Host file <filename>");
- nputs(" i - Interactive prompting off");
- nputs(" m - use built in More");
- nputs(" n - No login on connect");
- nputs(" p - input file with interactive Password <filename>");
- nputs(" r - turn off command line output Redirection");
- nputs(" s - turn off Slash flip (/\\)");
- nputs(" v - Verbose");
- nputs(" ? - This list");
- exit(1);
- }
-
- /************************************************************************/
- /* ftpgets - read a line from the keyboard
- /* returns ABORT if aborted, non-zero on success
- /************************************************************************/
-
- static int ftpgets(s,lim,echo)
- char *s; /* where to put the line */
- int lim,echo; /* max chars to read, echo? */
- {
- int c,count,i;
- char *save, *ret;
-
- count=0; /* none read */
- save=s; /* beginning of line */
-
- if(foundbreak) {
- foundbreak=0;
- *s='\0';
- nputs("");
- return(ABORT);
- }
- 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\n");
- if(connected) {
- ftpdo("QUIT","");
- connected=FALSE;
- }
- netclose(ftpnum); /* close command connection */
- netshut();
- if (display_init) { /* Restore DOS' color scheme */
- n_color(dos_color);
- n_clear(); /* clear screen */
- n_wrap(1); /* cursor positioning */
- n_cur(0,0);
- };
- exit(1);
- }
- s[strlen(s)-1]='\0'; /* remove newline */
- if(echo && fromfp)
- nputs(s);
- return(strlen(s));
- }
- while(1) {
- if(foundbreak) { /* abort */
- s=save; /* reset line */
- *s='\0'; /* null line */
- nputs(""); /* newline */
- foundbreak=0; /* break processed */
- return(ABORT);
- }
- /* SAR 9/13/90 */
- if (!kbhit()) { /* if no char available */
- checkevent(); /* check event queue */
- c=0;
- }
- else c=getch(); /* else get character */
- switch(c) { /* allow certain editing chars */
- case BACKSPACE:
- case 8: /* backspace */
- if(count) {
- if(echo) {
- nputchar((char)8);
- nputchar(' ');
- nputchar((char)8);
- }
- count--; /* one less character */
- s--; /* move pointer backward */
- }
- break;
-
- case EOF:
- case 13: /* carriage return,=ok */
- nputs(""); /* newline */
- *s='\0'; /* terminate the string */
- return(c); /* return ok */
- break;
-
- case 10: /* line feed */
- break; /* ignore */
-
- case 21: /* kill line */
- for(i=0; i<s-save; i++) { /* length of line */
- if(echo) { /* erase */
- nputchar(8);
- nputchar(' ');
- nputchar(8);
- }
- }
- s=save; /* reset line */
- break;
-
- case 0: /* do nothing */
- break;
-
- default: /* not special char */
- if(c>31&&c<127) { /* printable */
- if(echo) nputchar((char)c); /* display */
- *s++=(char)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;
-
- }
-
- }
- }
-
- /************************************************************************/
- /* dumpcon
- * take everything from a connection and send it to the screen
- * return -1 on closed connection, else 0, 1 if paused
- /************************************************************************/
-
- static int dumpcon(cnum)
- int cnum;
- {
- int cnt;
- if(fromtty && n_scrlck())
- return(TRUE); /* if paused, nothing to do */
- do {
- cnt=netread(cnum,s,64); /* get some from queue */
- telnet(cnt); /* display on screen, etc.*/
- } while(cnt>0);
- return(cnt); /* 0 normally, -1 if connection closed */
- }
-
-
- /************************************************************************/
- /* telnet
- * filter telnet options on incoming data
- /************************************************************************/
-
- static void telnet(cnt)
- int cnt;
- {
- int i;
-
- if(debug>4) {
- sprintf(printline,"telnet(): cnt=%d ",cnt);
- nputs(printline);
- } /* end if */
- for(i=0; i<cnt; i++) { /* put on screen */
- if(s[i] & 128) { /* if over ASCII 128 */
- sprintf(printline," %d ",(int)s[i]); /* show as number */
- nputs(printline);
- }
- else
- nputchar(s[i]);
- }
- if(debug>4) {
- nputs("telnet(): leaving ");
- } /* end if */
- }
-
- /********************************************************************/
- /* 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.
- /************************************************************************/
-
- static int ftppi(command)
- char *command;
- {
- int retry;
- int cmdno,i;
- char cmdname[50],word[50],line[100],answer[20],ofilename[50];
- char *p,*firstname(),*nextname();
- struct machinfo *mp,*Sgethost();
-
- if(debug>1) { /* print command */
- sprintf(printline,"command: %s",command);
- nputs(printline);
- }
- /* get command number */
- if(!getword(command,cmdname))
- return(FALSE); /* get command name */
- /* removes first word from command */
- strlwr(cmdname);
- cmdno=finduniq(cmdname,ftp_cmdlist,NCMDS); /* search cmdlist for prefix */
- if(cmdno==AMBIGUOUS) { /* not unique abbreviation */
- nputs("?Ambiguous command");
- return(FALSE);
- }
- if(cmdno==NONE) { /* not a prefix of any command */
- nputs("?Invalid command");
- return(FALSE);
- }
- /* change \ to / and check if command output redirected */
- if(cmdno!=BANG) { /* don't alter shell escape */
- if(redirect) { /* check for ouput redirection selected */
- if(cmdno!=LLS) /* do not flip slashes for LLS */
- checkoredir(command,ofilename,slashflip); /* check redirection, flip \ */
- else
- checkoredir(command,ofilename,FALSE); /* check redirection */
- } /* end if */
- else { /* no output redirection */
- if(cmdno!=LLS && slashflip) /* don't flip slashes for LLS and check for slashflipping here and assume it in routine */
- flip_slashes(command,ofilename);
- } /* end else */
- }
- /* process commands */
- switch(cmdno) {
- case QMARK:
- case HELP:
- if(!command[0]) { /* no argument */
- nputs("Commands may be abbreviated. Commands are:\n");
- /* display command list */
- printline[0]='\0';
- for(i=0; i<NCMDS; i++) {
- sprintf(word,"%-16s",ftp_cmdlist[i]); /* get word from list */
- strcat(printline,word); /* add to line */
- if(i%5==4) { /* display line */
- printline[79]='\0';
- nputs(printline);
- printline[0]='\0';
- }
- }
- if(i%5!=4)
- nputs(printline); /* last line */
- return(TRUE);
- }
- /* help for specific commands */
- else {
- while(getword(command,word)) { /* loop for all args */
- i=finduniq(word,ftp_cmdlist,NCMDS); /* which command? */
- if(i==AMBIGUOUS) /* non-unique command name */
- sprintf(printline,"?Ambiguous help command %s",word);
- else
- if(i==NONE) /* no such command */
- sprintf(printline,"?Invalid help command %s",word);
- else /* display help string */
- sprintf(printline,"%s",helpstrings[i-1]);
- nputs(printline);
- }
- return(TRUE);
- }
- break;
-
- case BANG: /* shell escape */
- fflush(stdout);
- if(*(stpblk(command))) { /* command specified */
- system(command); /* execute command */
- return(TRUE);
- }
- dosescape(); /* subshell */
- return(TRUE);
-
- case BELL:
- if(getword(command,word)) { /* scan arg */
- strlwr(word);
- if(!strcmp(word,"off"))
- bell=FALSE;
- else
- if(!strcmp(word,"on"))
- bell=TRUE;
- else
- bell=!bell;
- }
- else
- bell=!bell;
- if(bell)
- nputs("Bell mode on.");
- else
- nputs("Bell mode off.");
- return(TRUE);
-
- case BYE:
- case QUIT:
- if(connected) {
- ftpdo("QUIT",ofilename);
- connected=FALSE;
- }
- /* if(fromtty) hack
- n_cur(24,0); go to bottom of screen */
- netclose(ftpnum); /* close command connection */
- netshut();
- if (display_init) { /* Restore DOS' color scheme */
- n_color(dos_color);
- n_clear(); /* clear screen */
- n_wrap(1); /* cursor positioning */
- n_cur(0,0);
- };
- exit(0);
-
- case DEBUG: /* turn on/off debugging, optional level */
- if(sscanf(command,"%d",&i)>0)
- debug=i; /* level */
- else
- if(getword(command,word)) { /* scan arg */
- strlwr(word);
- if(!strcmp(word,"off"))
- debug=FALSE;
- else
- if(!strcmp(word,"on"))
- debug=TRUE;
- else
- debug=!debug;
- }
- else
- debug=!debug;
- if(debug) {
- sprintf(printline,"Debugging on(debug=%d).",debug);
- nputs(printline);
- }
- else
- nputs("Debugging off.");
- return(TRUE);
-
- case GLOB: /* wildcard expansion */
- if(getword(command,word)) {
- strlwr(word);
- if(!strcmp(word,"off"))
- glob=FALSE;
- else
- if(!strcmp(word,"on"))
- glob=TRUE;
- else
- glob=!glob;
- }
- else
- glob=!glob;
- if(glob)
- nputs("Globbing on.");
- else
- nputs("Globbing off.");
- return(TRUE);
-
- case HASH: /* hash mark printing */
- if(getword(command,word)) {
- strlwr(word);
- if(!strcmp(word,"off"))
- hash=FALSE;
- else
- if(!strcmp(word,"on"))
- hash=TRUE;
- else
- hash=!hash;
- }
- else
- hash=!hash;
- if(hash)
- nputs("Hash mark printing on(1024 bytes/hash mark).");
- else
- nputs("Hash printing off.");
- return(TRUE);
-
- case INTERACTIVE: /* prompting on multiple transfers */
- prompt=TRUE;
- nputs("Interactive mode on.");
- return(TRUE);
-
- case LCD: /* change local directory */
- if(command[1]==':') { /* if disk specified */
- #ifdef MSC
- #ifdef __TURBOC__
- setdisk(tolower(command[0])-'a');
- #else
- unsigned int bogus;
- _dos_setdrive( tolower( command[0])-'a'+1,&bogus);
- #endif
- #else
- chgdsk(tolower(command[0])-'a');
- #endif
- strcpy(command,&command[2]);
- }
- if(*(stpblk(command))&&chdir(command)) { /* CD */
- nputs("Unable to change directory");
- }
- getdir(0,line); /* current directory */
- sprintf(printline,"Local directory now %s",line);
- nputs(printline);
- return(TRUE);
-
- case LLS: /* local DIR */
- sprintf(line,"DIR %s",command);
- fflush(stdout);
- system(line);
- return(TRUE);
-
- case MORE: /* toggle use of MORE */
- if (getword(command,word)) {
- strlwr(word);
- if (!strcmp(word,"off"))
- usemore=FALSE;
- else if (!strcmp(word,"on"))
- usemore=TRUE;
- }
- else usemore=!usemore;
- if (usemore) nputs("Use of built in | more on.");
- else nputs("Use of built in | more off.");
- numlines=numrows();
- lineslft=numlines;
- break;
-
- case NONINTERACTIVE: /* turn off interactive prompting */
- prompt=FALSE;
- nputs("Interactive mode off.");
- return(TRUE);
-
- case OPEN: /* open connection to host */
- if(connected) {
- nputs("Already connected.");
- return(FALSE);
- }
- while(!(*(stpblk(command)))) { /* no argument */
- putstring("To: ");
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE);
- }
- getword(command,destname); /* host name */
- mp=Sgethost(destname); /* get host info */
- if(foundbreak) return(FALSE); /* abort */
- if(mp==NULL) { /* try domain serving */
- Sdomain(destname);
- while(mp==NULL) {
- switch(checkevent()) {
- case ABORT:
- return(FALSE); /* abort */
-
- case DOMFAIL:
- printerr();
- sprintf(printline,"Unknown host: %s\n",destname);
- nputs(printline);
- return(FALSE);
-
- case DOMOK:
- mp=Slooknum(ftpnum); /* get host info */
- break;
-
- default:
- break;
- }
- } /* end while */
- }
- display_init=TRUE;
- def.color[0]=(unsigned char) (mp->nfcolor + (mp->nbcolor<<4));
- scrsetup=FALSE;
- nputs("");
- if(sscanf(command,"%d",&i)>0) /* port number specified */
- ftpnum=Snetopen(mp,i);
- else {
- ftpnum=Snetopen(mp,HFTP); /* default port */
- }
- if(foundbreak) return(FALSE); /* abort */
- if(ftpnum<0) { /* error on open */
- printerr();
- sprintf(printline,"Unable to connect to %s",destname);
- nputs(printline);
- return(FALSE);
- }
- ftpreplies(ftpnum,&i); /* response from other end */
- if(foundbreak) return(FALSE);
- connected=TRUE;
- if(autologin) { /* execute login command */
- strcpy(command,"user");
- ftppi(command);
- }
- return(TRUE);
-
- case PROMPT: /* interactive prompting */
- if(getword(command,word)) {
- strlwr(word);
- if(!strcmp(word,"off"))
- prompt=FALSE;
- else
- if(!strcmp(word,"on"))
- prompt=TRUE;
- else prompt=!prompt;
- }
- else
- prompt=!prompt;
- if(prompt)
- nputs("Interactive mode on.");
- else
- nputs("Interactive mode off.");
- return(TRUE);
-
- case SENDPORT: /* send PORT commands for each transfer */
- if(getword(command,word)) {
- strlwr(word);
- if(!strcmp(word,"off"))
- sendport=FALSE;
- else
- if(!strcmp(word,"on"))
- sendport=TRUE;
- else
- sendport=!sendport;
- }
- else
- sendport=!sendport;
- if(sendport)
- nputs("Use of PORT cmds on.");
- else
- nputs("Use of PORT cmds off.");
- return(TRUE);
-
- case SLASHFLIP: /* change \ to / */
- if(getword(command,word)) {
- strlwr(word);
- if(!strcmp(word,"off"))
- slashflip=FALSE;
- else
- if(!strcmp(word,"on"))
- slashflip=TRUE;
- else
- slashflip=!slashflip;
- }
- else
- slashflip=!slashflip;
- if(slashflip)
- nputs("Slash translation on.");
- else
- nputs("Slash translation off.");
- return(TRUE);
-
- case STATUS: /* display status info */
- if(connected) {
- sprintf(printline,"Connected to %s",destname);
- nputs(printline);
- }
- if(ftpfilemode==FASCII)
- nputs("Transfer mode is ascii.");
- else
- nputs("Transfer mode is binary.");
- if(bell)
- nputs("Bell on."); else nputs("Bell off.");
- if(debug) {
- sprintf(printline,"Debugging on.(Debug=%d)",debug);
- nputs(printline);
- }
- else
- nputs("Debugging off.");
- if(glob)
- nputs("Filename globbing on.");
- else
- nputs("Filename globbing off.");
- if(hash)
- nputs("Hash-mark printing on.");
- else
- nputs("Hash-mark printing off.");
- if(prompt)
- nputs("Interactive prompting on.");
- else
- nputs("Interactive prompting off.");
- if(sendport)
- nputs("Sending of port commands on.");
- else
- nputs("Sending of PORT cmds off.");
- if(slashflip)
- nputs("Flipping \\ to / on.");
- else
- nputs("Flipping \\ to / off.");
- if(verbose)
- nputs("Verbose mode on.");
- else
- nputs("Verbose mode off.");
- if (usemore)
- nputs("Use of built in | more on.");
- else
- nputs("Use of built in | more off.");
- if(connected) { /* send STAT command */
- nputs("\nRemote status:");
- ftpdo("STAT",ofilename);
- }
- return(TRUE);
-
- case VERBOSE: /* display informative messages */
- if(getword(command,word)) {
- strlwr(word);
- if(!strcmp(word,"off"))
- verbose=FALSE;
- else
- if(!strcmp(word,"on"))
- verbose=TRUE;
- else
- verbose=!verbose;
- }
- else
- verbose=!verbose;
- if(verbose)
- nputs("Verbose mode on.");
- else
- nputs("Verbose mode off.");
- return(TRUE);
-
- default: /* The other commands valid only if connected */
- if(!connected) {
- nputs("Not connected.");
- return(FALSE);
- }
-
- switch(cmdno) {
- case ASCII: /* transfer mode */
- ftpdo("TYPE A",ofilename);
- return(TRUE);
-
- case BGET: /* get file in binary mode */
- i=ftpfilemode; /* save current mode */
- if(i==FASCII)
- ftpdo("TYPE I",ofilename);
- while(!(*(stpblk(command)))) {
- putstring("File: ");
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE);
- }
- sprintf(line,"RETR %s",command);
- ftpdo(line,ofilename); /* get file */
- if(i==FASCII)
- ftpdo("TYPE A",ofilename); /* restore mode */
- return(TRUE);
-
- case BINARY: /* binary mode */
- ftpdo("TYPE I",ofilename);
- return(TRUE);
-
- case BPUT: /* put file in binary mode */
- i=ftpfilemode;
- if(i==FASCII)
- ftpdo("TYPE I",ofilename);
- while(!(*(stpblk(command)))) { /* if no arg */
- putstring("File: "); /* get from user */
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE);
- }
- sprintf(line,"STOR %s",command);
- for (retry = 0; retry < 5; retry++) {
- if ((i = ftpdo(line,ofilename)) == TRUE) {
- if(i==FASCII) ftpdo("TYPE A",ofilename);
- return(TRUE);
- }
- else if (i != FALSE) {
- if(i==FASCII) ftpdo("TYPE A",ofilename);
- return(ERROR);
- }
- printf("\nRetrying...");
- }
- printf("Maximum retry count reached. Aborting this file transfer...");
- return(FALSE);
-
- case CD: /* change remote directory */
- while(!(*(stpblk(command)))) { /* if no arg, get from user */
- putstring("To: ");
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE); /* abort */
- }
- getword(command,word);
- if(!strcmp(word,"..")) { /* special case */
- i=ftpdo("CDUP",ofilename);
- if(i!=ERROR)
- return(TRUE); /* if CDUP understood */
- nputs("Trying again...");
- i=ftpdo("XCUP",ofilename); /* try alternative */
- if(i!=ERROR)
- return(TRUE);
- nputs("Trying again..."); /* else try usual CD */
- }
- sprintf(line,"CWD %s",word); /* try CWD */
- i=ftpdo(line,ofilename);
- if(i!=ERROR)
- return(TRUE);
- nputs("Trying again...");
- sprintf(line,"XCWD %s",word); /* try XCWD */
- ftpdo(line,ofilename);
- return(TRUE);
-
- case CLOSE: /* drop connection */
- ftpdo("QUIT",ofilename);
- connected=FALSE;
- return(TRUE);
-
- case DEL:
- case RM:
- getword(command,word);
- while(!word[0]) { /* get arg from user */
- putstring("File: ");
- if(ftpgets(word,100,1)==ABORT)
- return(FALSE); /* abort */
- }
- if(prompt) { /* check interactively */
- sprintf(printline,"Delete %s? ",word);
- putstring(printline);
- ftpgets(answer,20,1);
- if(tolower(*(stpblk(answer)))!='y')
- return(TRUE);
- }
- sprintf(line,"DELE %s",word);
- ftpdo(line,ofilename);
- return(TRUE);
-
- case DIR: /* get list of remote files */
- i=ftpfilemode; /* save mode */
- if(i==FIMAGE)
- ftpdo("TYPE A",ofilename);
- if(getword(command,word)) { /* do DIR */
- sprintf(line,"LIST %s",word);
- ftpdo(line,ofilename);
- }
- else
- ftpdo("LIST",ofilename);
- if(i==FIMAGE)
- ftpdo("TYPE I",ofilename);
- return(TRUE);
-
- case GET:
- case RECV: /* get remote file */
- while(!(*(stpblk(command)))) { /* if no arg */
- putstring("File: ");
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE); /* abort */
- }
- sprintf(line,"RETR %s",command);
- ftpdo(line,ofilename);
- return(TRUE);
-
- case LS: /* get remote file list - short */
- i=ftpfilemode;
- if(i==FIMAGE)
- ftpdo("TYPE A",ofilename);
- if(getword(command,word)) {
- sprintf(line,"NLST %s",word);
- ftpdo(line,ofilename);
- }
- else
- ftpdo("NLST",ofilename);
- if(i==FIMAGE)
- ftpdo("TYPE I",ofilename);
- return(TRUE);
-
- case MDELETE:
- while(!(*(stpblk(command)))) { /* no arg */
- putstring("Files: ");
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE); /* abort */
- }
- while(getword(command,word)) { /* for each arg */
- if(glob) { /* wildcard expansion */
- sprintf(line,"NLST %s",word);
- capture=TRUE;
- ftpdo(line,ofilename); /* put exapnsion in captlist */
- capture=FALSE;
- }
- else
- strcpy(captlist,word); /* captlist has name(s) now */
- while(getnname(captlist,word)) { /* for each name */
- if(prompt) { /* check */
- sprintf(printline,"mdelete %s? ",word);
- putstring(printline);
- if(ftpgets(answer,20,1)==ABORT) { /* abort */
- command[0]='\0'; /* no more processing */
- break; /* quit immediately */
- }
- if(tolower(*(stpblk(answer)))!='y')
- continue;
- }
- sprintf(line,"DELE %s",word); /* delete */
- ftpdo(line,ofilename);
- }
- }
- return(TRUE);
-
- case MDIR: /* remote multiple DIR */
- i=ftpfilemode; /* save mode */
- if(i==FIMAGE)
- ftpdo("TYPE A",ofilename);
- while(!(*(stpblk(command)))) { /* no arg */
- putstring("Directories: ");
- if(ftpgets(command,100,1)==ABORT) return(FALSE); /* abort */
- }
- while(getword(command,word)) { /* for each arg */
- if(glob) { /* expand wildcards */
- sprintf(line,"NLST %s",word);
- capture=TRUE;
- ftpdo(line,ofilename);
- capture=FALSE;
- }
- else
- strcpy(captlist,word);
- while(getnname(captlist,word)) { /* for each name */
- if(prompt) { /* check */
- sprintf(printline,"mdir %s? ",word);
- putstring(printline);
- if(ftpgets(answer,20,1)==ABORT) { /* abort */
- command[0]='\0'; /* no more processing */
- break; /* quit immediately */
- }
- if(tolower(*(stpblk(answer)))!='y')
- continue;
- }
- sprintf(line,"LIST %s",word); /* DIR */
- ftpdo(line,ofilename);
- }
- }
- if(i==FIMAGE)
- ftpdo("TYPE I",ofilename);
- return(TRUE);
-
- case MGET: /* get multiple files */
- getword(command,line);
- while(!line[0]) { /* no arg */
- putstring("Files: ");
- if(ftpgets(line,100,1)==ABORT)
- return(FALSE); /* abort */
- }
- while(getword(line,word)) { /* for each arg */
- if(glob) { /* expand wildcards */
- sprintf(command,"NLST %s",word);
- capture=TRUE;
- ftpdo(command,ofilename);
- capture=FALSE;
- }
- else
- strcpy(captlist,word);
- while(getnname(captlist,word)) { /* for each name */
- if(prompt) { /* check */
- sprintf(printline,"mget %s? (Yes/No/All/Quit) ",word);
- putstring(printline);
- if((ftpgets(answer,20,1)==ABORT)||(tolower(*(stpblk(answer)))=='q')) { /* abort */
- command[0]='\0'; /* no more processing */
- break; /* quit immediately */
- }
- if(tolower(*(stpblk(answer)))=='a') { /* All */
- prompt=FALSE;
- tempprompt=TRUE;
- }
- if((tolower(*(stpblk(answer)))!='y')&&(tolower(*(stpblk(answer)))!='a')) continue;
- }
- sprintf(command,"RETR \"%s\"",word);
- ftpdo(command,ofilename);
- }
- if (tempprompt==TRUE) {
- prompt=TRUE;
- tempprompt=FALSE;
- }
- }
- return(TRUE);
-
- case MKDIR: /* create directory */
- while(!(*(stpblk(command)))) { /* no arg */
- putstring("Directory: ");
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE); /* abort */
- }
- sprintf(line,"XMKD %s",command); /* try XMKD */
- i=ftpdo(line,ofilename);
- if(i!=ERROR)
- return(TRUE);
- nputs("Trying again...");
- sprintf(line,"MKD %s",command); /* else try MKD */
- ftpdo(line,ofilename);
- return(TRUE);
-
- case MLS:
- i=ftpfilemode;
- if(i==FIMAGE)
- ftpdo("TYPE A",ofilename);
- while(!(*(stpblk(command)))) { /* no arg */
- putstring("Directories: ");
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE); /* abort */
- }
- while(getword(command,word)) { /* for each arg */
- if(glob) { /* exapnd wildcards */
- sprintf(line,"NLST %s",word);
- capture=TRUE;
- ftpdo(line,ofilename);
- capture=FALSE;
- }
- else
- strcpy(captlist,word);
- while(getnname(captlist,word)) { /* for each name */
- if(prompt) { /* check */
- sprintf(printline,"mls %s? ",word);
- putstring(printline);
- if(ftpgets(answer,20,1)==ABORT) { /* abort */
- command[0]='\0'; /* no more processing */
- break; /* quit immediately */
- }
- if(tolower(*(stpblk(answer)))!='y')
- continue;
- }
- sprintf(line,"NLST %s",word); /* DIR */
- ftpdo(line,ofilename);
- }
- }
- if(i==FIMAGE)
- ftpdo("TYPE I",ofilename);
- return(TRUE);
-
- case MODE: /* set stream mode */
- getword(command,word);
- strlwr(word);
- if(strncmp(word,"stream",strlen(word)))
- nputs("We only support stream mode, sorry.");
- else
- nputs("Mode is stream.");
- return(TRUE);
-
- case MPUT: /* put multiple files */
- getword(command,line);
- while(!line[0]) { /* no arg */
- putstring("Files: ");
- if(ftpgets(line,100,1)==ABORT)
- return(FALSE); /* abort */
- }
- p=NULL; /* no names expanded yet */
- while(getword(line,word)) { /* for each arg */
- do { /* for each name */
- if(glob) { /* local wildcard expansion */
- if(p==NULL) { /* if no expansions yet */
- p=firstname(word,0); /* get first name, with no file information attached */
- if(p==NULL) { /* if no expansions */
- sprintf(printline,"No match for %s",word);
- nputs(printline);
- continue;
- }
- }
- else { /* not first name */
- p=nextname(0); /* get next name, with no file information attached */
- if(p==NULL)
- continue; /* if no names, next arg */
- }
- }
- else
- p=word; /* no expansion */
- if(prompt) { /* check */
- sprintf(printline,"mput %s? (Yes/No/All/Quit) ",p);
- putstring(printline);
- if((ftpgets(answer,20,1)==ABORT)||(tolower(*(stpblk(answer)))=='q')) { /* abort */
- command[0]='\0'; /* no more processing */
- break; /* quit immediately */
- }
- if(tolower(*(stpblk(answer)))=='a') {
- prompt=FALSE;
- tempprompt=TRUE;
- }
- if((tolower(*(stpblk(answer)))!='y')&&(tolower(*(stpblk(answer)))!='a'))
- continue;
- }
- sprintf(command,"STOR \"%s\"",p); /* name may have spl chars */
- ftpdo(command,ofilename);
- } while(glob && p!=NULL); /* Not last expansion */
- if (tempprompt) {
- prompt=TRUE;
- tempprompt=FALSE;
- }
- }
- return(TRUE);
-
- case PUT:
- case SEND: /* put file */
- while(!(*(stpblk(command)))) { /* no args */
- putstring("File: ");
- if(ftpgets(command,100,1)==ABORT) return(FALSE);
- }
- sprintf(line,"STOR %s",command); /* put file */
- for (retry = 0; retry < 5; retry++) {
- if ((i = ftpdo(line,ofilename)) == TRUE)
- return(TRUE);
- else if (i !=FALSE)
- return(ERROR);
- printf("\nRetrying...");
- }
- printf("\nMaximum retry count reached. Aborting file transfer...");
- return(ERROR);
-
- case PWD:
- i=ftpdo("XPWD",ofilename); /* try XPWD */
- if(i!=ERROR)
- return(TRUE);
- nputs("Trying again...");
- ftpdo("PWD",ofilename); /* else try PWD */
- return(TRUE);
-
- case QUOTE:
- while(!(*(stpblk(command)))) { /* no arg */
- putstring("Command: ");
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE);
- }
- ftpdo(command,ofilename); /* send command */
- return(TRUE);
-
- case REMOTEHELP: /* get help */
- if(*(stpblk(command))) { /* for specific command */
- sprintf(line,"HELP %s",command);
- ftpdo(line,ofilename);
- }
- else
- ftpdo("HELP",ofilename); /* generic help */
- return(TRUE);
-
- case RENAME: /* rename remote file */
- while(!(*(stpblk(command)))) { /* no arg */
- putstring("From: ");
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE);
- }
- getword(command,word);
- sprintf(line,"RNFR %s",word);
- ftpdo(line,ofilename); /* send rename from name */
- while(!(*(stpblk(command)))) { /* no second arg */
- putstring("To: ");
- if(ftpgets(command,100,1)==ABORT) {
- ftpdo("ABOR",ofilename);
- return(FALSE);
- }
- }
- sprintf(line,"RNTO %s",command); /* send rename to name */
- ftpdo(line,ofilename);
- return(TRUE);
-
- case RMDIR: /* remove remote dir */
- while(!(*(stpblk(command)))) { /* no arg */
- putstring("Directory: ");
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE);
- }
- sprintf(line,"XRMD %s",command); /* try XRMD */
- i=ftpdo(line,ofilename);
- if(i!=ERROR)
- return(TRUE);
- nputs("Trying again...");
- sprintf(line,"RMD %s",command); /* try RMD */
- ftpdo(line,ofilename);
- return(TRUE);
-
- case STRUCT: /* set structure type - only file */
- getword(command,word);
- strlwr(word);
- if(strncmp(word,"file",strlen(word)))
- nputs("We only support file structure, sorry.");
- else
- nputs("Structure is file.");
- return(TRUE);
-
- case TYPE: /* set transfer type */
- if(!getword(command,word)) { /* no arg, just show */
- if(ftpfilemode==FASCII)
- nputs("Transfer type is ascii.");
- else
- nputs("Transfer type is binary.");
- }
- strlwr(word);
- if(!strncmp(word,"ascii",strlen(word)))
- ftpdo("TYPE A",ofilename);
- else
- if(!strncmp(word,"binary",strlen(word))||!strncmp(word,"image",strlen(word)))
- ftpdo("TYPE I",ofilename);
- else {
- sprintf(printline,"Unrecognized type: %s",word);
- nputs(printline);
- }
- return(TRUE);
-
- case USER: /* login to remote machine */
- if (!fromtty && ttypass)
- fromtty = TRUE; /* go interactive */
- if (f_enter_login) {
- fromtty = 1; /* fake interactive mode */
- n_cur(n_row(), 0); /* in case screen is messed up */
- }
- if(!(*(stpblk(command)))) { /* null response to prompt ok */
- putstring("Username: ");
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE);
- }
- sprintf(line,"USER %s",command); /* username */
- switch(ftpdo(line,ofilename)) {
- case TRUE: return (TRUE);
- case FALSE:
- case ERROR: return(FALSE);
- case ABORT: return(ABORT);
- default: break;
- }
- putstring("Password: ");
- if(ftpgets(word,40,0)==ABORT)
- return(FALSE); /* no echoing */
- if (f_enter_login) /* restore to non-interactive mode */
- fromtty = 0;
- sprintf(line,"PASS %s",word); /* password */
- if(ftpdo(line,ofilename)==INCOMPLETE) { /* if account needed */
- do {
- putstring("Account: ");
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE);
- } while(!(*(stpblk(command))));
- sprintf(line,"ACCT %s",command);
- ftpdo(line,ofilename);
- }
- if (ttypass) fromtty=FALSE; /* back to batch */
- return(TRUE);
-
- case ACCOUNT:
- if (!(*(stpblk(command)))) { /* null response to prompt OK */
- putstring("Account: ");
- if (ftpgets(command,100,0)==ABORT) return(FALSE); /* no echo */
- while (!(*(stpblk(command))));
- sprintf(line,"ACCT %s",command);
- ftpdo(line,ofilename);
- }
- return(TRUE);
-
- case SITE: /* site commands */
- while(!(*(stpblk(command)))) { /* if no arg */
- putstring("Site: ");
- if(ftpgets(command,100,1)==ABORT)
- return(FALSE); /* abort */
- }
- sprintf(line,"SITE %s",command);
- ftpdo(line,ofilename);
- return(TRUE);
-
-
- default: /* unknown command */
- sprintf(printline,"***Program error: Unknown command no: %d",cmdno);
- nputs(printline);
- break;
- }
- }
- }
-
- /************************************************************************/
- /* ftpdo
- * Do whatever command is sent from the user interface using
- * userftpd, the background file handler
- * Returns code from ftpreplies
- /************************************************************************/
-
- static int ftpdo(s,ofile)
- char *s,*ofile;
- {
- int i,rcode;
- char name[50],name2[50];
-
- for(i=0; i<4; i++) {
- s[i]=(char) toupper(s[i]); /* command to upper case */
- }
- if(!strncmp(s,"STOR",4)) { /* put file */
- getword(&s[5],name); /* first arg - local file */
- if(!s[5])
- strcpy(&s[5],name); /* if only one argument */
- else {
- getword(&s[5],name2); /* second arg - removes quotes etc. */
- strcpy(&s[5],name2); /* copy back into command */
- }
- #ifdef MSC
- if(0>(ftpfh=open(name,O_RDONLY | O_BINARY))) { /* open local file */
- #else
- if(0 >(ftpfh=open(name,O_RAW))) { /* open local file */
- #endif
- nputs(" Cannot open file to transfer.");
- return(-1);
- }
- ftpdata=netlisten(ftpport()); /* open data connection */
- ftpstate=20;
- }
- else
- if(!strncmp(s,"RETR",4)) { /* get file */
- getword(&s[5],name); /* remote file */
- if(s[5]) /* two args present */
- getword(&s[5],name2); /* local file */
- else
- check_file_name (name, name2);
- #ifdef MSC
- ftpfh=open(name2,O_BINARY|O_CREAT|O_TRUNC+O_WRONLY,S_IREAD|S_IWRITE);
- #else
- ftpfh=creat(name2,O_RAW); /* open local file */
- #endif
- if(ftpfh<0) {
- sprintf(printline,"Cannot open file to receive: %s",name);
- nputs(printline);
- return(-1);
- }
- strcpy(&s[5],name); /* put remote name back into command */
- ftpdata=netlisten(ftpport()); /* open data connection */
- ftpstate=30;
- }
- else
- if(!strncmp(s,"LIST",4)||!strncmp(s,"NLST",4)) {
- if(capture)
- captlist[0]='\0'; /* where to put incoming data */
- if(debug>4) {
- nputs("ftpdo(): before calling ftpport() ");
- } /* end if */
- ftpdata=netlisten(ftpport()); /* data connection */
- if(debug>4) {
- nputs("ftpdo(): after calling ftpport() ");
- } /* end if */
- ftpstate=40;
- }
- else
- if(!strncmp(s,"TYPE",4)) {
- if(toupper(s[5])=='I')
- ftpfilemode=FIMAGE; /* remember mode */
- else
- if(toupper(s[5])=='A')
- ftpfilemode=FASCII;
- }
-
- dumpcon(ftpnum); /* clear command connection */
- netpush(ftpnum);
- netwrite(ftpnum,s,strlen(s)); /* send command */
- netwrite(ftpnum,"\r\n",2); /* <CRLF> terminates command */
- if(!capture && ofile[0]) { /* command redirected */
- if((ftpstate!=20) &&(ftpstate!=30)) { /* not get or put */
- #ifdef MSC
- if(0>(ftpfh=open(ofile,O_CREAT|O_APPEND|O_WRONLY,S_IWRITE|S_IREAD)))
- #else
- if(0>(ftpfh=open(ofile,O_CREAT|O_APPEND|O_WRONLY,S_IWRITE)))
- #endif
- nputs(" Cannot open output file.");
- else
- if(ftpdata > -1)
- ftpstate=30; /* act as get, since data goes into file */
- else {
- close(ftpfh);
- ftpfh=0;
- }
- }
- }
- if(debug) {
- sprintf(printline,"---> %s",s); /* show command sent */
- nputs(printline);
- if(debug>=7) {
- for(i=0; i < (int)strlen(s); i++)
- sprintf(&printline[4*i],"%3d ",s[i]);
- nputs(printline);
- }
- }
- i=ftpreplies(ftpnum,&rcode); /* get remote response */
- if(debug) {
- nputs("after ftpreplies() call, in ftpdo ");
- } /* end if */
- if((i==NONE) && strncmp(s,"QUIT",4)) { /* unexpected connection drop */
- nputs("lost connection");
- connected=FALSE;
- }
- if(i==ABORT||i==NONE||i==ERROR||i==FALSE) {
- ftpstate=0; /* if error, no transfer */
- if(ftpdata>-1)
- netclose(ftpdata);
- if(ftpfh!=0)
- close(ftpfh);
- ftpdata=-1;
- ftpfh=0;
- }
- return(i);
- }
-
- /************************************************************************/
- /* ftpport
- * return a new port number so that we don't try to re-use ports
- * before the mandatory TCP timeout period. (lifetime of a packet)
- * use a time-based initial port selection scheme.
- /************************************************************************/
-
- long int time(); /* global */
-
- static unsigned int ftpport()
- {
- unsigned int i,rcode;
- unsigned char hostnum[5];
- char sendline[60]; /* for port command */
-
- if(!sendport) /* default port */
- return(HFTP-1);
- if(curftpprt<0x4000) { /* restart cycle */
- i=(unsigned int)time(NULL);
- curftpprt=(unsigned int) (0x4000+(i&0x3fff));
- }
- i=curftpprt--; /* get port, update for next time */
- netgetip(hostnum); /* get my ip number */
- sprintf(sendline,"PORT %d,%d,%d,%d,%d,%d\r\n",hostnum[0],hostnum[1],hostnum[2],hostnum[3],i/256,i&255); /* full port number */
- if(debug>1)
- nputs(sendline);
- netpush(ftpnum); /* empty command connection */
- netwrite(ftpnum,sendline,strlen(sendline)); /* send PORT command */
- if(debug>1) {
- nputs("ftpport(): before dumpcon() call ");
- } /* end if */
- /* check result of command, make sure port was okay */
- /* return 0 on error */ /* ????? */
- dumpcon(ftpnum);
- if(debug>1) {
- nputs("ftpport(): before ftpreplies() call ");
- } /* end if */
- ftpreplies(ftpnum,&rcode); /* get response */
- if(debug>1) {
- sprintf(printline,"ftpport(): after ftpreplies() call, i=%d ",i);
- nputs(printline);
- } /* end if */
- return(i); /* port number */
- }
-
- /************************************************************************/
- /* ftpreplies
- * get responses to commands to server
- * return TRUE on successful completion, FALSE on transient negative
- * completion, INCOMPLETE if more commands needed for operation,
- * NONE on lost connection, ABORT on user abort and ERROR on failure
- *
- /************************************************************************/
-
- static int ftpreplies(cnum,rcode)
- int cnum,*rcode;
- {
- int cnt,ev,j=0;
-
- while(1) {
- if(debug>4) {
- nputs("ftpreplies(): before rgetline() call ");
- } /* end if */
- cnt=rgetline(cnum); /* get line form remote host */
- if(debug>4) {
- sprintf(printline,"s=%s cnt=%d ",s,cnt);
- nputs(printline);
- } /* end if */
- if(cnt==NONE)
- return(NONE); /* lost connection */
- if(cnt==ABORT) { /* user abort */
- netpush(cnum);
- netwrite(cnum,"ABOR\r\n",6); /* send abort */
- return(ABORT);
- }
- if(!sscanf(s,"%d",rcode))
- *rcode=-1; /* continuation line */
- if((*rcode/100)==2) { /* positive completion */
- dumpcon(ftpnum); /* clear command connection */
- while(ftpdata>=0) { /* wait till transfers complete */
- ev=checkevent();
- if(debug>4) {
- sprintf(printline,"ev=%d ",ev);
- nputs(printline);
- } /* end if */
- if(ev==NONE)
- return(NONE); /* lost connection */
- if(ev==ABORT)
- return(ABORT); /* user abort */
-
- if(ev==HAVEDATA)
- dumpcon(ftpnum); /* msg on command connection */
- }
- }
- if(verbose || (*rcode==-1) || (*rcode>500))
- telnet(cnt); /* informative/error msg or display on */
- if(j)
- if(*rcode==j)
- j=0; /* end of continuation */
- else
- continue;
- else
- if(s[3]=='-') { /* line with continuations */
- j=*rcode; /* remember end code */
- continue;
- }
- if(debug>4) {
- sprintf(printline,"*rcode=%d ",*rcode);
- nputs(printline);
- } /* end if */
- switch((int)(*rcode/100)) { /* first digit */
- case 1: /* preliminary */
- continue;
-
- case 2: /* positive completion */
- return(TRUE);
- break;
-
- case 3: /* intermediate */
- return(INCOMPLETE);
- break;
-
- case 4: /* transient negative completion */
- return(FALSE);
- break;
-
- case 5: /* Permanent negative completion */
- return(ERROR);
- break;
-
- default:
- nputs("Server response not understood. Terminating command\n");
- return(ERROR);
- } /* end switch */
- } /* end while */
- }
-
- /************************************************************************/
- /* rgetline - get a line from remote server
- * return ABORT on user ABORT, NONE on lost connection,
- * length of received line on success
- *
- /************************************************************************/
-
- static int rgetline(cnum)
- int cnum;
- {
- int cnt,i=0,ev;
-
- while(1) {
- if(debug>4)
- nputs("rgetline(): before checkevent() ");
- ev=checkevent();
- if(debug>4) {
- printf("\nevent: %d\n",ev);
- nputs("rgetline(): after checkevent() ");
- } /* end if */
-
- switch(ev) {
- case ABORT: /* user abort */
- case NONE: /* lost connection */
- return(ev);
-
- case HAVEDATA:
- if(fromtty && n_scrlck())
- cnt=0; /* if paused, nothing to do */
- else
- while(1) {
- cnt=netread(cnum,&s[i],1); /* get some from queue */
- if(!cnt)
- break; /* nothing available */
- if(s[i++]=='\n') { /* end of line */
- s[i]='\0';
- if(debug>3) {
- sprintf(printline,"rgetline(): s=%s, i=%d ",s,i);
- nputs(printline);
- } /* end if */
- return(i); /* return line length */
- }
- }
- break;
-
- default: /* ignore other events */
- break;
- }
- }
- }
-
- /************************************************************************/
- /* breakstop
- * handle cntrl-break
- /************************************************************************/
-
- static void breakstop()
- {
- #ifdef MSC
- signal(SIGINT,SIG_IGN); /* ignore interrupts while processing this routine */
- #endif
- foundbreak=1;
- #ifdef MSC
- signal(SIGINT,breakstop); /* reset Microsoft interception of break */
- #endif
- }
-
- /************************************************************************/
- /* userftpd
- * FTP receive and send file functions
- /************************************************************************/
-
- static void userftpd(void )
- {
- int i,r1,r2;
- char lastchar;
- double rate;
- static int stopcapture=FALSE; /* bytes xferred % 1024 */
- static long tbytes;
-
- switch(ftpstate) {
- default: /* unknown */
- break;
-
- case 40: /* start LIST */
- if(!netest(ftpdata)) {
- start=time(NULL); /* current time */
- tbytes=0; /* received so far */
- ftpstate=41;
- }
- break;
-
- case 41: /* get started */
- do {
- if(capture && !stopcapture) { /* into captlist */
- fcnt=netread(ftpdata,xs,READSIZE);
- if(fcnt>0) { /* make certain a negative length string is not appended */
- if(strlen(captlist)+fcnt>=2000) { /* full */
- if(!fromtty || !n_scrlck())
- nputs(&xs[2001-strlen(captlist)]); /* display excess chars */
- strncat(captlist,xs,2000-strlen(captlist));
- nputs("Error: capture list too long");
- stopcapture=TRUE;
- }
- else
- strncat(captlist,xs,fcnt); /* append */
- } /* end if */
- if(debug>2) {
- sprintf(printline,"xs %s fcnt %d ",xs,fcnt);
- nputs(printline);
- sprintf(printline,"tbytes %ld strlen(captlist) %d ",tbytes,strlen(captlist));
- nputs(printline);
- }
- }
- else {
- if(fromtty && n_scrlck())
- break; /* paused */
- fcnt=netread(ftpdata,xs,READSIZE);
- for(i=0; i<fcnt; i++) {
- nputchar(xs[i]); /* display */
- if (xs[i] == 10) domore(); /* |more */
- }
- }
- if(fcnt>0)
- tbytes += fcnt; /* how much */
- } while(fcnt>0); /* till no more input */
- if(debug>1) {
- sprintf(printline,"tbytes %ld ",tbytes);
- nputs(printline);
- sprintf(printline,"captlist %s ",captlist);
- nputs(printline);
- }
- break;
-
- case 30: /* receive */
- if(!netest(ftpdata)) { /* connection made */
- start=time(NULL);
- ftpstate=31;
- len=xp=0;
- tbytes=0;
- }
- break;
-
- case 31:
- /*
- * file has already been opened, take everything from the connection
- * and place into the open file: ftpfh
- */
- do { /* wait until xs is full before writing to disk */
- if(len <= 0) {
- if(xp) {
- if ((write(ftpfh,xs,xp) == -1)&&(errno==ENOSPC)) {
- netwrite(ftpdata,"ABOR\r\n",6); /* send abort */
- netwrite(ftpdata,"452 Disk full error.\r\n",22);
- printf("Local disk full error.\n");
- }
- else xp=0;
- }
- len=BUFFERS; /* expected or desired len to go */
- }
- /* how much to read */
- if(len < READSIZE)
- i=len;
- else
- i=READSIZE;
- fcnt=netread(ftpdata,&xs[xp],i);
- if(fcnt>0) { /* adjust counts */
- len -= fcnt;
- xp += fcnt;
- tbytes += fcnt;
- }
- if(debug>1) {
- sprintf(printline,"len %d xp %d fcnt %d",len,xp,fcnt);
- nputs(printline);
- }
- if(fcnt<0) { /* connection closed */
- write(ftpfh,xs,xp); /* write last block */
- if(ftpfilemode==FASCII)
- write(ftpfh,"\032",1); /* EOF char */
- close(ftpfh);
- ftpfh=0;
- }
- if(hash) { /* hash mark printing */
- for(i=(int)(((tbytes-(long)fcnt)%1024L+(long)fcnt)/1024L); i; i--)
- nputchar('#');
- }
- } while(fcnt>0);
- break;
-
- case 20: /* send */
- if(!netest(ftpdata)) { /* connection made */
- start=time(NULL);
- ftpstate=21;
- lengthfile=lseek(ftpfh,0L,SEEK_END); /* how long is file? */
- lseek(ftpfh, -1L,SEEK_CUR); /* position at last character*/
- if (read(ftpfh, &lastchar, 1)==0) {
- if (debug>4) printf("LC Test failed.\n");
- lastchar='\0';
- }
- else {
- if (debug>4) printf("Last character test returned %d.\n",(int) lastchar);
- };
- lseek(ftpfh,0L,SEEK_SET); /* back to beginning */
- if ((ftpfilemode==FASCII)&&(lastchar=='\26')) /* drop cntr-Z for ascii transfer */
- lengthfile--; /* leave off ctrl-Z */
- towrite=0;
- xp=0;
- tbytes=0;
- }
- break;
-
- case 21:
- /*
- * transfer file(s) to the other host via ftp request
- * file is already open=ftpfh
- */
- if (debug > 4) printf("lengthfile=%d towrite=%d xp=%d i=%d\n",lengthfile,towrite,xp,i);
-
- if(towrite<=xp) { /* need to read again */
- if (debug > 4) printf("towrite<=xp\n");
- if(lengthfile <(long)BUFFERS)
- i=(int)lengthfile;
- else
- i=BUFFERS;
- if (debug > 4) printf("i=%d\n",i);
- towrite=read(ftpfh,xs,i);
- if (debug > 4) printf("towrite=%d\n",towrite);
- xp=0;
- }
- if (towrite>=xp)
- i=netwrite(ftpdata,&xs[xp],towrite-xp);
- else
- i=netwrite(ftpdata,&xs[xp],0);
- if(i>0) { /* send successful, adjust counts */
- xp+=i;
- lengthfile -=i;
- tbytes+=i;
- }
- if(debug>1) {
- sprintf(printline,"i %d xp %d towrite %d",i,xp,towrite);
- nputs(printline);
- }
- if(hash) { /* hash printing */
- for(r1=(int)(((tbytes-(long)i)%1024L+(long)i)/1024L); r1; r1--)
- nputchar('#');
- }
- /*
- * done if: the file is all read from disk and all sent
- * or other side has ruined connection
- */
- if((lengthfile<=0L&&xp>=towrite)||netest(ftpdata))
- ftpstate=22;
- break;
-
- case 22: /* send done */
- /* wait for other side to accept everything and then close */
- if(0>=(r1=netpush(ftpdata)))
- fcnt=-1;
- if(debug>1) {
- sprintf(printline,"fcnt %d r1 %d\n",fcnt,r1);
- nputs(printline);
- if (kbhit()) { netclose(ftpdata); exit(0);};
- };
- break;
-
- } /* end of switch */
- /*
- * after reading from connection, if the connection is closed,
- * reset up shop.
- */
- if(fcnt<0) { /* connection lost */
- if(ftpfh>0) { /* close file */
- close(ftpfh);
- ftpfh=0;
- }
- ftpstate=0; /* done */
- fcnt=0;
- i=(int)(time(NULL)-start); /* how long to transfer */
- if(!i)
- rate=((double) tbytes) / 1024.0;
- else
- rate=((double) tbytes) /(i * 1024.0);
- r1=(int) rate; /* integer part of rate */
- r2=(int)((rate -(double) r1) * 1000);
- sprintf(printline,"Transferred %ld bytes in %d seconds(%d.%03d Kbytes/sec)",tbytes,i,r1,r2);
- if(hash)
- nputs("");
- if(verbose)
- nputs(printline);
- netclose(ftpdata); /* close connection */
- ftpdata=-1;
- if(bell)
- nputchar(7);
- }
- }
-
- /************************************************************************/
- /* 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
- /************************************************************************/
-
- static int getword(string,word)
- char *string,*word;
- {
- char *p,*q;
- int i=0;
-
- if(debug>4) {
- sprintf(printline,"getword: string is %s",string);
- nputs(printline);
- }
- p=stpblk(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\r\n"); /* get word, max len 50 */
- p=stpblk(q); /* remove trailing blanks */
- strcpy(string,p); /* remove extracted stuff */
- return(TRUE);
- }
-
- /************************************************************************/
- /* flip_slashes: change \ to / */
- /************************************************************************/
- static void flip_slashes(command,filename)
- char *command;
- char *filename;
- {
- register int i; /* local counting variable */
-
- filename[0]='\0'; /* don't do anything with the filename */
- for(i=0; !command[i]; i++) { /* loop over entire string */
- if(command[i]=='\\') /* found a \ ? */
- command[i]='/'; /* flip the \ to a / */
- }
- } /* end flip_slashes() */
-
- /************************************************************************/
- /* checkoredir: check for output redirection. If the command contains a
- * >, assume a filename follows and extract it. Remove the redirection
- * from the original command.
- * Also change \ to /
- * return TRUE if redirection specified, FALSE otherwise
- /************************************************************************/
-
- static int 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);
- }
-
- /************************************************************************/
- /* getdir: get current directory. Finds current drive and current path
- * on drive, returns a string.
- *
- /************************************************************************/
-
- static void getdir(drive,path)
- int drive;
- char *path;
- {
- #ifdef MSC
- getcwd(path,100);
- drive=drive; /* To get rid of annoying "Unreferenced formal parameter" warning. */
- #else
- char partpath[64];
- if(!drive) drive=getdsk(); /* current disk */
- getcd(drive+1,partpath); /* current dir */
- sprintf(path,"%c:\\%s",'A'+drive,partpath);
- #endif
- }
-
- /************************************************************************/
- /* 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.
- *
- /************************************************************************/
-
- static int finduniq(name,list,listsize)
- char *name, *list[];
- int listsize;
- {
- int i,j=NONE,len;
- len=strlen(name);
- for(i=0; i<listsize; i++) {
- if(!strncmp(name,list[i],len)) { /* prefix */
- if(len==(int)strlen(list[i]))
- return(i+1); /* exact match */
- if(j!=NONE)
- j=AMBIGUOUS; /* more than one match */
- else
- j=i+1; /* note prefix found */
- }
- }
- return(j); /* prefix */
- }
-
- /************************************************************************/
- /* checkevent
- * get and process network events
- * returns ABORT on user abort, HAVEDATA if data available on command
- * connection, NONE if connection lost, DOMOK if domain search succeeds,
- * DOMFAIL if domain search fails, TRUE if no relevant event.
- /************************************************************************/
-
- static int checkevent(void)
- {
- int ev,class=0,data;
-
- kbhit(); /* check for cntrl-break */
- if(foundbreak) return(ABORT);
- userftpd(); /* do ftp stuff */
- Stask(); /* keep connections alive */
- ev=Sgetevent(CONCLASS|ERRCLASS|USERCLASS, &class,&data);
- if(class==CONCLASS) {
- if(data==ftpnum) { /* command connection */
- if(ev==CONCLOSE) { /* connection lost */
- netclose(ftpnum);
- if(!netest(ftpdata))
- netclose(ftpdata); /* close data connection */
- connected=FALSE;
- return(NONE);
- }
- if(ev==CONDATA)
- return(HAVEDATA); /* data received */
- }
- }
- else
- if(class==USERCLASS) {
- if(ev==DOMOK) { /* domain search succeeded */
- ftpnum=data;
- return(DOMOK);
- }
- else
- if(ev==DOMFAIL)
- return(DOMFAIL); /* domain search failed */
- }
-
- /* else if(class==ERRCLASS&&ev==ERR1) nputs(neterrstring(data)); */
- return(TRUE);
- }
-
- /************************************************************************/
- /* putstring: display string using vt100 emulation routines
- /************************************************************************/
-
- static int putstring(string)
- char *string;
- {
- for(; *string; string++) nputchar(*string);
- return(TRUE);
- }
-
- /************************************************************************/
- /* printerr: display TCP error messages - disabled
- /************************************************************************/
-
- static int printerr(void )
- {
- /* int data,class; while(ERR1==Sgetevent(ERRCLASS,&class,&data))nputs(neterrstring(data));*/
- return(TRUE);
- }
-
- /************************************************************************/
- /* getnname: get next name from captured list
- * names delimited by newlines - <CR> or <LF>
- /************************************************************************/
-
- static int getnname(string,word)
- char *string,*word;
- {
- char *s;
-
- s=string;
- while((*string=='\n')||(*string=='\r'))
- string++; /* skip initial newlines */
- if(!(*string))
- return(FALSE); /* end of captlist */
- while((*string!='\n') &&(*string!='\r') &&(*string)) *(word++)=*(string++);
- while((*string=='\n')||(*string=='\r'))
- string++; /* skip trailing newline */
- *word='\0';
- strcpy(s,string);
- return(TRUE);
- }
-
- /***************************************************************************/
- /* dosescape
- * escape to dos for processing
- * put the connections to automated sleep while in DOS
- /************************************************************************/
-
- void dosescape(void)
- {
- int i;
- char *command_shell;
-
- nputs("Warning, some programs will interfere with network communication and can");
- nputs("cause lost connections. Do not run any network programs from this DOS shell.");
- nputs("Type 'EXIT' to return to FTP");
- /*
- * invoke a put-to-sleep routine which calls netsleep every 8/18ths of a sec
- */
- tinst();
- command_shell=getenv("COMSPEC");
- if (command_shell !=NULL)
- i=system(command_shell); /* call DOS */
- else
- i= -1;
- tdeinst();
-
- if(i<0) {
- nputs("\n\nError loading COMMAND.COM");
- nputs("Make sure COMMAND.COM is specified under COMSPEC.");
- nputs("It must also be in a directory which is in your PATH statement.");
- }
- if(fromtty)
- n_row();
- }
-
-
- static void nputs(line)
- char *line;
- {
- if(!scrsetup) {
- scrsetup = 1;
- if(fromtty) { /* don't do anything now */
- if (!display_init) {
- Sgetconfig(&def); /* get information provided in hosts file */
- display_init=TRUE;
- dos_color=n_color((int) def.color[0]); /* set color to that set in config file */
- };
- n_color((int) def.color[0]); /* set color to that set in config file */
- n_clear(); /* clear screen */
- n_wrap(1); /* cursor positioning */
- n_cur(0,0);
- }
- puts("National Center for Supercomputing Applications");
- puts(" FTP version 2.3.03 7/23/91");
- #ifdef FINAL_RELEASE
- puts("Copyright Board of Trustees University of Illinois");
- #endif
- }
-
- if(*line)
- puts(line);
- else
- puts("");
- }
-
- static void nputchar(ch)
- char ch;
- {
- if(fromtty & ttypass)
- putc(ch,stderr);
- else
- putchar(ch);
- }
- /*
- unsigned char convtable []={
- '{', 0x84,
- '|',0x94,
- '}',0x86,
- '[',0x8e,
- '\\',0x99,
- ']',0x8f,
- 0,0
- };
-
- n_chkchar()
- {
- int x;
- unsigned char *i=convtable;
-
- x=x_chkchar();
- for( ; *i!=0; i+=2)
- if(x==(int)*(i+1))
- x=(int) *i;
- return( x);
- }
- */
-
- #ifdef MSC
-
- static char *stptok( p, toword, len, delim)
-
- char *p;
- char *toword;
- int len;
- char *delim;
-
- {
- char *adv=toword;
- int i;
- int end=0;
-
- do {
- for(i=0; i< (int) strlen(delim); i++)
- if(*p==delim[i]||(!*p))
- end++;
- if(! end) {
- if(adv>=(toword+len-1))
- end++;
- *adv++=*p++;
- }
- } while(! end);
- *adv='\0';
- return( p);
- }
-
- static char *stpblk( ch)
- char *ch;
-
- {
- while(*ch==' '||*ch=='\t') ch++;
- return( ch);
- }
- #endif
-
- int numrows() /* detect number of rows */
- {
- int rows=24; /* default number of rows */
-
- #ifdef INT_FIXED
- union REGS regs;
-
- regs.x.ax = 0x1130; /* get font information (includes # of rows) */
- int86(0x10,®s,®s);
- rows = regs.h.dl; /* number of rows */
- #endif
-
- return (rows);
- }
-
- int domore(void)
- {
- int ch = 0;
-
- if (usemore) {
- if (lineslft-- <=1) {
- printf("-- more --");
- ch=0;
- while (!ch) {
- if (!kbhit()) /* if no char available */
- Stask(); /* keep the connection alive */
- else
- ch = getch(); /* else get a character */
- if (foundbreak) {
- foundbreak=0;
- ch=32;
- }
- }
- printf("\r \r");
- if (ch == 13)
- lineslft++;
- else lineslft=numlines;
- }
- }
- return(ch);
- }
-
- /************************************************************************/
- /* check_file_name */
- /* */
- /* A function to check for and enforce MS-DOS file name compatibility */
- /* and uniqueness. All non-MS-DOS filename characters from 'in_fname' */
- /* are deleted. If the filename exists in the current directory, a */
- /* unique name is created to avoid file name collision. */
- /* 'out_fname' must be large enough for the full filename (13 bytes). */
- /* */
- /* Returns: pointer to 'out_fname' */
- /* */
- /* Allen W. Todd Dec 24, 1990 */
- /* */
- /************************************************************************/
-
- char *check_file_name (char *in_fname,
- char *out_fname)
-
- {
- char buf[80];
- char *s;
- char *fname;
- char *fextn;
- char num_buf[20];
- long count = 0L;
-
- strcpy (buf, in_fname); /* make local copy */
- strlwr (buf); /* convert to lower case */
- while ((s = strpbrk (buf, "\"*+,/:;<=>?[\]^|")) != NULL)
- strcpy (s, s+1); /* delete non-DOS chars */
- fname = &buf[0]; /* separate filename from file extension */
- if ((fextn = strchr (buf, '.')) != NULL)
- *fextn++ = '\0';
- if (strlen (fname) > 8) *(fname+8) = '\0'; /* fix filename @ 8 char */
- if (strlen (fextn) > 3) *(fextn+3) = '\0'; /* fix file extension @ 3 char */
- strcpy (out_fname, fname); /* build complete filename */
- if (fextn)
- {
- strcat (out_fname, ".");
- strcat (out_fname, fextn);
- }
- while (access (out_fname, 0) == 0) /* if file already exists */
- {
- ltoa (count++, num_buf, 10);
- strcpy (out_fname, fname); /* build complete filename */
- if ( (strlen (fextn) < 3) && (strlen (num_buf) + strlen (fextn) <= 3) )
- strcat (fextn, num_buf);
- else
- {
- if (strlen(fname) > strlen(num_buf))
- strcpy (out_fname+(strlen(fname)-strlen(num_buf)), num_buf);
- else
- strcat (out_fname, num_buf);
- }
- if (fextn)
- {
- strcat (out_fname, ".");
- strcat (out_fname, fextn);
- }
- }
- return (out_fname);
- }
-
-