www.pudn.com > tcpipstack.rar > TINYFT3.C


/* TINYFT3.C - Part 3 of tiny FTP. 
 
 * Copyright (C) 1986, IMAGEN Corporation 
 * "This code may be duplicated in whole or in part provided that [1] there 
 * is no commercial gain involved in the duplication, and [2] that this 
 * copyright notice is preserved on all copies. Any other duplication 
 * requires written notice of the author." 
 
|===================================================================| 
|  The author of this code hereby licenses all duplication and/or   | 
|  modification of this code, in whole or in part, consistent with  | 
|  the terms of the GNU Library General Public License.             | 
|              - Geoffrey H. Cooper 10/29/97                        | 
|===================================================================| 
 
|===================================================================| 
|  My changes can be considered public domain.  Geof's statement    | 
|  will cover everything.                                           | 
|              - Rick Rodman 09/02/97                               | 
|===================================================================| 
 
	941012	rr	split into 3 parts 
*/ 
 
/* #define DEBUG_FTP */ 
 
#define	RECEIVE_DATA_PORT	0x8080 
 
	/* This is working now. */ 
/* #define	IMMEDIATE_OPEN */ 
 
#include "tinytcp.h" 
#include "fileio.h" 
 
#include 	/* for printf, etc */ 
 
#include 	/* for kbhit, etc. Amazingly, Hitech C has these 
				entry points too! */ 
 
#include 	/* for strcpy, etc. */ 
 
	/* the following are what these seem to be */ 
 
#define	isina		kbhit 
#define	busyina		getch 
#define busyouta	putch 
 
	/* Sockets */ 
 
extern	struct tcp_Socket s_og_ctl,	/* outgoing connection socket */ 
			s_og_data,	/* data socket */ 
			s_ic_ctl,	/* server control socket */ 
			s_ic_data;	/* server data socket */ 
 
	/* Receive buffer for client side. */ 
 
extern	char		b_response[ 120 ];	/* response buffer */ 
extern	int		i_response;		/* index into response buf */ 
 
	/* Client output command buffer */ 
 
extern	char		b_c_command[ 82 ];	/* send buffer */ 
 
	/* Server output buffer */ 
 
extern	char		b_s_response[ 128 ]; 
					/* server output buffer */ 
 
	/* Server file transfer buffer, index, and length */ 
 
extern	Byte		b_s_data[ 1024 ];	/* server output buffer */ 
extern	int		n_s_sent,	/* bytes sent of buffer */ 
			n_s_left;	/* bytes left in serv2 buffer */ 
 
	/* file handle for retrieve */ 
 
extern	char		recv_filename[ 82 ]; 
extern	FH		p_recv_file; 
 
	/* file handle for server */ 
 
extern	char		send_filename[ 82 ]; 
extern	FH		p_send_file; 
 
/* ----- prototypes ------------------------------------------------- */ 
 
extern void exit P(( int )); 
 
/* ----- abort ftp -------------------------------------------------- */ 
 
Void ftp_Abort( Void ) { 
	tcp_Abort( &s_og_ctl ); 
	tcp_Abort( &s_og_data ); 
} 
 
/* ----- FTP application - called by TCP when there's nothing to do -- */ 
 
Void ftp_application( Void ) { 
	S8	int		i, n; 
	static	char		userbuffer[ 84 ] = ""; 
 
	fflush( stdout );	/* make sure prompt, etc. is visible */ 
 
	/* Check the console for a keypress */ 
 
	if( isina() ) { 
		i = busyina() & 0177; 
 
		/* Actually, control-C will be captured by the OS and 
			terminate everything. Use control-X. */ 
 
		if(( i == ( 'C' & 037 )) || ( i == ( 'X' & 037 ))) { 
			printf( "Closing...\n" ); 
			tcp_Close( &s_og_ctl ); 
		} 
 
		/* have a user character */ 
 
		if(( i >= ' ' ) && ( i <= 126 )) { 
			n = strlen( userbuffer ); 
			if( n < 81 ) { 
				userbuffer[ n++ ] = ( char ) i; 
				userbuffer[ n ] = '\0'; 
			} 
			busyouta( i );		/* echo the char */ 
		} else if( i == '\b' ) { 
			n = strlen( userbuffer ); 
			if( n > 0 ) { 
				userbuffer[ --n ] = '\0'; 
				printf( "\b \b" ); 
			} 
		} else if( i == '\022' ) {	/* control-R */ 
			printf( "\r\nftp> %s", userbuffer ); 
		} else if( i == '\r' ) { 
 
			/* Carriage return */ 
 
			if( strlen( userbuffer )) { 
 
				strcat( userbuffer, "\r\n" ); 
 
				/* If it's an internal command, process it 
					locally; else concatenate it to the 
					output buffer */ 
 
				if( userbuffer[ 0 ] == '@' ) 
					ftp_local_command( userbuffer ); 
 
				else { 
					/* See if it is a RETR command */ 
 
					if(( strncmp( userbuffer, "RETR ", 5 ) == 0 ) 
						|| ( strncmp( userbuffer, 
							"retr ", 5 ) == 0 )) 
						strcpy( recv_filename, 
							&userbuffer[ 5 ] ); 
 
					strcat( b_c_command, userbuffer ); 
				} 
				userbuffer[ 0 ] = '\0'; 
			} 
			printf( "\r\nftp> " ); 
		} 
	} 
 
	/* send any data on the control port which is waiting to be sent */ 
 
	i = strlen( b_c_command ); 
	if( i ) { 
		i = tcp_Write( &s_og_ctl, 
			( Byte * ) b_c_command, 
			i ); 
 
		/* move down the data which remains to be sent */ 
 
		if( i ) strcpy( &b_c_command[ 0 ], &b_c_command[ i ] ); 
 
		tcp_Flush( &s_og_ctl ); 
	} 
 
	/* Look at the SERVER buffer and send anything that's there */ 
 
	i = strlen( b_s_response ); 
	if( i ) { 
		i = tcp_Write( &s_ic_ctl, 
			( Byte * ) b_s_response, 
			i ); 
 
		/* move down the data which remains to be sent */ 
 
		strcpy( &b_s_response[ 0 ], &b_s_response[ i ] ); 
 
		tcp_Flush( &s_ic_ctl ); 
	} 
 
	/* If the server (or the client?) is sending a file, send the file */ 
 
	if( p_send_file != ( FH ) 0 ) { 
 
		/* if buffer is empty, read some more data */ 
 
		if( n_s_left == 0 ) { 
			n_s_left = ( int ) my_read( p_send_file, 
				&b_s_data[ 0 ], 
				sizeof( b_s_data )); 
			if( n_s_left == 0 ) {		/* EOF! */ 
				my_close( p_send_file ); 
				p_send_file = ( FH ) 0; 
 
				printf( "Closing...\n" ); 
 
				tcp_Close( &s_ic_data ); 
 
				strcat( b_s_response, "226 File sent.\r\n" ); 
 
				goto done_serv2; 
 			} 
			n_s_sent = 0; 
		} 
 
		/* send as much as will fit */ 
   
		i = tcp_Write( &s_ic_data, 
			&b_s_data[ n_s_sent ], 
			n_s_left ); 
 
		/* if buffer is empty, read some more data */ 
 
		n_s_sent += i; 
		n_s_left -= i; 
 
		tcp_Flush( &s_ic_data ); 
	} 
done_serv2: ; 
} 
 
/* end of tinyft3.c */