📄 tinyftp.c
字号:
sys_sprintf(buffer, "221 Goodbye.\r\n"); FTPSend(s, buffer, 0); tcp_Close(s); // by Oleg to exit from telnet client tcp_Abort(s); ftpServerStatus = STATUS_NONE; break; case TOK_PORT: i = 0; cp = argstr; argstr = strtok(cp, ','); while (argstr != NULL && i < 10) { strArr[i] = cp; cp = argstr; argstr = strtok(cp, ','); i++; } if (i != 10) { strArr[i] = cp; } sys_sprintf(ipaddr, "%s.%s.%s.%s", strArr[0], strArr[1], strArr[2], strArr[3]); convert2num(ipaddr, &ftpRemoteHost); ftpRemotePort = (256 * atoui(strArr[4])) + atoui(strArr[5]); tcp_Open(&ftp_data, 20, ftpRemoteHost, ftpRemotePort, FTPDataHandler); FTPSend(s, "200 Port command successful.\r\n", 0); ftpServerStatus = STATUS_ACTIVE; break; case TOK_USER: ftpServerStatus = STATUS_LOGIN; if (argstr != NULL) { strncpy(username, argstr, (USERNAME_LEN-1)); sys_sprintf(buffer, "331 Password required for %s.\r\n", username); } else sys_sprintf(buffer, "530 Please login with USER and PASS.\r\n"); FTPSend(s, buffer, 0); break; case TOK_PASS: if (username[0] == 0) FTPSend(s, "503 Login with USER first.\r\n", 0); else { if (strcmp(username, "adam2") == 0) // by Oleg not needed && (strcmp(argstr, "adam2") == 0)) { ftpServerStatus = STATUS_IDLE; sys_sprintf(buffer, "230 %s logged in.\r\n", username); FTPSend(s, buffer, 0); } else FTPSend(s, "530 Login incorrect.\r\n", 0); } break; case TOK_HELP: sys_sprintf(buffer, "214-commands:\r\n"); for (i = TOK_ABOR; i < TOK_ERROR; i++) { strcat(buffer, commandList[i].commandName); strcat(buffer, "\r\n"); } FTPSend(s, buffer, 0); sys_sprintf(buffer, "214 HELP Command successful\r\n"); FTPSend(s, buffer, 0); break; #if 0 case TOK_SYST: FTPSend(s, "215 UNIX emulated bye ADAM2's FTP Server.\r\n", 0); break; case TOK_PASW: #endif case TOK_PASV: port = (sed_lclEthAddr[2] + rtim) & 0xFFFF; sys_sprintf(buffer, "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d).\r\n", ((sin_lclINAddr>>24) & 0xff), ((sin_lclINAddr>>16) & 0xff), ((sin_lclINAddr>>8) & 0xff), (sin_lclINAddr & 0xff), port/256, port%256); tcp_Listen(&ftp_data, port, FTPDataHandler, 0); FTPSend(s, buffer, 0); ftpServerStatus = STATUS_PASSIVE; break; #if 0 case TOK_NLST: case TOK_LIST: if (ftpCheckState() == 0) { FTPSend(s, "550 Data Socket is not ready.\r\n", 0); break; } ftpServerStatus = STATUS_LIST; FTPSend(s, "150 Opening ASCII mode.\r\n", 0); strcpy(buffer, "FLASH-Adam2\r\nFLASH-Linux Kernel\r\nFLASH-Linux FileSystem\r\nFLASH-Linux Configuration\r\nFLASH-Env Space\r\nSDRAM-POST\r\n"); FTPSend(&ftp_data, buffer, 0); tcp_Close(&ftp_data); FTPSend(s, "226 Transfer complete.\r\n", 0); ftpServerStatus = STATUS_IDLE; break; #endif case TOK_STOR: if (ftpCheckState() == 0) { FTPSend(s, "550 Data Socket not ready.\r\n", 0); break; } if (ftpType != TYPE_BINARY) { FTPSend(s, "550 Data connection mode not set to BINARY.\r\n", 0); tcp_Close(&ftp_data); break; }/* if (ftpMedia == MEDIA_NONE) ftpMedia = MEDIA_SDRAM;*/ if (ftpMedia == MEDIA_FLASH) { char cfgman_mtd_name[FLASH_ENV_ENTRY_SIZE]; bit8u *pdata; bit8u *pdst; sys_sprintf(cfgman_mtd_name,"mtd%d", CFGMAN_MTD); cp = strtok(argstr, ' '); if (cp == NULL) { FTPSend(s, "550 No <blockname> specified.\r\n", 0); tcp_Close(&ftp_data); break; } start = sys_getenv(cp); if (start == NULL) { FTPSend(s, "550 <blockname> environment variable not set.\r\n", 0); tcp_Close(&ftp_data); break; } end = strtok(start, ','); if ((start == NULL) || (end == NULL) || (myatox(start,&flashAddress) == 0) || (myatox(end,&endAddress) == 0)) { FTPSend(s, "550 invalid <blockname>.\r\n", 0); tcp_Close(&ftp_data); break; } flashAddress &= 0x1fffffff; flashAddress |= 0xa0000000; endAddress &= 0x1fffffff; endAddress |= 0xa0000000; /* when updating the config.xml, we need to save the env vars data since * we are sharing the same block */ if(strcmp(cp,cfgman_mtd_name)==0) { /* create a buffer to hold the data */ pdata=sys_malloc(ENV_VAR_MTD_SIZE); if(!pdata) { FTPSend(s, "550 malloc failed.\r\n", 0); tcp_Close(&ftp_data); break; } /* save the env vars */ sys_memcpy(pdata,(void *)(flashAddress+ENV_VAR_MTD_OFFSET), ENV_VAR_MTD_SIZE); }// by Oleg add check to protect Adam, it can not be erased if ((FWBValid((bit32u)flashAddress) == 0)||(erase(flashAddress, endAddress) != 0)) { FTPSend(s, "550 can not erase\r\n", 0); tcp_Close(&ftp_data); if(pdata) sys_free(pdata); break; } /* when updating the config.xml, we need to restore the env vars data */ if(strcmp(cp,cfgman_mtd_name)==0) { pdst=(bit8u *)(flashAddress+ENV_VAR_MTD_OFFSET); if( !FWBOpen((bit32u)flashAddress) ) { FTPSend(s, "550 Could not open flash for write.\r\n", 0); tcp_Close(&ftp_data); sys_free(pdata); break; } WriteToFlash(pdst, pdata, ENV_VAR_MTD_SIZE); if( !FWBClose() ) { FTPSend(s, "550 Could not close flash.\r\n", 0); tcp_Close(&ftp_data); sys_free(pdata); break; } sys_free(pdata); /* Here is the hack that will adjust the offset so that the store * will write to the correct area in the flash */ flashOffset=CFGMAN_MTD_OFFSET; } } FTPSend(s, "150 Opening BINARY mode.\r\n", 0); ftpServerStatus = STATUS_UPLOAD; break; case TOK_TYPE: sys_sprintf(buffer, "200 Type set to %s.\r\n", argstr); FTPSend(s, buffer, 0); if (strcmp(argstr, "I") == 0) ftpType = TYPE_BINARY; else ftpType = TYPE_ASCII; break; case TOK_RETR: if (ftpCheckState() == 0) { FTPSend(s, "550 Data Socket is not ready.\r\n", 0); break; }/* if (ftpMedia == MEDIA_NONE) ftpMedia = MEDIA_SDRAM;*/ if (ftpType == TYPE_BINARY) strcpy(buffer, "150 Opening BINARY mode data connection for file transfer.\r\n"); else strcpy(buffer, "150 Opening ASCII mode data connection for file transfer.\r\n"); ftpServerStatus = STATUS_DOWNLOAD; if (strcmp(argstr, "config.xml") == 0) { FTPSend(s, buffer, 0); if (RetrConfigSpace(&ftp_data) == TRUE) break; } else if (strcmp(argstr, "env") == 0) { FTPSend(s, buffer, 0); RetrEnvSpace(&ftp_data); } else if (sys_getenv(argstr) != NULL) { // by Oleg start = sys_getenv(argstr); end = strtok(start, ','); if ((start == NULL) || (end == NULL) || (myatox(start,&flashAddress) == 0) || (myatox(end,&endAddress) == 0)) { FTPSend(s, "550 invalid <blockname>.\r\n", 0); tcp_Close(&ftp_data); break; } FTPSend(s, buffer, 0); if (RetrMtdSpace(&ftp_data) == TRUE) break; // transfer by parts } else { FTPSend(s, "550 File not found.\r\n", 0); tcp_Close(&ftp_data); break; } tcp_Close(&ftp_data); FTPSend(s, "226 Transfer complete.\r\n", 0); ftpServerStatus = STATUS_IDLE; break; case TOK_MEDIA: if (strcmp(argstr, "FLSH") == 0) { ftpMedia = MEDIA_FLASH; FTPSend(s, "200 media set to FLASH\r\n", 0); } else { ftpMedia = MEDIA_SDRAM; FTPSend(s, "200 media set to SDRAM\r\n", 0); } break; case TOK_GETENV: cp = sys_getenv(argstr); if (cp == NULL) sys_sprintf(buffer, "501 %s environment variable not set.\r\n", argstr); else { sys_sprintf(buffer, "%-20s %s\r\n\r\n200 GETENV successful\r\n", argstr, cp); } FTPSend(s, buffer, 0); break; case TOK_SETENV: cp = strtok(argstr, ','); if (sys_setenv(argstr, cp) == 0) FTPSend(s, "200 SETENV successful\r\n", 0); else FTPSend(s, "501 SETENV failed.\r\n", 0); break; case TOK_UNSETENV: if (sys_unsetenv(argstr) != 0) FTPSend(s, "501 no such variable.\r\n", 0); else FTPSend(s, "200 UNSETENV successful\r\n", 0); break; case TOK_FIXENV: if (fixenv(0, NULL) != 0) FTPSend(s, "501 FIXENV error.\r\n", 0); else FTPSend(s, "200 FIXENV successful\r\n", 0); break; case TOK_PRINTENV: FTPSend(s, "214-list\r\n", 0); RetrEnvSpace(s); FTPSend(s, "214 PRINTENV successful\r\n", 0); break; case TOK_REBOOT: sys_sprintf(buffer, "221 Goodbye.\r\n"); FTPSend(s, buffer, 0); tcp_Close(s); rebootFlag = TRUE; break; default: FTPSend(s, "502 not implemented - Try HELP.\r\n", 0); break; }}void FTPCommandHandler (tcp_Socket *s, byte *dp, int len, int state){ byte c, *bp, data[80]; int i; if (state == SOPEN || state == SABORT || state == SCLOSE) { if (ftp_ctl.state == tcp_StateCLOSED) ftpServerStatus = STATUS_NONE; return; } if (dp == 0) { if ((ftp_data.state != 0) &&(ftp_data.state != tcp_StateCLOSED)) { tcp_Abort(&ftp_data); } return; } do { i = len; if ( i > sizeof data ) i = sizeof data; MoveW(dp, data, i); dp += i; len -= i; bp = data; while ( i-- > 0 ) { c = *bp++; if ( c != '\r' ) { if ( c == '\n' ) { ftp_cmdbuf[ftp_cmdbufi] = 0; FTPCommandLine(s); ftp_cmdbufi = 0; } else { if ( ftp_cmdbufi < ((sizeof ftp_cmdbuf)-1) ) { ftp_cmdbuf[ftp_cmdbufi++] = c; } } } } }while(len > 0);}void FTPCtrlHandler(tcp_Socket *s, byte *dp, int len, int state){ switch (ftpServerStatus) { case STATUS_WELCOME: FTPSend(s, "220 ADAM2 FTP Server ready.\r\n", 0); ftpServerStatus = STATUS_LOGIN; break; case STATUS_LOGIN: case STATUS_IDLE: case STATUS_PASSIVE: case STATUS_ACTIVE: case STATUS_LIST : case STATUS_UPLOAD : case STATUS_DOWNLOAD : case STATUS_NONE: FTPCommandHandler(s, dp, len, state); break; default: sys_printf("FTPCtrlHandler: Unknown -%d\n", ftpServerStatus); break; }}int FTPServer(void){ tcp_Init(); rebootFlag = FALSE; ftpMedia = MEDIA_SDRAM; /* MEDIA_NONE; */ ftpType = TYPE_NONE; tcp_Listen(&ftp_ctl, 21, FTPCtrlHandler, 0); ftpServerStatus = STATUS_WELCOME; return 1;}void autodetect_Handler(void){ char cp[20]; longword rcv_ipaddress, req_ipaddress = 0x0; autodetectPacket rxpacket; UINT32 bootloaderVersion = 0x0; if ((udp_receive(&rcv_ipaddress, &rxpacket, sizeof(autodetectPacket), FALSE)) == 0) return; bootloaderVersion = lfix(rxpacket.version);// by Oleg commented this check/* sys_printf("adam2app packet received: 0x%x\n", bootloaderVersion); if ((((bootloaderVersion>>16) & 0xFF) == MonitorMajorRev) && (((bootloaderVersion>>8) & 0xFF) == MonitorMinorRev) && ((bootloaderVersion & 0xFF) == TelogyMonitorRev))*/ {/* Check the version in the packet from PC Application If it is same as * BootLoader version then proceed further.*/ if (rxpacket.type == TYPE_REQUEST) { req_ipaddress = lfix(rxpacket.data); sys_memset(&rxpacket, 0, sizeof(autodetectPacket)); rxpacket.version = lfix(bootloaderVersion); rxpacket.type = TYPE_RESPONSE; if (req_ipaddress == 0x0) rxpacket.data = sin_lclINAddr; else { sin_lclINAddr = req_ipaddress; sys_memset(cp, 0, sizeof(cp)); sys_sprintf(cp, "%d.%d.%d.%d", ((req_ipaddress>>24) & 0xff), ((req_ipaddress>>16) & 0xff),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -