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


/* 
 * tinyftp.c - user ftp built on tinytcp.c 
 * 
 * Written March 31, 1986 by Geoffrey Cooper 
 * 
 * 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                               | 
|===================================================================| 
 
940213	rr	minor mods 
940403	rr	some bug fixes. receive side working. 
940424	rr	start working on the server side 
940513	rr	more coding on server side - may work, who knows 
940529	rr	simplifications and cleanup 
940925	rr	shorten some names 
941012	rr	split into 2 parts 
 
Notes: 
	940424: This is the CLIENT side of the FTP connection. Currently it 
	is only capable of requesting that files be RETRieved. It cannot 
	retrieve more than one file. The file logic needs beefing up. (rr) 
 
	940424: Names in this program often appear to have been chosen 
	quite poorly - that is, they either are unintelligible, or don't 
	reflect the true meaning of what they represent. I have been changing 
	them slowly, but consider this to be a low priority. (rr) 
 
	940424: There is something funny about the kbhit stuff. It seems to 
	sometimes wait for a key even if I haven't pressed one. (rr) 
	There is also something wrong with receiving long multi-line responses 
	such as to HELP, like the data gets overwritten or unterminated. 
 
	940513: file should be opened when socket opens. 
 
	940513: Need some work on the interactive client; it doesn't work. 
	The server is coming along nicely. 
 
	940529: Do we need to do a new listen after a file is received? 
*/ 
 
/* #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 */ 
 
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. */ 
 
char		b_response[ 120 ];	/* response buffer */ 
int		i_response;		/* index into response buf */ 
 
	/* Client output command buffer */ 
 
char		b_c_command[ 82 ];	/* send buffer */ 
 
	/* Server output buffer */ 
 
char		b_s_response[ 128 ] = ""; 
					/* server output buffer */ 
 
	/* Server file transfer buffer, index, and length */ 
 
Byte		b_s_data[ 1024 ];	/* server output buffer */ 
int		n_s_sent,	/* bytes sent of buffer */ 
			n_s_left;	/* bytes left in serv2 buffer */ 
 
	/* file handle for retrieve */ 
 
char		recv_filename[ 82 ]; 
FH		p_recv_file = ( FH ) 0; 
 
	/* file handle for server */ 
 
char		send_filename[ 82 ]; 
FH		p_send_file = ( FH ) 0; 
 
/* ----- prototypes ------------------------------------------------- */ 
 
static Void ftp_process_response P(( Void )); 
 
/* ----- ftp control handler ---------------------------------------- */ 
 
Void ftp_ctlHandler( s, dp, len ) 
	struct tcp_Socket *	s; 
	Byte *			dp; 
	int			len; 
{ 
	S8	Byte		c, 
				*bp, 
				data[ 82 ]; 
	S8	int		i; 
 
#ifdef DEBUG_FTP 
	printf( "in ftp_ctlHandler %08lx %08lx %d\n", s, dp, len ); 
		/* 22904a58 22900a14 0 */ 
#endif 
 
	/* 940403 comes in here with 2 pointers and 65 - a string. */ 
 
	if( dp == 0 ) { 
		tcp_Abort( &s_og_data ); 
		return; 
	} 
 
	/* Received a message. What do I do with it? */ 
 
	do { 
		i = len; 
		if( i > sizeof( data )) i = sizeof( data ); 
		Move( dp, data, i ); 
		len -= i; 
 
		/* Look at the buffer that was received and try to 
			interpret it as an FTP response */ 
 
		bp = data; 
		while( i-- > 0 ) { 
			c = *bp++; 
 
			if( c == '\r' ) continue;	/* ignore the cr? */ 
 
			if( c == '\n' ) { 
				/* We've received the end of the response. */ 
 
				b_response[ i_response ] = '\0'; 
 
				/* Process the message received. */ 
 
				ftp_process_response(); 
				i_response = 0; 
 
			} else if( i_response < 
				( sizeof( b_response ) - 1 )) { 
 
				/* Not the end yet, keep storing. */ 
 
				b_response[ i_response++ ] = c; 
			} 
		} 
 
	} while( len > 0 ); 
} 
 
/* ----- ftp data handler ------------------------------------------- */ 
 
Void ftp_dataHandler( s, dp, len ) 
	struct tcp_Socket *	s; 
	Byte *			dp; 
	int			len; 
{ 
#ifdef DEBUG_FTP 
	printf( "in ftp_dataHandler %08lx %08lx %d\n", s, dp, len ); 
#endif 
	/* When a file is retr'd, it comes in here. */ 
 
	if( len <= 0 ) {	/* 0 = EOF, -1 = close */ 
		if( p_recv_file != ( FH ) 0 ) { 
			my_close( p_recv_file ); 
			p_recv_file = ( FH ) 0; 
		} 
		return; 
	} 
 
	/* if the file isn't open yet, try to open it */ 
 
	if(( p_recv_file == ( FH ) 0 ) 
		&& ( strlen( recv_filename ))) { 
 
		/* open the file for retrieve */ 
 
		p_recv_file = my_open( recv_filename, MY_OPEN_WRITE );  
 
		if( p_recv_file == ( FH ) 0 ) { 
			printf( "** Can't open file %s **", 
				recv_filename ); 
			recv_filename[ 0 ] = '\0'; 
		} 
	} 
 
	/* write the data to the file */ 
 
	if( p_recv_file != ( FH ) 0 ) { 
		my_write( p_recv_file, dp, len ); 
		dp += len; 
		return; 
	} 
 
	/* as a last resort, dump it to the screen (Hm, to stdout?) */ 
 
	while( len > 0 ) { 
		if(( *dp < 32 ) || ( *dp > 126 )) 
			printf( " %02x ", *dp ); 
		else	putchar( *dp ); 
		++dp; 
		--len; 
	} 
} 
 
/* ----- process response from distant end ftp ---------------------- */ 
 
static Void ftp_process_response( Void ) { 
	printf( "< %s\n", b_response ); 
 
	/* Look at the fourth byte of the response message. 
		If there is a -, there is more to come. 
		If there is a blank, this is the end. */ 
} 
 
/* end of tinyftp.c */