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

📄 tinyftp.c

📁 ADAM2 sources (modified by Oleg)
💻 C
📖 第 1 页 / 共 3 页
字号:
/*-----------------------------------------------------------------------------*//*																			   */	/* 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."								   *//*-----------------------------------------------------------------------------*/#include "_stdio.h"#include "env.h"#include "tinyip.h"#include "support.h"#include "flashop.h"#include "srloader.h"#include "shell.h"#include "revision.h"tcp_Socket ftp_ctl, ftp_data;static byte ftp_cmdbuf[128];static int ftp_cmdbufi;static byte ftp_outbuf[ftp_MaxData];static int ftp_outbufix, ftp_outbuflen;#ifdef FTP_SERVER_SUPPORT#define USERNAME_LEN		16#define REC_GET_TAG		0#define REC_GET_LEN		1#define REC_GET_ADDR		2#define REC_GET_DATA		3#define REC_GET_CHECKSUM	4#define REC_GET_ABORT		5#define REC_GET_DONE		6#define CFG_MAGIC_NUMBER	0x434D4D4C /* CMML */// by Oleg can be 0x0300 #define CFG_VERSION_NUMBER	0x0200int ftpServerStatus = STATUS_NONE;int rebootFlag = FALSE;static char buffer[ftp_MaxData];static longword ftpRemoteHost;static longword ftpRemotePort;static int dlen;static bit32 flashAddress;static bit32u flashOffset;static bit32 endAddress;static bit32u ramAddress;static bit32u recState, recLen, recAddr, recChecksum;static short ftpMedia;static short ftpType;static FTPCommand commandList[] = {	{TOK_ABOR, 	"ABOR",  FALSE},/*Abort transfer: ABOR.*//*	{TOK_BYE,  	"BYE",   FALSE}, Logout or break connection: BYE.*/	{TOK_QUIT, 	"QUIT",  FALSE},/*Logout or break connection: QUIT.*/ 	{TOK_PORT, 	"PORT",  TRUE}, /*Specify the client port number: PORT a0,a1,a2,a3,a4,a5.*/	{TOK_USER,	"USER",  TRUE},	/*Supply a username: USER username.*/ 	{TOK_PASS, 	"PASS",  TRUE},	/*Supply a user password: PASS password.*//* #if 0 */	{TOK_HELP, 	"HELP",  FALSE},/*Show help: HELP*//* #endif *//*	{TOK_SYST, 	"SYST",  FALSE}, Get operating system type: SYST.*/	{TOK_PASV, 	"PASV",  FALSE},/*Set server in passive mode: PASV.*//*	{TOK_PASW, 	"P@SW",  FALSE}, Set server in passive mode: P@SV.*/#if 0		{TOK_NLST, 	"NLST",  FALSE},/*List filenames only: NLST.*/ 	{TOK_LIST, 	"LIST",  FALSE},/*Get directory listing: LIST.*/#endif	{TOK_STOR, 	"STOR",  TRUE},	/*Store file: STOR file-name.*/ 	{TOK_TYPE, 	"TYPE",  TRUE},	/*Set filetype: TYPE [A | I].*/	{TOK_RETR,	"RETR",	 TRUE},	/*Get file: RETR file-name.*/	{TOK_MEDIA,	"MEDIA", TRUE},	/*Set storage media - Flash/SDRAM: MEDIA [FLSH | SDRM].*/	{TOK_GETENV,	"GETENV",TRUE},	/*Retreive the value for an env variable: GET env-name.*/	{TOK_SETENV,	"SETENV",TRUE},	/*Set an env value-variable pair: SET env-name,value.*/	{TOK_UNSETENV,"UNSETENV",TRUE},	/*Unset an env value-variable pair: UNSET env-name.*/	{TOK_FIXENV,	"FIXENV",FALSE},/*rebuild env: FIXENV.*/	{TOK_PRINTENV,"PRINTENV",FALSE},/*print env variables: PRINTENV.*/	{TOK_REBOOT,	"REBOOT",FALSE},/*Reboot the server: REBOOT.*/	{TOK_ERROR,	"", 	 FALSE},};void FlushICache(void);int RetrConfigSpace(tcp_Socket *s);int RetrMtdSpace(tcp_Socket *s);void FTPSend (tcp_Socket *s, char *data, int len){	char *sr;	char *dp;				sr = data;   	dp = (char *)ftp_outbuf;	if (len == 0) len = strlen(data);	if (len > ftp_MaxData) len = ftp_MaxData;		sys_memcpy(dp, data, len);	ftp_outbuflen = len;   	ftp_outbufix = 0;	if ( len > 0 ) 	{		len = tcp_Write(s, &ftp_outbuf[ftp_outbufix], len);		ftp_outbufix += len;		tcp_Flush(s);	}}int flashStore (byte *dp, int len){	if ((dlen == 0) && (dp))	{		if (FWBValid((bit32u)flashAddress) == 0) {			return FALSE;		}		if (FWBOpen((bit32u)flashAddress) == 0) {			return FALSE;		}				/* The code assumes that every time you want to start writing to the flash you want		 * to start at the beginning of the block.  Since the env var and cfgman data are 		 * sharing the same block, this is no longer true.  Therefore, we include this		 * hack here to adjust the offset on the first write */		flashAddress+=flashOffset;		sys_printf("WriteToFlash\n");	}	if ((flashAddress + len) > endAddress) return FALSE;	if ((dp) && (len))	{		WriteToFlash((UINT8 *)flashAddress, (UINT8 *)dp, len);		dlen += len;		flashAddress += len;	}		return TRUE;}int ramStore (byte *dp, int len){ bit32u recTag, newChecksum; static UINT32 TotalBytes = 0; while (len) {  switch (recState)  {   case REC_GET_TAG:	if (getf32((bit32u)dp, &recTag, FALSE) == 4) {		if (recTag != TAG_WANTED) {			recState = REC_GET_ABORT;			sys_printf("Error: File for wrong endian.\n");		}		else	recState = REC_GET_LEN;	}	ramAddress = 0;	len -= 4;	dp += 4;	sys_printf("\n");	break;   case REC_GET_LEN:	if (getf32((bit32u)dp, &recLen, FALSE) == 4) {		recChecksum = recLen;		recState = REC_GET_ADDR;	}	len -= 4;	dp += 4;	break;   case REC_GET_ADDR:	if (getf32((bit32u)dp, &recAddr, FALSE) == 4) {		if (recLen == 0) {			ramAddress = recAddr;			recState = REC_GET_DONE;		}		else {			recChecksum += recAddr;				recState = REC_GET_DATA;		}	}	len -= 4;	dp += 4;	break;   case REC_GET_DATA:	while ((recLen != 0) && (len != 0))	{		recChecksum += ((bit32u)*dp)&0x0ff;	   	*(char *)recAddr++ = *dp++;		recLen--;		len--;		if ((TotalBytes++ % INDICATE_WRITE) == 0) sys_printf(".");	}	if (recLen == 0) recState = REC_GET_CHECKSUM;	break;   case REC_GET_CHECKSUM:	if (getf32((bit32u)dp, &newChecksum, FALSE) == 4) {		recChecksum += newChecksum;		if (recChecksum != 0) {			sys_printf("Error: Bad Checksum.\n");			recState = REC_GET_ABORT;		}		else recState = REC_GET_LEN;	}	dp += 4;	len -= 4;	break;   case REC_GET_ABORT:				   case REC_GET_DONE:	len = 0;	break;				  } } if (recState == REC_GET_ABORT) return FALSE; return TRUE;}void FTPDataHandler (tcp_Socket *s, byte *dp, int len, int state){ int ret = FALSE; switch (state) {  case SOPEN:	dlen = 0;	flashOffset=0;	recState = REC_GET_TAG;	recChecksum = 0;				recLen = recAddr = 0;	break;	  case SDATA:	if (ftpServerStatus == STATUS_DOWNLOAD)	{		if (s->dataSize == 0)	   	{// by Oleg			if ((RetrConfigSpace(&ftp_data) == FALSE)&&(RetrMtdSpace(&ftp_data) == FALSE))			{				dlen = 0;				flashOffset=0;				tcp_Close(&ftp_data);				FTPSend(&ftp_ctl, "226 complete.\r\n", 0);				ftpServerStatus = STATUS_IDLE;			}		}		break;	}	else if (ftpServerStatus != STATUS_UPLOAD) break;		if (ftpMedia == MEDIA_FLASH) {//		sys_printf("\nflashStore 0x%x to 0x%x offset 0x%x length %d\n", flashAddress, endAddress, flashOffset, len); // by Oleg for debug		ret = flashStore(dp, len);	}	else if (ftpMedia == MEDIA_SDRAM) {						ret = ramStore(dp, len);	}		if (ret == FALSE)	{		sys_printf("ERROR: Store to media failed\n");		tcp_Close(&ftp_data);		FTPSend(&ftp_ctl, "426 Connection close; transfer aborted.\r\n", 0);		ftpServerStatus = STATUS_IDLE;					}	break;	  case SCLOSE:  case SABORT:	if (ftpServerStatus != STATUS_UPLOAD) break;	if (dlen && (ftpMedia == MEDIA_FLASH))	{		if (!FWBClose())      			sys_printf("ERROR: Could not close flash block, dlen = %d\n", dlen);	}				dlen = 0;	flashOffset=0;	tcp_Close(&ftp_data);	FTPSend(&ftp_ctl, "226 Transfer complete.\r\n", 0);	ftpServerStatus = STATUS_IDLE;	sys_printf("\n");	if ((ftpMedia == MEDIA_SDRAM) && (ramAddress != 0)) {		FlushICache();		sys_printf("\nExecuting the RAM image at 0x%x.\n", ramAddress);		if (executeProgram(0, ramAddress, 0, NULL) == 0)			FTPSend(&ftp_ctl, "200 Execution successful.\r\n", 0);		else			FTPSend(&ftp_ctl, "214 Execution failed.\r\n", 0);		ramAddress = 0;	}	break;			 }}int ftpCheckState (void){ if (ftp_data.state != tcp_StateESTAB) return 0; if ((ftpServerStatus != STATUS_PASSIVE) && (ftpServerStatus != STATUS_ACTIVE))  return 0; return 1;}int RetrEnvSpace(tcp_Socket *s){	int i;	char *cp,*cp2;	for(i=0;i<256;i++)	{		cp=sys_getienv(i);		if (cp)		{			cp2=sys_getenv(cp);			if (!cp2) cp2 = "";			sys_sprintf(buffer, "%-20s  %s\r\n", cp, cp2);			FTPSend(s, buffer, 0);		}	}	return TRUE;}int RetrMtdSpace(tcp_Socket *s){	int len = (ftp_MaxData - 1);	static bit32u size = 0x0;	static bit32 configAddress = 0x0;	if (dlen == 0)	{			 sys_printf("RetrMtdSpace: 0x%x; 0x%x\r\n", flashAddress, endAddress);	 configAddress = flashAddress;	 configAddress &= 0x1fffffff;	 configAddress |= 0xa0000000; // by Oleg 0xB-------	 size = endAddress-flashAddress;	}	if ((configAddress == 0x0) || (size == 0x0)) return FALSE;	if (size < len) len = size;	sys_memset(buffer, 0, ftp_MaxData);	sys_memcpy(buffer, (void *) configAddress, len);	FTPSend(s, buffer, len);	configAddress += len; // by Oleg : this is static variable=> preserve state	dlen += len;	size -= len; // by Oleg : this is static variable=> preserve state	return TRUE;}int RetrConfigSpace(tcp_Socket *s){	char *cp;	bit32u magicNumber, versionNumber;	char cfgman_mtd_name[FLASH_ENV_ENTRY_SIZE];	int len = (ftp_MaxData - 1);	static bit32u size = 0x0;	static bit32 configAddress = 0x0;		if (dlen == 0)	{				/* calculate the address for the config block */		sys_sprintf(cfgman_mtd_name,"mtd%d", CFGMAN_MTD);		cp = sys_getenv(cfgman_mtd_name);		if ((cp == NULL) || (myatox(cp,&configAddress) == 0))			return FALSE;		configAddress &= 0x1fffffff;		configAddress |= 0xa0000000;		/* adjust for the offset */		configAddress += CFGMAN_MTD_OFFSET;		/* Get magic number, version and size, but leave configAddress as it is. */		if ((getf32((bit32u)configAddress, &magicNumber, FALSE) != 4) || 				(magicNumber != CFG_MAGIC_NUMBER))			return FALSE;		configAddress += 4;				// by Oleg remove if ((getf32((bit32u)configAddress, &versionNumber, FALSE) != 4) || (versionNumber != CFG_VERSION_NUMBER)) return FALSE;		configAddress += 4;			if ((getf32((bit32u)configAddress, &size, FALSE) != 4) || (size >= 0xFFFF))			return FALSE;/* by Oleg		configAddress += 8; Leaving size and crc; No need to read the crc */		configAddress -= 8; // by Oleg to read config with headrer, to be able "put config.xml"		size +=8;	}	if ((configAddress == 0x0) || (size == 0x0)) return FALSE;	if (size < len) len = size;	sys_memset(buffer, 0, ftp_MaxData);	sys_memcpy(buffer, (void *)configAddress, len);	FTPSend(s, buffer, len);	configAddress += len; // by Oleg : this is static variable=> preserve state	dlen += len;	size -= len; // by Oleg : this is static variable=> preserve state	return TRUE;}void FTPCommandLine(tcp_Socket *s){	char *cmdstr, *argstr;	int ncmd, i, port;	char *cp, *start, *end;	char *strArr[10];	static char username[USERNAME_LEN];		char ipaddr[USERNAME_LEN];		cmdstr = (char *)ftp_cmdbuf;	argstr = strtok(cmdstr, ' ');	for (ncmd = TOK_ABOR; ncmd < TOK_ERROR; ncmd++) {		if (strcmp(cmdstr, commandList[ncmd].commandName) == 0) {			if ((commandList[ncmd].argFlag == TRUE) && (argstr == NULL)) {				FTPSend(s, "501 Invalid number of parameters.\r\n", 0);				return;			}			break;		}	}		if ((ncmd != TOK_USER && ncmd != TOK_PASS) && (ftpServerStatus == STATUS_LOGIN))	{		FTPSend(s, "530 Please login with USER and PASS.\r\n", 0);		sys_memset(username, 0, USERNAME_LEN);		return;	}	switch(ncmd) {		case TOK_ABOR:			if (ftpServerStatus != STATUS_IDLE)				FTPSend(s, "426 Data connection closed.\r\n", 0);			FTPSend(s, "226 ABOR command successful.\r\n", 0);			if (ftp_data.state != tcp_StateCLOSED)    			tcp_Abort(&ftp_data);			break;			//		case TOK_BYE:		case TOK_QUIT:

⌨️ 快捷键说明

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