TFTPD.C
上传用户:sunrenlu
上传日期:2022-06-13
资源大小:1419k
文件大小:4k
- /*
- * eRTOS TFTP Server
- * Copyright (c) 2000 Erick Engelke
- */
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <memory.h>
- #include <rtos.h>
- #include <net.h>
- #include <tftp.h>
- #define TFTP_PORT 69
- #define TFTP_BUF_LEN 1024
- #define MAXPATHLEN 81
- int _tftpd_readonly = 0;
- //---------------------------------------------------------------------
- // getblock - returns received length
- static int getblock( char *filename, int blocknum, void *buffer )
- {
- FILE *f;
- int result = 0;
- dos_enter();
- f = fopen( filename, "rb");
- if ( f != NULL ) {
- if ( 0 == fseek( f, (blocknum - 1) * 512, SEEK_SET ))
- result = fread( buffer, 1, 512, f );
- fclose( f );
- }
- dos_exit();
- return( result );
- }
- // putblock - returns 0 on success
- static int putblock( char *filename, int blocknum, void *buffer, int length )
- {
- FILE *f;
- int result = 0;
- dos_enter();
- f = fopen( filename, "a+b");
- if ( f != NULL ) {
- if ( 0 == fseek( f, (blocknum - 1) * 512, SEEK_SET ))
- fwrite( buffer, 1, length, f );
- else result = 3; // disk full or alloc exceeded
- fclose( f );
- } else result = 3;
- dos_exit();
- return( result ? 3 : 0 );
- }
- #pragma argsused
- void tftpdthread( DWORD remotehost )
- {
- char *buf;
- unsigned buflen;
- int socklistening;
- static udp_Socket sock;
- DATA_Packet *d;
- ACK_Packet *a;
- RRQ_Packet *r;
- ERROR_Packet *e;
- char filename[ MAXPATHLEN ];
- int block;
- *filename = 0;
- if ( ( buf = kcalloc( TFTP_BUF_LEN, 1 )) == NULL )
- rt_halt( "TFTPD insufficient memory");
- d = a = r = e = buf;
- socklistening = 0;
- do {
- if ( socklistening == 0 ) {
- /* udp_open - use remote_IP=0, bind to first incoming IP address */
- /* if remotehost = 0 listen to anyone */
- /* otherwise directed listen */
- if (!udp_open( &sock, TFTP_PORT, remotehost, -1, NULL ))
- rt_halt("unable to open TFTP server socket");
- socklistening = 1;
- }
- rt_sleep( 10 );
- tcp_tick( NULL );
- /* look for input */
- if ( (buflen = sock_dataready( &sock )) == 0 ) {
- continue; /* no input */
- }
- /* we received an TFTP request, process it */
- buflen = sock_fastread( &sock, buf, buflen );
- /* remote GET */
- if ( d->op2 == TFTP_RRQ ) {
- memset( filename, 0, MAXPATHLEN );
- strncpy( filename, r->filename, MAXPATHLEN - 1 );
- d->op2 = TFTP_DATA;
- block = 1;
- buflen = sizeof( ACK_Packet ) + getblock( filename, block, d->data );
- d->block = intel16( block );
- }
- else if ( d->op2 == TFTP_ACK ) {
- d->op2 = TFTP_DATA;
- block = intel16( d->block ) + 1;
- buflen = sizeof( ACK_Packet ) + getblock( filename, block, d->data );
- d->block = intel16( block );
- }
- /* remote PUT */
- else if ( d->op2 == TFTP_WRQ ) {
- memset( filename, 0, MAXPATHLEN );
- strncpy( filename, r->filename, MAXPATHLEN - 1 );
- unlink( filename ); // reset existing file
- d->op2 = TFTP_ACK;
- d->block = intel16( 0 );
- buflen = sizeof( ACK_Packet );
- }
- else if ( d->op2 == TFTP_DATA ) {
- if ( _tftpd_readonly != 0 ) {
- e->op2 = TFTP_ERROR;
- e->err1 = 0;
- e->err2 = 3;
- e->errmsg[0] = 0;
- buflen = sizeof( ERROR_Packet );
- } else {
- block = intel16( d->block );
- if ( putblock( filename, block, d->data, buflen - sizeof( ACK_Packet )) != 0 ) {
- e->op2 = TFTP_ERROR;
- e->err1 = 0;
- e->err2 = 3;
- e->errmsg[0] = 0;
- buflen = sizeof( ERROR_Packet );
- } else {
- d->op2 = TFTP_ACK;
- buflen = sizeof( ACK_Packet );
- // d->block = intel16( block ) ; // redundant
- }
- }
- }
- sock_fastwrite( &sock, buf, buflen );
- sock_close( &sock );
- /* open next tftpd server */
- socklistening = 0;
- } while( 1 );
- }