⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tftpsrv.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
字号:
/*   tftpsrv.c

  Copyright 1998 by InterNiche Technologies Inc. All rights reserved.
  Copyright 1995 by NetPort Software.
  Copyright 1986 by Carnegie Mellon
  Copyright 1984 by the Massachusetts Institute of Technology

   TFTP server code - uses common code in tftputil.c and udp
interface in tftpudp.c
*/

#include "tftpport.h"

#ifdef TFTP_SERVER

#include "tftp.h"

void * tftpsconn = NULL;   /* server UDPCONN or socket */

static int (*tfs_alert)(ip_addr,char*,unshort);   /* security callback */
static int (*tfs_done)(int status, struct tfconn *, char*);   /* transfer complete callback */


extern int ntftps;
int tftp_server_on = FALSE;
u_long refusedt = 0;      /*  time of most recent transfer refusal  */

/* tfsinit(alert, done) - initialize the tftp server. This opens a UDP
   connection but does not turn on the server. That needs to done by
   an explicit call to tfs_on().

   alert() is a function which the server will call whenever it receives
   request for a transfer. This function will be called int he following
   way:
      alert(ip_addr, file_name, direction)

   alert() should return TRUE if it wishes to allow the transfer and
   FALSE otherwise.  

   done() is a function that the server will
   call to   inform the invoker that this file transfer is complete or
   aborted.
*/

int
tfsinit(
   int (*alert)(ip_addr, char*, unshort),    /* notification callback */
   int (*done)(int, struct tfconn *, char*)) /* transfer complete callback */
{
unshort lport = TFTPPORT;  /* for pass to tftp_udplisten() */

   /* open server tftp connection to receive incoming requests
   with wildcard foriegn host & wildcard foriegn port */
   tftpsconn = tftp_udplisten(0L, 0, &lport, TFTPSERVER);

   if(!tftpsconn)
      return ENP_RESOURCE;

   tfs_done = done;
   tfs_alert = alert;

   return 0;
}

/* turn the tftp server on
*/

void
tfs_on() 
{
   tftp_server_on = TRUE;
}

/* turn the tftp server off
*/

void
tfs_off() 
{
   tftp_server_on = FALSE;
}

/* tfshnd() - handle an initial incoming tftp packet. 

   This involves opening a udp connection (immediately so that we can
report errors). If the server is OFF then the tftp will be refused;
otherwise more checking will be done.  Call the alert function and
verify that the "user" wishes to allow the tftp. Report an error if
not. Finally, spawn a session to oversee the tftp and cleanup when
it's done.  

Returns 0 if OK, else ENP error code.
*/

int
tfshnd(ip_addr host, unshort fport, char * udata)
{
struct tfreq *ptreq;
char *file, *smode, *tmp;
struct tfconn *cn = NULL;
unsigned mode;
int e = 0;  /* error value to return */

   /* Do we have room to do this transfer?  */
   if(ntftps >= MAXTFTPS) 
   {
      dprintf("TFTP Serve:  Ignoring req, too many connections\n");
      return ENP_RESOURCE;
   }

   ptreq = (struct tfreq *)udata;
   ptreq->tf_op = htons(ptreq->tf_op);
   if(ptreq->tf_op > TF_WRQ) 
   {
      dprintf("TFTP Server: bad init opcode %u\n", ptreq->tf_op);
      return ENP_LOGIC;
   }
   file = (char*)&ptreq->tf_name[0];

   smode = file + strlen(file)+1;

   for(tmp = smode; *tmp; tmp++)
      if(*tmp >= 'A' && *tmp <= 'Z') *tmp += 32;


   cn = tfmkcn();    /* make conn now in case we send errors */
   if(cn == 0) 
   {
      dprintf("TFTP Server: session Alloc failed\n");
      return ENP_RESOURCE;
   }
   cn->tf_start = cticks;
   cn->tf_fhost = host;
   cn->tf_fport = fport;
   cn->tf_lport = TFTPPORT;   /* errors come from std port for now */

   if(strcmp(smode, "image") == 0) mode = OCTET;
   else if(strcmp(smode, "octet") == 0) mode = OCTET;
   else if(strcmp(smode, "netascii") == 0) mode = ASCII;
   else 
   {
      dprintf("TFTP Server:  Bad mode %s in req\n", smode);
      tfsnderr(cn, ERRTXT, "Bad mode");
      tfcleanup(cn);
      return ENP_LOGIC;
   }

   if(tftp_server_on != TRUE) 
   {
      dprintf("TFTP Server: got req while off\n");
      tfsnderr(cn, ERRTXT, "Transfers currently disabled.");
      tfcleanup(cn);
      return 0;   /* this is not an error */
   }

   if(tfs_alert)
   {
   int code;
      code = (*tfs_alert)(host, file, 
               (unshort)(ptreq->tf_op == TF_RRQ ? PUT : GET)  );

      if(code == 0)
      {
         tfsnderr(cn, ERRTXT, "Transfer refused.");
         refusedt = cticks;
         tfcleanup(cn);
         return 0;
      }
   }

   cn->tf_lport = 0;    /* let UDP select local port */

   /* open a UDP connection for data transfer with this host */
   cn->tf_conn = tftp_udplisten(host, fport, &cn->tf_lport, (void*)cn);
   if(cn->tf_conn == NULL) 
   {
      dprintf("TFTP Server: UDP listen error\n");
      tfcleanup(cn);
      return ENP_RESOURCE;
   }

   cn->tf_mode = mode;
   if(ptreq->tf_op == TF_RRQ) 
   {
      cn->tf_dir = PUT;
      if(cn->tf_mode == ASCII)   /* let file sys handle netascii */
         cn->tf_fd = vfopen(file, "r");
      else
         cn->tf_fd = vfopen(file, "rb");

      if(cn->tf_fd == NULL) 
      {
         dprintf("TFTP server: couldn't open file\n");
         tfsnderr(cn, FNOTFOUND, " ");
         (*tfs_done)(TFC_FILEOPEN, cn, file);
         tfcleanup(cn);
         return ENP_FILEIO;
      }
      cn->tf_state = RCVACK;  /* consider request to first ack */
      cn->tf_expected = 1;    /* start with block number 1 */
      cn->callback = tfs_done;
      cn->tf_flen = NORMLEN;
   }
   else  /* get request */
   {
      cn->tf_dir = GET;
      if(cn->tf_mode == ASCII)   /* let file sys handle netascii */
         cn->tf_fd = vfopen(file, "w");
      else
         cn->tf_fd = vfopen(file, "wb");

      if(cn->tf_fd == NULL) 
      {
         dprintf("TFTP Server: couldn't open file\n");
         tfsnderr(cn, ACCESS, " ");
         (*tfs_done)(TFC_FILEOPEN, cn, file);
         tfcleanup(cn);
         return ENP_FILEIO;
      }
      cn->tf_expected = 0;    /* ack block number 0 */
      e = tfsndack(cn);
      cn->tf_expected = 1;    /* start with block number 1 */
      cn->tf_state = DATAWAIT;
      cn->callback = tfs_done;
   }
   return e;   /* OK return */
}

#endif /* TFTP_SERVER */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -