TFTPD.C
上传用户:sunrenlu
上传日期:2022-06-13
资源大小:1419k
文件大小:4k
源码类别:

操作系统开发

开发平台:

DOS

  1. /*
  2.  * eRTOS TFTP Server
  3.  * Copyright (c) 2000 Erick Engelke
  4.  */
  5. #include <stdio.h>
  6. #include <ctype.h>
  7. #include <string.h>
  8. #include <memory.h>
  9. #include <rtos.h>
  10. #include <net.h>
  11. #include <tftp.h>
  12. #define TFTP_PORT 69
  13. #define TFTP_BUF_LEN 1024
  14. #define MAXPATHLEN 81
  15. int _tftpd_readonly = 0;
  16. //---------------------------------------------------------------------
  17. // getblock - returns received length
  18. static int getblock( char *filename, int blocknum, void *buffer )
  19. {
  20.     FILE *f;
  21.     int result = 0;
  22.     dos_enter();
  23.     f = fopen( filename, "rb");
  24.     if ( f != NULL ) {
  25.         if ( 0 == fseek( f, (blocknum - 1) * 512, SEEK_SET ))
  26.             result = fread( buffer, 1, 512, f );
  27.         fclose( f );
  28.     }
  29.     dos_exit();
  30.     return( result );
  31. }
  32. // putblock - returns 0 on success
  33. static int putblock( char *filename, int blocknum, void *buffer, int length )
  34. {
  35.     FILE *f;
  36.     int result = 0;
  37.     dos_enter();
  38.     f = fopen( filename, "a+b");
  39.     if ( f != NULL ) {
  40.         if ( 0 == fseek( f, (blocknum - 1) * 512, SEEK_SET ))
  41.             fwrite( buffer, 1, length, f );
  42.         else result = 3;    // disk full or alloc exceeded
  43.         fclose( f );
  44.     } else result = 3;
  45.     dos_exit();
  46.     return( result ? 3 : 0 );
  47. }
  48. #pragma argsused
  49. void tftpdthread( DWORD remotehost )
  50. {
  51.     char *buf;
  52.     unsigned buflen;
  53.     int socklistening;
  54.     static udp_Socket sock;
  55.     DATA_Packet *d;
  56.     ACK_Packet *a;
  57.     RRQ_Packet *r;
  58.     ERROR_Packet *e;
  59.     char filename[ MAXPATHLEN ];
  60.     int block;
  61.     *filename = 0;
  62.     if ( ( buf = kcalloc( TFTP_BUF_LEN, 1 )) == NULL )
  63.         rt_halt( "TFTPD insufficient memory");
  64.     d = a = r = e = buf;
  65.     socklistening = 0;
  66.     do {
  67.         if ( socklistening == 0 ) {
  68.             /* udp_open - use remote_IP=0, bind to first incoming IP address */
  69.             /* if remotehost = 0  listen to anyone */
  70.             /* otherwise directed listen */
  71.             if (!udp_open( &sock, TFTP_PORT, remotehost, -1, NULL ))
  72.                 rt_halt("unable to open TFTP server socket");
  73.             socklistening = 1;
  74.         }
  75.         rt_sleep( 10 );
  76.         tcp_tick( NULL );
  77.         /* look for input */
  78.         if ( (buflen = sock_dataready( &sock )) == 0 ) {
  79.             continue;   /* no input */
  80.         }
  81.         /* we received an TFTP request, process it */
  82.         buflen = sock_fastread( &sock, buf, buflen );
  83.         /* remote GET */
  84.         if ( d->op2 == TFTP_RRQ ) {
  85.             memset( filename, 0, MAXPATHLEN );
  86.             strncpy( filename, r->filename, MAXPATHLEN - 1 );
  87.             d->op2 = TFTP_DATA;
  88.             block = 1;
  89.             buflen = sizeof( ACK_Packet ) + getblock( filename, block, d->data );
  90.             d->block = intel16( block );
  91.         }
  92.         else if ( d->op2 == TFTP_ACK ) {
  93.             d->op2 = TFTP_DATA;
  94.             block = intel16( d->block ) + 1;
  95.             buflen = sizeof( ACK_Packet ) + getblock( filename, block, d->data );
  96.             d->block = intel16( block );
  97.         }
  98.         /* remote PUT */
  99.         else if ( d->op2 == TFTP_WRQ ) {
  100.             memset( filename, 0, MAXPATHLEN );
  101.             strncpy( filename, r->filename, MAXPATHLEN - 1 );
  102.             unlink( filename );     // reset existing file
  103.             d->op2 = TFTP_ACK;
  104.             d->block = intel16( 0 );
  105.             buflen = sizeof( ACK_Packet );
  106.         }
  107.         else if ( d->op2 == TFTP_DATA ) {
  108.             if ( _tftpd_readonly != 0 ) {
  109.                e->op2 = TFTP_ERROR;
  110.                e->err1 = 0;
  111.                e->err2 = 3;
  112.                e->errmsg[0] = 0;
  113.                buflen = sizeof( ERROR_Packet );
  114.             } else {
  115.                 block = intel16( d->block );
  116.                 if ( putblock( filename, block, d->data, buflen - sizeof( ACK_Packet )) != 0 ) {
  117.                     e->op2 = TFTP_ERROR;
  118.                     e->err1 = 0;
  119.                     e->err2 = 3;
  120.                     e->errmsg[0] = 0;
  121.                     buflen = sizeof( ERROR_Packet );
  122.                 } else {
  123.                     d->op2 = TFTP_ACK;
  124.                     buflen = sizeof( ACK_Packet );
  125.                     // d->block = intel16( block ) ; // redundant
  126.                 }
  127.             }
  128.         }
  129.         sock_fastwrite( &sock, buf, buflen );
  130.         sock_close( &sock );
  131.         /* open next tftpd server */
  132.         socklistening = 0;
  133.     } while( 1 );
  134. }