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 */