Line 8... |
Line 8... |
* Software 'as is' without warranty. Author liable for nothing.
|
* Software 'as is' without warranty. Author liable for nothing.
|
* DESCRIPTION:
|
* DESCRIPTION:
|
* Plasma FTP server and FTP client and TFTP server and client
|
* Plasma FTP server and FTP client and TFTP server and client
|
* and Telnet server.
|
* and Telnet server.
|
*--------------------------------------------------------------------*/
|
*--------------------------------------------------------------------*/
|
#undef INCLUDE_FILESYS
|
#define INSIDE_NETUTIL
|
#define INCLUDE_FILESYS
|
#include "plasma.h"
|
#include "rtos.h"
|
#include "rtos.h"
|
#include "tcpip.h"
|
#include "tcpip.h"
|
|
|
#ifdef DLL_SETUP
|
#ifndef EXCLUDE_DLL
|
static void ConsoleRun(IPSocket *socket, char *argv[]);
|
static void ConsoleRun(IPSocket *socket, char *argv[]);
|
#endif
|
#endif
|
|
|
//******************* FTP Server ************************
|
//******************* FTP Server ************************
|
typedef struct {
|
typedef struct {
|
Line 133... |
Line 133... |
info->file = NULL;
|
info->file = NULL;
|
info->bytes = 0;
|
info->bytes = 0;
|
info->done = 0;
|
info->done = 0;
|
if(strstr((char*)buf, "RETR"))
|
if(strstr((char*)buf, "RETR"))
|
info->file = fopen((char*)buf + 5, "rb");
|
info->file = fopen((char*)buf + 5, "rb");
|
else if(info->canReceive)
|
else if(info->canReceive && strcmp((char*)buf+5, "/flash/web"))
|
info->file = fopen((char*)buf + 5, "wb");
|
info->file = fopen((char*)buf + 5, "wb");
|
if(info->file)
|
if(info->file)
|
{
|
{
|
IPPrintf(socket, "150 File ready\r\n");
|
IPPrintf(socket, "150 File ready\r\n");
|
if(strstr((char*)buf, "RETR"))
|
if(strstr((char*)buf, "RETR"))
|
Line 373... |
Line 373... |
memcpy((uint8*)socket->userPtr + blockNum * 512 - 512, buf+4, bytes-4);
|
memcpy((uint8*)socket->userPtr + blockNum * 512 - 512, buf+4, bytes-4);
|
buf[1] = 4; //ACK
|
buf[1] = 4; //ACK
|
IPWrite(socket, buf, 4);
|
IPWrite(socket, buf, 4);
|
if(bytes-4 < 512)
|
if(bytes-4 < 512)
|
{
|
{
|
socket->userFunc(socket, socket->userPtr, length);
|
socket->userFunc(socket, (uint8*)socket->userPtr, length);
|
IPClose(socket);
|
IPClose(socket);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
Line 407... |
Line 407... |
#define COMMAND_BUFFER_SIZE 80
|
#define COMMAND_BUFFER_SIZE 80
|
#define COMMAND_BUFFER_COUNT 10
|
#define COMMAND_BUFFER_COUNT 10
|
static char CommandHistory[400];
|
static char CommandHistory[400];
|
static char *CommandPtr[COMMAND_BUFFER_COUNT];
|
static char *CommandPtr[COMMAND_BUFFER_COUNT];
|
static int CommandIndex;
|
static int CommandIndex;
|
|
static OS_Semaphore_t *semProtect;
|
|
|
typedef void (*ConsoleFunc)(IPSocket *socket, char *argv[]);
|
typedef void (*ConsoleFunc)(IPSocket *socket, char *argv[]);
|
typedef struct {
|
typedef struct {
|
char *name;
|
char *name;
|
ConsoleFunc func;
|
ConsoleFunc func;
|
} TelnetFunc_t;
|
} TelnetFunc_t;
|
static TelnetFunc_t *TelnetFuncList;
|
static TelnetFunc_t *TelnetFuncList;
|
|
|
|
static int TelnetGetLine(IPSocket *socket, uint8 *bufIn, int bytes)
|
static void TelnetServer(IPSocket *socket)
|
|
{
|
{
|
uint8 buf[COMMAND_BUFFER_SIZE+4];
|
int i, j, length;
|
|
char *ptr, *command = (char*)socket->userPtr;
|
char bufOut[32];
|
char bufOut[32];
|
int bytes, i, j, k, length, found;
|
|
char *ptr, *command = socket->userPtr;
|
|
char *argv[10];
|
|
|
|
if(socket->state > IP_TCP)
|
|
return;
|
|
for(;;)
|
|
{
|
|
bytes = IPRead(socket, buf, sizeof(buf)-1);
|
|
if(command == NULL)
|
|
{
|
|
socket->userPtr = command = (char*)malloc(COMMAND_BUFFER_SIZE);
|
|
if(command == NULL)
|
|
{
|
|
IPClose(socket);
|
|
return;
|
|
}
|
|
socket->timeoutReset = 300;
|
|
buf[0] = 255; //IAC
|
|
buf[1] = 251; //WILL
|
|
buf[2] = 3; //suppress go ahead
|
|
buf[3] = 255; //IAC
|
|
buf[4] = 251; //WILL
|
|
buf[5] = 1; //echo
|
|
strcpy((char*)buf+6, "Welcome to Plasma.\r\n-> ");
|
|
IPWrite(socket, buf, 6+23);
|
|
IPWriteFlush(socket);
|
|
command[0] = 0;
|
|
return;
|
|
}
|
|
if(bytes == 0)
|
|
return;
|
|
socket->dontFlush = 0;
|
|
buf[bytes] = 0;
|
|
length = (int)strlen(command);
|
length = (int)strlen(command);
|
for(j = 0; j < bytes; ++j)
|
for(j = 0; j < bytes; ++j)
|
{
|
{
|
if(buf[j] == 255)
|
if(bufIn[j] == 255)
|
return;
|
break;
|
if(buf[j] == 8 || (buf[j] == 27 && buf[j+2] == 'D'))
|
if(bufIn[j] == 8 || (bufIn[j] == 27 && bufIn[j+2] == 'D'))
|
{
|
{
|
if(buf[j] == 27)
|
if(bufIn[j] == 27)
|
j += 2;
|
j += 2;
|
if(length)
|
if(length)
|
{
|
{
|
// Backspace
|
// Backspace
|
command[--length] = 0;
|
command[--length] = 0;
|
bufOut[0] = 8;
|
bufOut[0] = 8;
|
bufOut[1] = ' ';
|
bufOut[1] = ' ';
|
bufOut[2] = 8;
|
bufOut[2] = 8;
|
IPWrite(socket, (uint8*)bufOut, 3);
|
IPWrite(socket, (uint8*)bufOut, 3);
|
|
IPWriteFlush(socket);
|
}
|
}
|
}
|
}
|
else if(buf[j] == 27)
|
else if(bufIn[j] == 27)
|
{
|
{
|
// Command History
|
// Command History
|
if(buf[j+2] == 'A')
|
if(bufIn[j+2] == 'A')
|
{
|
{
|
if(++CommandIndex > COMMAND_BUFFER_COUNT)
|
if(++CommandIndex > COMMAND_BUFFER_COUNT)
|
CommandIndex = COMMAND_BUFFER_COUNT;
|
CommandIndex = COMMAND_BUFFER_COUNT;
|
}
|
}
|
else if(buf[j+2] == 'B')
|
else if(bufIn[j+2] == 'B')
|
{
|
{
|
if(--CommandIndex < 0)
|
if(--CommandIndex < 0)
|
CommandIndex = 0;
|
CommandIndex = 0;
|
}
|
}
|
else
|
else
|
return;
|
return -1;
|
bufOut[0] = 8;
|
bufOut[0] = 8;
|
bufOut[1] = ' ';
|
bufOut[1] = ' ';
|
bufOut[2] = 8;
|
bufOut[2] = 8;
|
for(i = 0; i < length; ++i)
|
for(i = 0; i < length; ++i)
|
IPWrite(socket, (uint8*)bufOut, 3);
|
IPWrite(socket, (uint8*)bufOut, 3);
|
command[0] = 0;
|
command[0] = 0;
|
if(CommandIndex && CommandPtr[CommandIndex-1])
|
if(CommandIndex && CommandPtr[CommandIndex-1])
|
strncat(command, CommandPtr[CommandIndex-1], COMMAND_BUFFER_SIZE-1);
|
strncat(command, CommandPtr[CommandIndex-1], COMMAND_BUFFER_SIZE-1);
|
length = (int)strlen(command);
|
length = (int)strlen(command);
|
IPWrite(socket, (uint8*)command, length);
|
IPWrite(socket, (uint8*)command, length);
|
|
IPWriteFlush(socket);
|
j += 2;
|
j += 2;
|
}
|
}
|
else
|
else
|
{
|
{
|
if(buf[j] == 0)
|
if(bufIn[j] == 0)
|
buf[j] = '\n'; //Linux support
|
bufIn[j] = '\n'; //Linux support
|
if(length < COMMAND_BUFFER_SIZE-4 || (length <
|
if(length < COMMAND_BUFFER_SIZE-4 || (length <
|
COMMAND_BUFFER_SIZE-2 && (buf[j] == '\r' || buf[j] == '\n')))
|
COMMAND_BUFFER_SIZE-2 && (bufIn[j] == '\r' || bufIn[j] == '\n')))
|
{
|
{
|
IPWrite(socket, buf+j, 1);
|
IPWrite(socket, (uint8*)bufIn+j, 1);
|
command[length] = buf[j];
|
IPWriteFlush(socket);
|
|
command[length] = bufIn[j];
|
command[++length] = 0;
|
command[++length] = 0;
|
}
|
}
|
}
|
}
|
ptr = strstr(command, "\r\n");
|
ptr = strstr(command, "\r\n");
|
|
if(ptr == NULL)
|
|
ptr = strstr(command, "\n");
|
if(ptr)
|
if(ptr)
|
{
|
{
|
// Save command in CommandHistory
|
// Save command in CommandHistory
|
ptr[0] = 0;
|
ptr[0] = 0;
|
length = (int)strlen(command);
|
length = (int)strlen(command);
|
if(length == 0)
|
if(length == 0)
|
{
|
{
|
IPPrintf(socket, "-> ");
|
IPPrintf(socket, "\n-> ");
|
continue;
|
continue;
|
}
|
}
|
if(length < COMMAND_BUFFER_SIZE)
|
if(length < COMMAND_BUFFER_SIZE)
|
{
|
{
|
|
OS_SemaphorePend(semProtect, OS_WAIT_FOREVER);
|
memmove(CommandHistory + length + 1, CommandHistory,
|
memmove(CommandHistory + length + 1, CommandHistory,
|
sizeof(CommandHistory) - length - 1);
|
sizeof(CommandHistory) - length - 1);
|
strcpy(CommandHistory, command);
|
strcpy(CommandHistory, command);
|
CommandHistory[sizeof(CommandHistory)-1] = 0;
|
CommandHistory[sizeof(CommandHistory)-1] = 0;
|
for(i = COMMAND_BUFFER_COUNT-2; i >= 0; --i)
|
for(i = COMMAND_BUFFER_COUNT-2; i >= 0; --i)
|
Line 538... |
Line 512... |
CommandPtr[i+1] = NULL;
|
CommandPtr[i+1] = NULL;
|
else
|
else
|
CommandPtr[i+1] = CommandPtr[i] + length + 1;
|
CommandPtr[i+1] = CommandPtr[i] + length + 1;
|
}
|
}
|
CommandPtr[0] = CommandHistory;
|
CommandPtr[0] = CommandHistory;
|
|
OS_SemaphorePost(semProtect);
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
static void TelnetServerCallback(IPSocket *socket)
|
|
{
|
|
uint8 bufIn[COMMAND_BUFFER_SIZE+4];
|
|
int bytes, i, k, found, rc;
|
|
char *ptr, *command = (char*)socket->userPtr;
|
|
char command2[COMMAND_BUFFER_SIZE];
|
|
char *argvStorage[12], **argv = argvStorage+2;
|
|
|
|
if(socket->state > IP_TCP)
|
|
return;
|
|
for(;;)
|
|
{
|
|
bytes = IPRead(socket, bufIn, sizeof(bufIn)-1);
|
|
if(command == NULL)
|
|
{
|
|
socket->userPtr = command = (char*)malloc(COMMAND_BUFFER_SIZE);
|
|
if(command == NULL)
|
|
{
|
|
IPClose(socket);
|
|
return;
|
|
}
|
|
socket->timeoutReset = 60*15;
|
|
bufIn[0] = 255; //IAC
|
|
bufIn[1] = 251; //WILL
|
|
bufIn[2] = 3; //suppress go ahead
|
|
bufIn[3] = 255; //IAC
|
|
bufIn[4] = 251; //WILL
|
|
bufIn[5] = 1; //echo
|
|
strcpy((char*)bufIn+6, "Welcome to Plasma.\r\n-> ");
|
|
IPWrite(socket, bufIn, 6+23);
|
|
IPWriteFlush(socket);
|
|
command[0] = 0;
|
|
OS_ThreadInfoSet(OS_ThreadSelf(), 0, (void*)socket); //for stdin and stdout
|
|
return;
|
}
|
}
|
|
if(bytes == 0)
|
|
return;
|
|
socket->dontFlush = 0;
|
|
bufIn[bytes] = 0;
|
|
|
//Start command
|
//Get a complete command line
|
|
rc = TelnetGetLine(socket, bufIn, bytes);
|
|
if(rc)
|
|
continue;
|
|
strcpy(command2, command);
|
|
command[0] = 0;
|
|
|
|
//Process arguments
|
for(i = 0; i < 10; ++i)
|
for(i = 0; i < 10; ++i)
|
argv[i] = "";
|
argv[i] = "";
|
i = 0;
|
i = 0;
|
argv[i++] = command;
|
argv[i++] = command2;
|
for(ptr = command; *ptr && i < 10; ++ptr)
|
for(ptr = command2; *ptr && i < 10; ++ptr)
|
{
|
{
|
if(*ptr == ' ')
|
if(*ptr == ' ')
|
{
|
{
|
*ptr = 0;
|
*ptr = 0;
|
argv[i++] = ptr + 1;
|
argv[i++] = ptr + 1;
|
Line 558... |
Line 586... |
if(argv[0][0] == 0)
|
if(argv[0][0] == 0)
|
{
|
{
|
IPPrintf(socket, "-> ");
|
IPPrintf(socket, "-> ");
|
continue;
|
continue;
|
}
|
}
|
found = 0;
|
|
for(i = 0; TelnetFuncList[i].name; ++i)
|
//Check for file in or out
|
{
|
|
if(strcmp(command, TelnetFuncList[i].name) == 0 &&
|
|
TelnetFuncList[i].func)
|
|
{
|
|
found = 1;
|
|
for(k = 1; k < 10; ++k)
|
for(k = 1; k < 10; ++k)
|
{
|
{
|
if(argv[k][0] == '>' && argv[k][1]) //stdout to file?
|
if(argv[k][0] == '>') //stdout to file?
|
{
|
{
|
|
if(argv[k][1])
|
socket->fileOut = fopen(&argv[k][1], "a");
|
socket->fileOut = fopen(&argv[k][1], "a");
|
|
else
|
|
socket->fileOut = fopen(argv[k+1], "a");
|
argv[k] = "";
|
argv[k] = "";
|
}
|
}
|
if(argv[k][0] == '<' && argv[k][1]) //stdin from file?
|
if(argv[k][0] == '<') //stdin from file?
|
{
|
{
|
|
if(argv[k][1])
|
socket->fileIn = fopen(&argv[k][1], "r");
|
socket->fileIn = fopen(&argv[k][1], "r");
|
|
else
|
|
socket->fileIn = fopen(argv[k+1], "r");
|
argv[k] = "";
|
argv[k] = "";
|
}
|
}
|
}
|
}
|
TelnetFuncList[i].func(socket, argv);
|
|
if(socket->fileOut)
|
//Find command
|
|
found = 0;
|
|
for(i = 0; TelnetFuncList[i].name; ++i)
|
{
|
{
|
fwrite("\r\n", 1, 2, socket->fileOut);
|
if(strcmp(argv[0], TelnetFuncList[i].name) == 0 &&
|
fclose(socket->fileOut);
|
TelnetFuncList[i].func)
|
}
|
{
|
socket->fileOut = NULL;
|
found = 1;
|
|
TelnetFuncList[i].func(socket, argv);
|
break;
|
break;
|
}
|
}
|
}
|
}
|
#ifdef DLL_SETUP
|
#ifndef EXCLUDE_DLL
|
if(found == 0)
|
if(found == 0)
|
{
|
{
|
strcpy((char*)buf, "/flash/bin/");
|
FILE *file = fopen(argv[0], "r");
|
strcat((char*)buf, argv[0]);
|
if(file)
|
argv[0] = (char*)buf;
|
{
|
|
fclose(file);
|
ConsoleRun(socket, argv);
|
ConsoleRun(socket, argv);
|
}
|
}
|
|
else
|
|
{
|
|
strcpy((char*)bufIn, "/flash/bin/");
|
|
strcat((char*)bufIn, argv[0]);
|
|
argv[0] = (char*)bufIn;
|
|
ConsoleRun(socket, argv);
|
|
}
|
|
}
|
#endif
|
#endif
|
|
if(socket->fileOut)
|
|
{
|
|
fwrite("\r\n", 1, 2, (FILE*)socket->fileOut);
|
|
fclose((FILE*)socket->fileOut);
|
|
socket->fileOut = NULL;
|
|
}
|
|
|
if(socket->state > IP_TCP)
|
if(socket->state > IP_TCP)
|
return;
|
return;
|
command[0] = 0;
|
|
length = 0;
|
|
CommandIndex = 0;
|
CommandIndex = 0;
|
if(socket->dontFlush == 0)
|
if(socket->dontFlush == 0)
|
IPPrintf(socket, "\r\n-> ");
|
IPPrintf(socket, "\r\n-> ");
|
} //command entered
|
|
} //bytes
|
|
IPWriteFlush(socket);
|
|
}
|
}
|
}
|
}
|
|
|
|
|
|
static void TelnetThread(void *socketIn)
|
|
{
|
|
IPSocket *socket = (IPSocket*)socketIn;
|
|
|
|
while(socket->state <= IP_TCP)
|
|
{
|
|
OS_SemaphorePend(socket->userSemaphore, OS_WAIT_FOREVER);
|
|
TelnetServerCallback(socket);
|
|
}
|
|
if(socket->userPtr)
|
|
free(socket->userPtr);
|
|
socket->userPtr = NULL;
|
|
OS_SemaphoreDelete(socket->userSemaphore);
|
|
socket->userSemaphore = NULL;
|
|
OS_ThreadExit();
|
|
}
|
|
|
|
|
|
static void TelnetServer(IPSocket *socket)
|
|
{
|
|
if(socket->state <= IP_TCP && socket->userSemaphore == NULL)
|
|
{
|
|
socket->userSemaphore = OS_SemaphoreCreate("telnet", 0);
|
|
OS_ThreadCreate("telnet", TelnetThread, socket, 100, 1024*8);
|
|
}
|
|
if(socket->userSemaphore)
|
|
OS_SemaphorePost(socket->userSemaphore);
|
|
}
|
|
|
|
|
void TelnetInit(TelnetFunc_t *funcList)
|
void TelnetInit(TelnetFunc_t *funcList)
|
{
|
{
|
IPSocket *socket;
|
IPSocket *socket;
|
TelnetFuncList = funcList;
|
TelnetFuncList = funcList;
|
socket = IPOpen(IP_MODE_TCP, 0, 23, TelnetServer);
|
semProtect = OS_SemaphoreCreate("telprot", 1);
|
|
#ifndef WIN32
|
|
socket = IPOpen(IP_MODE_TCP, 0, 23, TelnetServer); //create thread
|
|
#else
|
|
socket = IPOpen(IP_MODE_TCP, 0, 23, TelnetServerCallback);
|
|
#endif
|
}
|
}
|
|
|
|
|
//******************* Console ************************
|
//******************* Console ************************
|
|
|
Line 627... |
Line 705... |
static uint8 *myStorage;
|
static uint8 *myStorage;
|
static IPSocket *socketTelnet;
|
static IPSocket *socketTelnet;
|
static char storageFilename[60];
|
static char storageFilename[60];
|
|
|
|
|
|
int ConsoleScanf(char *format,
|
|
int arg0, int arg1, int arg2, int arg3,
|
|
int arg4, int arg5, int arg6, int arg7)
|
|
{
|
|
IPSocket *socket = (IPSocket*)OS_ThreadInfoGet(OS_ThreadSelf(), 0);
|
|
char *command = (char*)socket->userPtr;
|
|
uint8 bufIn[256];
|
|
int bytes;
|
|
int rc;
|
|
|
|
while(socket->state <= IP_TCP)
|
|
{
|
|
bytes = IPRead(socket, (unsigned char*)bufIn, sizeof(bufIn));
|
|
rc = TelnetGetLine(socket, bufIn, bytes);
|
|
if(rc == 0)
|
|
break;
|
|
OS_ThreadSleep(1);
|
|
}
|
|
|
|
rc = sscanf(command, format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
|
command[0] = 0;
|
|
return rc;
|
|
}
|
|
|
|
|
|
int ConsoleKbhit(void)
|
|
{
|
|
IPSocket *socket = (IPSocket*)OS_ThreadInfoGet(OS_ThreadSelf(), 0);
|
|
|
|
if(socket->state > IP_TCP || socket->frameReadTail || socket->fileIn)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
|
|
int ConsoleGetch(void)
|
|
{
|
|
unsigned char buffer[8];
|
|
int rc, i;
|
|
|
|
for(i = 0; i < 100*60; ++i)
|
|
{
|
|
if(ConsoleKbhit())
|
|
break;
|
|
OS_ThreadSleep(5);
|
|
}
|
|
|
|
rc = IPRead(NULL, buffer, 1);
|
|
if(rc <= 0)
|
|
return -1;
|
|
return buffer[0];
|
|
}
|
|
|
|
|
|
int ConsolePrintf(char *format,
|
|
int arg0, int arg1, int arg2, int arg3,
|
|
int arg4, int arg5, int arg6, int arg7)
|
|
{
|
|
return IPPrintf(NULL, format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
|
}
|
|
|
|
|
static void ConsoleHelp(IPSocket *socket, char *argv[])
|
static void ConsoleHelp(IPSocket *socket, char *argv[])
|
{
|
{
|
char buf[200];
|
char buf[200];
|
int i;
|
int i;
|
(void)argv;
|
(void)argv;
|
strcpy(buf, "Commands: ");
|
strcpy(buf, "Version " __DATE__ " " __TIME__ "\nCommands: ");
|
for(i = 0; TelnetFuncList[i].name; ++i)
|
for(i = 0; TelnetFuncList[i].name; ++i)
|
{
|
{
|
if(TelnetFuncList[i].func)
|
if(TelnetFuncList[i].func)
|
{
|
{
|
if(i)
|
if(i)
|
Line 648... |
Line 788... |
}
|
}
|
|
|
|
|
static void ConsoleExit(IPSocket *socket, char *argv[])
|
static void ConsoleExit(IPSocket *socket, char *argv[])
|
{
|
{
|
free(argv[0]);
|
|
socket->userPtr = NULL;
|
|
IPClose(socket);
|
IPClose(socket);
|
}
|
}
|
|
|
|
|
|
static void ConsoleMemcpyReboot(int *dst, int *src, int length)
|
|
{
|
|
OS_FuncPtr_t funcPtr = (OS_FuncPtr_t)dst;
|
|
while(length-- > 0)
|
|
*dst++ = *src++;
|
|
funcPtr(NULL);
|
|
}
|
|
|
|
|
|
static void ConsoleReboot(IPSocket *socket, char *argv[])
|
|
{
|
|
FILE *file = NULL;
|
|
OS_FuncPtr_t funcPtr;
|
|
unsigned char *ptr;
|
|
int length;
|
|
(void)socket;
|
|
|
|
if(argv[1][0])
|
|
file = fopen(argv[1], "r");
|
|
#ifndef EXCLUDE_FLASH
|
|
if(file && strcmp(argv[2], "flash") == 0)
|
|
{
|
|
unsigned char buffer[64];
|
|
int offset;
|
|
|
|
FlashErase(0); //erase 128KB sector
|
|
offset = 0;
|
|
for(;;)
|
|
{
|
|
length = fread(buffer, 1, sizeof(buffer), file);
|
|
if(length == 0)
|
|
break;
|
|
FlashWrite((uint16*)buffer, offset, length);
|
|
offset += length;
|
|
}
|
|
fclose(file);
|
|
file = NULL;
|
|
}
|
|
#endif
|
|
if(file)
|
|
{
|
|
//Reboot running new image
|
|
typedef void (*RebootFunc)(int *, int *, int);
|
|
typedef void (*MemcpyFunc)(int *dst, int *src, int length);
|
|
union { //convert from function pointer to data pointer
|
|
RebootFunc rebootFunc;
|
|
MemcpyFunc memcpyFunc;
|
|
unsigned char *ptr;
|
|
} rfUnion;
|
|
|
|
ptr=(unsigned char*)malloc(256+1024*128);
|
|
if(ptr == NULL)
|
|
return;
|
|
rfUnion.memcpyFunc = ConsoleMemcpyReboot;
|
|
memcpy(ptr, rfUnion.ptr, 256); //rfUnion.ptr==ConsoleMemcpyReboot
|
|
rfUnion.ptr = ptr;
|
|
ptr += 256;
|
|
length = fread(ptr, 1, 128*1024, file) + 3;
|
|
fclose(file);
|
|
printf("rebooting 0x%x 0x%x %d\n", (int)rfUnion.rebootFunc, (int)ptr, length);
|
|
OS_ThreadSleep(100);
|
|
OS_CriticalBegin();
|
|
rfUnion.rebootFunc((int*)RAM_EXTERNAL_BASE, (int*)ptr, length>>2);
|
|
}
|
|
funcPtr = NULL;
|
|
OS_CriticalBegin();
|
|
funcPtr(NULL);
|
|
}
|
|
|
|
|
static void ConsoleCat(IPSocket *socket, char *argv[])
|
static void ConsoleCat(IPSocket *socket, char *argv[])
|
{
|
{
|
FILE *file;
|
FILE *file;
|
uint8 buf[200];
|
uint8 buf[200];
|
int bytes;
|
int bytes;
|
Line 681... |
Line 889... |
FILE *fileIn, *fileOut;
|
FILE *fileIn, *fileOut;
|
uint8 buf[200];
|
uint8 buf[200];
|
int bytes;
|
int bytes;
|
(void)socket;
|
(void)socket;
|
|
|
|
fileOut = fopen(argv[2], "r");
|
|
if(fileOut)
|
|
{
|
|
IPPrintf(socket, "File already exists!\n");
|
|
fclose(fileOut);
|
|
return;
|
|
}
|
fileIn = fopen(argv[1], "r");
|
fileIn = fopen(argv[1], "r");
|
if(fileIn == NULL)
|
if(fileIn == NULL)
|
|
{
|
|
IPPrintf(socket, "Error!\n");
|
return;
|
return;
|
|
}
|
fileOut = fopen(argv[2], "w");
|
fileOut = fopen(argv[2], "w");
|
if(fileOut)
|
if(fileOut)
|
{
|
{
|
for(;;)
|
for(;;)
|
{
|
{
|
Line 750... |
Line 968... |
}
|
}
|
fclose(file);
|
fclose(file);
|
}
|
}
|
|
|
|
|
#ifdef INCLUDE_FLASH
|
#ifndef EXCLUDE_FLASH
|
static void ConsoleFlashErase(IPSocket *socket, char *argv[])
|
static void ConsoleFlashErase(IPSocket *socket, char *argv[])
|
{
|
{
|
int bytes;
|
int bytes;
|
|
OS_FuncPtr_t funcPtr = NULL;
|
(void)argv;
|
(void)argv;
|
IPPrintf(socket, "\r\nErasing");
|
IPPrintf(socket, "\r\nErasing\n");
|
|
OS_ThreadSleep(10);
|
|
OS_CriticalBegin();
|
for(bytes = 1024*128; bytes < 1024*1024*16; bytes += 1024*128)
|
for(bytes = 1024*128; bytes < 1024*1024*16; bytes += 1024*128)
|
{
|
{
|
IPPrintf(socket, ".");
|
UartPrintfCritical(".");
|
FlashErase(bytes);
|
FlashErase(bytes);
|
}
|
}
|
IPPrintf(socket, "\r\nMust Reboot\r\n");
|
funcPtr(NULL);
|
OS_ThreadSleep(OS_WAIT_FOREVER);
|
|
}
|
}
|
#endif
|
#endif
|
|
|
|
|
static void ConsoleMath(IPSocket *socket, char *argv[])
|
static void ConsoleMath(IPSocket *socket, char *argv[])
|
Line 795... |
Line 1015... |
}
|
}
|
|
|
|
|
static void PingCallback(IPSocket *socket)
|
static void PingCallback(IPSocket *socket)
|
{
|
{
|
IPSocket *socket2 = socket->userPtr;
|
IPSocket *socket2 = (IPSocket*)socket->userPtr;
|
IPClose(socket);
|
IPClose(socket);
|
if(socket2)
|
if(socket2)
|
IPPrintf(socket2, "Ping Reply");
|
IPPrintf(socket2, "Ping Reply");
|
else
|
else
|
printf("Ping Reply\n");
|
printf("Ping Reply\n");
|
Line 912... |
Line 1132... |
}
|
}
|
|
|
|
|
static void ConsoleUptime(IPSocket *socket, char *argv[])
|
static void ConsoleUptime(IPSocket *socket, char *argv[])
|
{
|
{
|
|
unsigned int ticks;
|
int days, hours, minutes, seconds;
|
int days, hours, minutes, seconds;
|
(void)argv;
|
(void)argv;
|
//ticks per sec = 25E6/2^18 = 95.36743 -> 10.48576 ms/tick
|
//ticks per sec = 25E6/2^18 = 95.36743 -> 10.48576 ms/tick
|
seconds = OS_ThreadTime() / 95;
|
ticks = OS_ThreadTime(); // 1/(1-95.3674/95) = -259
|
|
seconds = (ticks - ticks / 259) / 95;
|
minutes = seconds / 60 % 60;
|
minutes = seconds / 60 % 60;
|
hours = seconds / 3600 % 24;
|
hours = seconds / 3600 % 24;
|
days = seconds / 3600 / 24;
|
days = seconds / 3600 / 24;
|
seconds %= 60;
|
seconds %= 60;
|
IPPrintf(socket, "%d days %2d:%2d:%2d\n", days, hours, minutes, seconds);
|
IPPrintf(socket, "%d days %2d:%2d:%2d\n", days, hours, minutes, seconds);
|
Line 1004... |
Line 1226... |
}
|
}
|
fclose(fileIn);
|
fclose(fileIn);
|
}
|
}
|
|
|
|
|
#ifdef DLL_SETUP
|
#ifndef EXCLUDE_DLL
|
|
#ifndef WIN32
|
|
#define DLL_SETUP
|
#include "dll.h"
|
#include "dll.h"
|
|
#else
|
|
typedef void *(*DllFunc)();
|
|
DllFunc DllFuncList[1];
|
|
#define ntohl(A) (((A)>>24)|(((A)&0x00ff0000)>>8)|(((A)&0xff00)<<8)|((A)<<24))
|
|
#define ntohs(A) (uint16)((((A)&0xff00)>>8)|((A)<<8))
|
|
#endif
|
|
|
|
typedef struct
|
|
{
|
|
uint8 e_ident[16];
|
|
uint16 e_e_type;
|
|
uint16 e_machine;
|
|
uint32 e_version;
|
|
uint32 e_entry;
|
|
uint32 e_phoff;
|
|
uint32 e_shoff;
|
|
uint32 e_flags;
|
|
uint16 e_ehsize;
|
|
uint16 e_phentsize;
|
|
uint16 e_phnum;
|
|
uint16 e_shentsize;
|
|
uint16 e_shnum;
|
|
uint16 e_shstrndx;
|
|
} ElfHeader;
|
|
|
|
typedef struct
|
|
{
|
|
uint32 p_type;
|
|
uint32 p_offset;
|
|
uint32 p_vaddr;
|
|
uint32 p_paddr;
|
|
uint32 p_filesz;
|
|
uint32 p_memsz;
|
|
uint32 p_flags;
|
|
uint32 p_align;
|
|
} Elf32_Phdr;
|
|
|
|
|
|
static unsigned int ConsoleLoadElf(FILE *file, uint8 *ptr)
|
|
{
|
|
int i;
|
|
ElfHeader *elfHeader = (ElfHeader*)ptr;
|
|
Elf32_Phdr *elfProgram;
|
|
#ifdef WIN32
|
|
elfHeader->e_entry = ntohl(elfHeader->e_entry);
|
|
elfHeader->e_phoff = ntohl(elfHeader->e_phoff);
|
|
elfHeader->e_phentsize = ntohs(elfHeader->e_phentsize);
|
|
elfHeader->e_phnum = ntohs(elfHeader->e_phnum);
|
|
#endif
|
|
//printf("Entry=0x%x ", elfHeader->e_entry);
|
|
OS_ThreadSleep(10);
|
|
|
|
for(i = 0; i < elfHeader->e_phnum; ++i)
|
|
{
|
|
elfProgram = (Elf32_Phdr*)(ptr + elfHeader->e_phoff +
|
|
elfHeader->e_phentsize * i);
|
|
#ifdef WIN32
|
|
elfProgram->p_offset = ntohl(elfProgram->p_offset);
|
|
elfProgram->p_vaddr = ntohl(elfProgram->p_vaddr);
|
|
elfProgram->p_filesz = ntohl(elfProgram->p_filesz);
|
|
#endif
|
|
//printf("0x%x 0x%x 0x%x\n", elfProgram->p_vaddr, elfProgram->p_offset, elfProgram->p_filesz);
|
|
fseek(file, elfProgram->p_offset, 0);
|
|
#ifndef WIN32
|
|
fread((char*)elfProgram->p_vaddr, 1, elfProgram->p_filesz, file);
|
|
#endif
|
|
}
|
|
return elfHeader->e_entry;
|
|
}
|
|
|
|
|
static void ConsoleRun(IPSocket *socket, char *argv[])
|
static void ConsoleRun(IPSocket *socket, char *argv[])
|
{
|
{
|
FILE *file;
|
FILE *file;
|
int bytes, i;
|
int bytes, i, run=0;
|
uint8 code[128];
|
uint8 code[256];
|
DllFunc funcPtr;
|
DllFunc funcPtr;
|
char *command, *ptr;
|
|
|
|
if(strcmp(argv[0], "run") == 0)
|
if(strcmp(argv[0], "run") == 0)
|
|
{
|
|
run = 1;
|
++argv;
|
++argv;
|
|
}
|
file = fopen(argv[0], "r");
|
file = fopen(argv[0], "r");
|
if(file == NULL)
|
if(file == NULL)
|
{
|
{
|
IPPrintf(socket, "Can't find %s", argv[0]);
|
IPPrintf(socket, "Can't find %s", argv[0]);
|
return;
|
return;
|
}
|
}
|
|
|
bytes = fread(code, 1, sizeof(code), file); //load first 128 bytes
|
memset(code, 0, sizeof(code));
|
if(code[0] >= ' ')
|
bytes = fread(code, 1, sizeof(code), file); //load first bytes
|
|
if(strncmp((char*)code + 1, "ELF", 3) == 0)
|
{
|
{
|
socket->fileIn = file; //script file
|
funcPtr = (DllFunc)ConsoleLoadElf(file, code);
|
fseek(file, 0, 0);
|
|
return;
|
|
}
|
|
|
|
funcPtr = (DllFunc)code;
|
|
ptr = funcPtr(NULL); //determine load address
|
|
|
|
memcpy(ptr, code, bytes); //copy to correct address
|
|
bytes += fread(ptr + bytes, 1, 1024*1024*8, file);
|
|
fclose(file);
|
fclose(file);
|
printf("address=0x%x bytes=%d\n", (int)ptr, bytes);
|
argv[-1] = (char*)DllFuncList; //DllF = argv[-1]
|
funcPtr = (DllFunc)ptr;
|
argv[-2] = (char*)socket;
|
funcPtr = (DllFunc)funcPtr(DllFuncList); //initialize DLL, find Start()
|
for(i = 0; i < 10; ++i)
|
|
|
//Register new command
|
|
command = argv[0];
|
|
for(;;)
|
|
{
|
{
|
ptr = strstr(command, "/");
|
if(argv[i] == 0)
|
if(ptr == NULL)
|
|
break;
|
break;
|
command = ptr + 1;
|
|
}
|
}
|
for(i = 0; TelnetFuncList[i].name; ++i)
|
#ifndef WIN32
|
{
|
funcPtr(i, argv);
|
if(TelnetFuncList[i].name[0] == 0 ||
|
#endif
|
strcmp(TelnetFuncList[i].name, command) == 0)
|
return;
|
{
|
|
TelnetFuncList[i].name = (char*)malloc(40);
|
|
strcpy(TelnetFuncList[i].name, command);
|
|
TelnetFuncList[i].func = (ConsoleFunc)funcPtr;
|
|
break;
|
|
}
|
}
|
|
if(run == 0)
|
|
{
|
|
fclose(file);
|
|
return;
|
}
|
}
|
|
|
socket->userFunc = (IPCallbackPtr)socket->funcPtr;
|
socket->fileIn = file; //script file
|
funcPtr(socket, argv);
|
fseek(file, 0, 0);
|
}
|
}
|
|
|
|
|
typedef struct NameValue_t {
|
typedef struct NameValue_t {
|
struct NameValue_t *next;
|
struct NameValue_t *next;
|
void *value;
|
void *value;
|
char name[1];
|
char name[4];
|
} NameValue_t;
|
} NameValue_t;
|
|
|
//Find the value associated with the name
|
//Find the value associated with the name
|
void *IPNameValue(const char *name, void *value)
|
void *IPNameValue(const char *name, void *value)
|
{
|
{
|
static NameValue_t *head;
|
static NameValue_t *head;
|
NameValue_t *node;
|
NameValue_t *node;
|
|
OS_SemaphorePend(semProtect, OS_WAIT_FOREVER);
|
for(node = head; node; node = node->next)
|
for(node = head; node; node = node->next)
|
{
|
{
|
if(strcmp(node->name, name) == 0)
|
if(strcmp(node->name, name) == 0)
|
break;
|
break;
|
}
|
}
|
Line 1096... |
Line 1378... |
node->next = head;
|
node->next = head;
|
head = node;
|
head = node;
|
}
|
}
|
if(value)
|
if(value)
|
node->value = value;
|
node->value = value;
|
|
OS_SemaphorePost(semProtect);
|
return node->value;
|
return node->value;
|
}
|
}
|
#endif
|
#endif
|
|
|
|
|
Line 1110... |
Line 1393... |
static TelnetFunc_t MyFuncs[] = {
|
static TelnetFunc_t MyFuncs[] = {
|
{"cat", ConsoleCat},
|
{"cat", ConsoleCat},
|
{"cp", ConsoleCp},
|
{"cp", ConsoleCp},
|
{"dump", ConsoleDump},
|
{"dump", ConsoleDump},
|
{"exit", ConsoleExit},
|
{"exit", ConsoleExit},
|
#ifdef INCLUDE_FLASH
|
#ifndef EXCLUDE_FLASH
|
{"flashErase", ConsoleFlashErase},
|
{"flashErase", ConsoleFlashErase},
|
#endif
|
#endif
|
{"ftp", ConsoleFtp},
|
{"ftp", ConsoleFtp},
|
{"grep", ConsoleGrep},
|
{"grep", ConsoleGrep},
|
{"help", ConsoleHelp},
|
{"help", ConsoleHelp},
|
{"ls", ConsoleLs},
|
{"ls", ConsoleLs},
|
{"math", ConsoleMath},
|
{"math", ConsoleMath},
|
{"mkdir", ConsoleMkdir},
|
{"mkdir", ConsoleMkdir},
|
{"mkfile", ConsoleMkfile},
|
{"mkfile", ConsoleMkfile},
|
{"ping", ConsolePing},
|
{"ping", ConsolePing},
|
|
{"reboot", ConsoleReboot},
|
{"rm", ConsoleRm},
|
{"rm", ConsoleRm},
|
{"tftp", ConsoleTftp},
|
{"tftp", ConsoleTftp},
|
{"uptime", ConsoleUptime},
|
{"uptime", ConsoleUptime},
|
#ifdef DLL_SETUP
|
#ifndef EXCLUDE_DLL
|
{"run", ConsoleRun},
|
{"run", ConsoleRun},
|
#endif
|
#endif
|
#ifdef EDIT_FILE
|
#ifdef EDIT_FILE
|
{"edit", EditFile},
|
{"edit", EditFile},
|
#endif
|
#endif
|
{"", NULL},
|
|
{"", NULL},
|
|
{"", NULL},
|
|
{"", NULL},
|
|
{"", NULL},
|
|
{"", NULL},
|
|
{"", NULL},
|
|
{"", NULL},
|
|
{"", NULL},
|
|
{"", NULL},
|
|
{"", NULL},
|
|
{NULL, NULL}
|
{NULL, NULL}
|
};
|
};
|
|
|
|
|
void ConsoleInit(void)
|
void ConsoleInit(void)
|