📄 tftpc.c
字号:
/*************************************************************************
*
* Copyright (c) 1993 - 2001 Accelerated Technology, Inc.
*
* PROPRIETARY RIGHTS of Accelerated Technology are involved in the
* subject matter of this material. All manufacturing, reproduction,
* use, and sales rights pertaining to this subject matter are governed
* by the license agreement. The recipient of this software implicitly
* accepts the terms of the license.
*
*************************************************************************/
/*************************************************************************
*
* FILE NAME VERSION
*
* tftpc.c 4.4
*
* COMPONENT
*
* Net - TFTP Client
*
* DESCRIPTION
*
* This file contains the TFTP routines necessary to get and to put
* a file to a TFTP server.
*
* DATA STRUCTURES
*
* None
*
* FUNCTIONS
*
* TFTPC_Get Get a file from a TFTP server.
* TFTPC_Put Put a file to a TFTP server.
* TFTPC_Request Send a request to a TFTP server.
* TFTPC_Recv Recv a packet.
* TFTPC_Process_Data Process a data packet.
* TFTPC_Ack Send a TFTP ack.
* TFTPC_Process_Ack Process an ack packet.
* TFTPC_Send_Data Send a TFTP data packet.
* TFTPC_Retransmit Retransmit the last TFTP packet.
* TFTPC_Error Send a TFTP error packet.
* TFTPC_Check_Options Evaluate server acknowledged options
* TFTPC_Set_Options Set options to be sent to the server.
*
* DEPENDENCIES
*
* nucleus.h
* target.h
* externs.h
* sockdefs.h
* tftpextc.h
* tftpdefs.h
* ncl.h
* fal.h
*
*************************************************************************/
#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/externs.h"
#include "net/inc/sockdefs.h"
#include "net/inc/socketd.h"
#include "net/inc/tftpdefc.h"
#include "net/inc/tftpextc.h"
#include "net/inc/ncl.h"
#include "fal/inc/fal.h"
extern NU_MEMORY_POOL System_Memory;
/* TFTP defines 9 error codes, with values 0 through 8. In the event that one
* of these errors is received it will be passed back to the application. Since
* a value of 0 is defined to be NU_SUCCESS in the Nucleus PLUS OS it is
* necessary to redefine the first error code, and since the convention at ATI
* is to return negative numbers for error codes all were redefined below.
*
* VALUE ERROR
* -100 Not defined, see error message (if any)
* -101 File not found
* -102 Access violation
* -103 Disk full or allocation execeeded
* -104 Illegal TFTP operation
* -105 Unknown transfer ID
* -106 File already exists
* -107 No such user
* -108 Illegal Option Negotiation
*/
INT16 tftp_errors[] = {-100, -101, -102, -103, -104, -105, -106, -107, -108};
/*************************************************************************
*
* FUNCTION
*
* TFTPC_Get
*
* DESCRIPTION
*
* This function is called from a user application. It retrieves a
* file from a TFTP server - compatible with RFC 2347 compliant and
* non-compliant servers.
*
* INPUTS
*
* *remote_ip Pointer to the target ip address.
* *rpath The remote file to get.
* *lpath Local name to give the file.
* *ops Pointer to options the user requests of the server.
*
* OUTPUTS
*
* The number of bytes received when succesful. Else various error
* codes are returned.
*
*************************************************************************/
INT32 TFTPC_Get(UINT8 *remote_ip, CHAR *rpath, CHAR *lpath, TFTP_OPTIONS *ops)
{
TFTP_CB *tftp_con;
STATUS status;
INT16 retransmits;
INT32 total_bytes, bytes_received;
UINT32 file_size = 0;
FAL_FILE file_desc;
/* Open the file and get the length for the tsize option */
if ((file_desc = FAL_Open(lpath, PO_RDWR|PO_CREAT|PO_TRUNC|PO_BINARY, FAL_IWRITE)) < 0)
return (FAL_Get_Last_Error());
/* Check that the requested options are valid */
TFTPC_Set_Options(file_size, ops);
/* We will need at least BUFFER_SIZE_MIN bytes to transmit a request
* packet, so if the requested blksize is less than BUFFER_SIZE_MIN,
* we still need to allocate BUFFER_SIZE_MIN bytes in memory for the
* transmission buffer
*/
if (ops->blksize < TFTP_BUFFER_SIZE_MIN)
{
/* Allocate memory for the TFTP Control Block & transmission buffer */
status = NU_Allocate_Memory (&System_Memory, (VOID **)&tftp_con,
sizeof(TFTP_CB) + TFTP_BUFFER_SIZE_MIN + TFTP_HEADER_SIZE, NU_SUSPEND);
}
/* Otherwise, the blksize is large enough to transmit a request packet */
else
{
/* Allocate memory for the TFTP Control Block & transmission buffer */
status = NU_Allocate_Memory (&System_Memory, (VOID **)&tftp_con,
(UNSIGNED)(sizeof(TFTP_CB) + ops->blksize + TFTP_HEADER_SIZE),
NU_SUSPEND);
}
/* If we cannot allocate the necessary memory for the control block and
* transmission buffer, return with an error
*/
if (status != NU_SUCCESS)
{
FAL_Fclose(tftp_con->file_desc, 0);
return(TFTP_NO_MEMORY);
}
/* Set the options that will be requested of the server - the tsize is
* sent as 0, and the server will return the size of the request file
*/
tftp_con->options.timeout = ops->timeout;
tftp_con->options.blksize = ops->blksize;
tftp_con->options.tsize = 0;
/* Setup the file descriptor, path and READ_TYPE */
tftp_con->file_desc = file_desc;
tftp_con->file_name = rpath;
tftp_con->type = READ_TYPE;
/* Setup a pointer to the transmission buffer */
tftp_con->trans_buf = (CHAR *)((UINT32)tftp_con + sizeof(TFTP_CB));
/* Send a TFTP Read Request to a server */
if ((status = TFTPC_Request(remote_ip, rpath, tftp_con)) <= 0)
{
FAL_Fclose(tftp_con->file_desc, 0);
NU_Deallocate_Memory((VOID *) tftp_con);
return(status);
}
/* Initialize retransmits. */
retransmits = 0;
/* Get the server's response - should be an OACK if the server is
* RFC 2347 compliant, an ACK otherwise
*/
while(((bytes_received = TFTPC_Recv(tftp_con)) == NU_NO_DATA) &&
(retransmits < TFTP_NUM_RETRANS))
{
TFTPC_Retransmit(tftp_con, (INT32)status);
retransmits++;
}
/* If we received a response, then set up the server's TID.
* Else return an error.
*/
if (bytes_received)
tftp_con->tid = tftp_con->server_addr.port;
else
{
FAL_Fclose(tftp_con->file_desc, 0);
NU_Close_Socket(tftp_con->socket_number);
NU_Deallocate_Memory((VOID *) tftp_con);
return(TFTP_CON_FAILURE);
}
/* If we did not receive an OACK, the server is not RFC 2347 compliant;
* therefore, we must set our values to conform to RFC 1350 and start
* on block 1
*/
if(GET16(tftp_con->trans_buf, 0) != TFTP_OACK_OPCODE)
{
tftp_con->options.blksize = TFTP_BLOCK_SIZE_DEFAULT;
tftp_con->options.timeout = TFTP_TIMEOUT_DEFAULT;
tftp_con->block_number++;
}
/* Process the first data packet that was received from the server. */
if((status = TFTPC_Process_Data(tftp_con, bytes_received)) < 0)
{
FAL_Fclose(tftp_con->file_desc, 0);
NU_Close_Socket(tftp_con->socket_number);
NU_Deallocate_Memory((VOID *) tftp_con);
return(status);
}
/* Get the rest of the file and process it */
while (tftp_con->status == TRANSFERRING_FILE)
{
/* Initialize retransmits. */
retransmits = 0;
/* Retrieve the next data packet. */
while(((bytes_received = TFTPC_Recv(tftp_con)) == NU_NO_DATA) &&
(retransmits < TFTP_NUM_RETRANS))
{
TFTPC_Retransmit(tftp_con, TFTP_ACK_SIZE);
retransmits++;
}
/* If a data packet was received, then process it. Else a problem
* occured, and we need to exit.
*/
if (bytes_received)
{
if((status = TFTPC_Process_Data(tftp_con, bytes_received)) !=
NU_SUCCESS)
tftp_con->status = TFTP_CON_FAILURE;
}
/* We will exit the loop and return status */
else
{
tftp_con->status = TFTP_CON_FAILURE;
status = TFTP_CON_FAILURE;
}
} /* While transferring file */
/* If everything went okay then calculate the number of bytes that were
* received in this file. Else we should return the last error code that
* was received.
*/
if(status == NU_SUCCESS)
total_bytes = FAL_Handle_File_Length(file_desc);
else
total_bytes = status;
/* Close the file */
FAL_Fclose(tftp_con->file_desc, 0);
/* Close the socket, freeing any resources that were used. */
NU_Close_Socket(tftp_con->socket_number);
/* Deallocate the memory used for the TFTP control block. */
NU_Deallocate_Memory((VOID *) tftp_con);
return(total_bytes);
} /* end TFTPC_Get */
/*************************************************************************
*
* FUNCTION
*
* TFTPC_Put
*
* DESCRIPTION
*
* This function is called from a user application. It puts a file
* to a TFTP server.
*
* INPUTS
*
* *remote_ip Pointer to the target ip address.
* *rpath What the file will be called on the remote host.
* *lpath The local file to be transferred.
* *ops Pointer to options the client requests of the
* server.
*
* OUTPUTS
*
* The number of bytes put to the server when succesful. Else
* various error conditions are returned.
*
*************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -