1
0
mirror of git://projects.qi-hardware.com/nn-usb-fpga.git synced 2024-12-13 23:02:49 +02:00
nn-usb-fpga/plasma/kernel/netutil.c
2010-04-21 20:01:38 -05:00

1160 lines
29 KiB
C

/*--------------------------------------------------------------------
* TITLE: Plasma TCP/IP Network Utilities
* AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
* DATE CREATED: 4/20/07
* FILENAME: netutil.c
* PROJECT: Plasma CPU core
* COPYRIGHT: Software placed into the public domain by the author.
* Software 'as is' without warranty. Author liable for nothing.
* DESCRIPTION:
* Plasma FTP server and FTP client and TFTP server and client
* and Telnet server.
*--------------------------------------------------------------------*/
#undef INCLUDE_FILESYS
#define INCLUDE_FILESYS
#ifdef WIN32
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define _LIBC
#endif
#include "rtos.h"
#include "tcpip.h"
#ifdef DLL_SETUP
static void ConsoleRun(IPSocket *socket, char *argv[]);
#endif
//******************* FTP Server ************************
typedef struct {
IPSocket *socket;
int ip, port, bytes, done, canReceive;
FILE *file;
} FtpdInfo;
static void FtpdSender(IPSocket *socket)
{
unsigned char buf[600];
int i, bytes, bytes2;
FtpdInfo *info = (FtpdInfo*)socket->userPtr;
if(info == NULL || info->done)
return;
fseek(info->file, info->bytes, 0);
for(i = 0; i < 100000; ++i)
{
bytes = fread(buf, 1, 512, info->file);
bytes2 = IPWrite(socket, buf, bytes);
info->bytes += bytes2;
if(bytes != bytes2)
return;
if(bytes < 512)
{
fclose(info->file);
IPClose(socket);
info->done = 1;
IPPrintf(info->socket, "226 Done\r\n");
return;
}
}
}
static void FtpdReceiver(IPSocket *socket)
{
unsigned char buf[600];
int bytes, state = socket->state;
FtpdInfo *info = (FtpdInfo*)socket->userPtr;
if(info == NULL || info->done)
return;
do
{
bytes = IPRead(socket, buf, sizeof(buf));
fwrite(buf, 1, bytes, info->file);
} while(bytes);
if(state > IP_TCP)
{
fclose(info->file);
info->done = 1;
IPPrintf(info->socket, "226 Done\r\n");
IPClose(socket);
return;
}
}
static void FtpdServer(IPSocket *socket)
{
uint8 buf[600];
int bytes;
int ip0, ip1, ip2, ip3, port0, port1;
IPSocket *socketOut;
FtpdInfo *info = (FtpdInfo*)socket->userPtr;
if(socket == NULL)
return;
bytes = IPRead(socket, buf, sizeof(buf)-1);
buf[bytes] = 0;
//printf("(%s)\n", buf);
if(socket->userPtr == NULL)
{
info = (FtpdInfo*)malloc(sizeof(FtpdInfo));
if(info == NULL)
return;
memset(info, 0, sizeof(FtpdInfo));
socket->userPtr = info;
info->socket = socket;
socket->timeoutReset = 60;
IPPrintf(socket, "220 Connected to Plasma\r\n");
}
else if(socket->userPtr == (void*)-1)
{
return;
}
else if(strstr((char*)buf, "USER"))
{
if(strstr((char*)buf, "PlasmaSend"))
info->canReceive = 1;
IPPrintf(socket, "331 Password?\r\n");
}
else if(strstr((char*)buf, "PASS"))
{
IPPrintf(socket, "230 Logged in\r\n");
}
else if(strstr((char*)buf, "PORT"))
{
sscanf((char*)buf + 5, "%d,%d,%d,%d,%d,%d", &ip0, &ip1, &ip2, &ip3, &port0, &port1);
info->ip = (ip0 << 24) | (ip1 << 16) | (ip2 << 8) | ip3;
info->port = (port0 << 8) | port1;
//printf("ip=0x%x port=%d\n", info->ip, info->port);
IPPrintf(socket, "200 OK\r\n");
}
else if(strstr((char*)buf, "RETR") || strstr((char*)buf, "STOR"))
{
char *ptr = strstr((char*)buf, "\r");
if(ptr)
*ptr = 0;
info->file = NULL;
info->bytes = 0;
info->done = 0;
if(strstr((char*)buf, "RETR"))
info->file = fopen((char*)buf + 5, "rb");
else if(info->canReceive)
info->file = fopen((char*)buf + 5, "wb");
if(info->file)
{
IPPrintf(socket, "150 File ready\r\n");
if(strstr((char*)buf, "RETR"))
socketOut = IPOpen(IP_MODE_TCP, info->ip, info->port, FtpdSender);
else
socketOut = IPOpen(IP_MODE_TCP, info->ip, info->port, FtpdReceiver);
if(socketOut)
socketOut->userPtr = info;
}
else
{
IPPrintf(socket, "500 Error\r\n");
}
}
else if(strstr((char*)buf, "QUIT"))
{
if(socket->userPtr)
free(socket->userPtr);
socket->userPtr = (void*)-1;
IPPrintf(socket, "221 Bye\r\n");
IPClose(socket);
}
else if(bytes)
{
IPPrintf(socket, "500 Error\r\n");
}
}
void FtpdInit(int UseFiles)
{
(void)UseFiles;
IPOpen(IP_MODE_TCP, 0, 21, FtpdServer);
}
//******************* FTP Client ************************
typedef struct {
uint32 ip, port;
char user[80], passwd[80], filename[80];
uint8 *buf;
int size, bytes, send, state;
} FtpInfo;
static void FtpCallbackTransfer(IPSocket *socket)
{
int bytes, state = socket->state;
FtpInfo *info = (FtpInfo*)socket->userPtr;
//printf("FtpCallbackTransfer\n");
if(info == NULL)
return;
bytes = info->size - info->bytes;
if(info->send == 0)
bytes = IPRead(socket, info->buf + info->bytes, bytes);
else
bytes = IPWrite(socket, info->buf + info->bytes, bytes);
info->bytes += bytes;
if(info->bytes == info->size || (bytes == 0 && state > IP_TCP))
{
socket->userFunc(info->buf, info->bytes);
free(info);
socket->userPtr = NULL;
IPClose(socket);
}
}
static void FtpCallback(IPSocket *socket)
{
char buf[600];
FtpInfo *info = (FtpInfo*)socket->userPtr;
int bytes, value;
bytes = IPRead(socket, (uint8*)buf, sizeof(buf)-1);
if(bytes == 0)
return;
buf[bytes] = 0;
sscanf(buf, "%d", &value);
if(bytes > 2)
buf[bytes-2] = 0;
//printf("FtpCallback(%d:%s)\n", socket->userData, buf);
if(value / 100 != 2 && value / 100 != 3)
return;
buf[0] = 0;
switch(socket->userData) {
case 0:
sprintf(buf, "USER %s\r\n", info->user);
socket->userData = 1;
break;
case 1:
sprintf(buf, "PASS %s\r\n", info->passwd);
socket->userData = 2;
if(value == 331)
break; //possible fall-through
case 2:
sprintf(buf, "PORT %d,%d,%d,%d,%d,%d\r\n",
info->ip >> 24, (uint8)(info->ip >> 16),
(uint8)(info->ip >> 8), (uint8)info->ip,
(uint8)(info->port >> 8), (uint8)info->port);
socket->userData = 3;
break;
case 3:
if(info->send == 0)
sprintf(buf, "RETR %s\r\n", info->filename);
else
sprintf(buf, "STOR %s\r\n", info->filename);
socket->userData = 4;
break;
case 4:
sprintf(buf, "QUIT\r\n");
socket->userData = 9;
break;
}
IPWrite(socket, (uint8*)buf, strlen(buf));
IPWriteFlush(socket);
if(socket->userData == 9)
IPClose(socket);
}
IPSocket *FtpTransfer(uint32 ip, char *user, char *passwd,
char *filename, uint8 *buf, int size,
int send, void (*callback)(uint8 *data, int size))
{
IPSocket *socket, *socketTransfer;
FtpInfo *info;
uint8 *ptr;
info = (FtpInfo*)malloc(sizeof(FtpInfo));
if(info == NULL)
return NULL;
strncpy(info->user, user, 80);
strncpy(info->passwd, passwd, 80);
strncpy(info->filename, filename, 80);
info->buf = buf;
info->size = size;
info->send = send;
info->bytes = 0;
info->state = 0;
info->port = 2000;
socketTransfer = IPOpen(IP_MODE_TCP, 0, info->port, FtpCallbackTransfer);
socketTransfer->userPtr = info;
socketTransfer->userFunc = callback;
socket = IPOpen(IP_MODE_TCP, ip, 21, FtpCallback);
socket->userPtr = info;
socket->userFunc = callback;
ptr = socket->headerSend;
info->ip = IPAddressSelf();
return socket;
}
//******************* TFTP Server ************************
static void TftpdCallback(IPSocket *socket)
{
unsigned char buf[512+4];
int bytes, blockNum;
FILE *file = (FILE*)socket->userPtr;
bytes = IPRead(socket, buf, sizeof(buf));
//printf("TfptdCallback bytes=%d\n", bytes);
if(bytes < 4 || buf[0])
return;
if(buf[1] == 1) //RRQ = Read Request
{
if(file)
fclose(file);
file = fopen((char*)buf+2, "rb");
socket->userPtr = file;
if(file == NULL)
{
buf[0] = 0;
buf[1] = 5; //ERROR
buf[2] = 0;
buf[3] = 0;
buf[4] = 'X'; //Error string
buf[5] = 0;
IPWrite(socket, buf, 6);
return;
}
}
if(buf[1] == 1 || buf[1] == 4) //ACK
{
if(file == NULL)
return;
if(buf[1] == 1)
blockNum = 0;
else
blockNum = (buf[2] << 8) | buf[3];
++blockNum;
buf[0] = 0;
buf[1] = 3; //DATA
buf[2] = (uint8)(blockNum >> 8);
buf[3] = (uint8)blockNum;
fseek(file, (blockNum-1)*512, 0);
bytes = fread(buf+4, 1, 512, file);
IPWrite(socket, buf, bytes+4);
}
}
void TftpdInit(void)
{
IPSocket *socket;
socket = IPOpen(IP_MODE_UDP, 0, 69, TftpdCallback);
}
//******************* TFTP Client ************************
static void TftpCallback(IPSocket *socket)
{
unsigned char buf[512+4];
int bytes, blockNum, length;
bytes = IPRead(socket, buf, sizeof(buf));
if(bytes < 4 || buf[0])
return;
blockNum = (buf[2] << 8) | buf[3];
length = blockNum * 512 - 512 + bytes - 4;
//printf("TftpCallback(%d,%d)\n", buf[1], blockNum);
if(length > (int)socket->userData)
{
bytes -= length - (int)socket->userData;
length = (int)socket->userData;
}
if(buf[1] == 3) //DATA
{
memcpy((uint8*)socket->userPtr + blockNum * 512 - 512, buf+4, bytes-4);
buf[1] = 4; //ACK
IPWrite(socket, buf, 4);
if(bytes-4 < 512)
{
socket->userFunc(socket->userPtr, length);
IPClose(socket);
}
}
}
IPSocket *TftpTransfer(uint32 ip, char *filename, uint8 *buffer, int size,
void (*callback)(uint8 *data, int bytes))
{
IPSocket *socket;
uint8 buf[512+4];
int bytes;
socket = IPOpen(IP_MODE_UDP, ip, 69, TftpCallback);
socket->userPtr = buffer;
socket->userData = size;
socket->userFunc = callback;
buf[0] = 0;
buf[1] = 1; //read
strcpy((char*)buf+2, filename);
bytes = strlen(filename);
strcpy((char*)buf+bytes+3, "octet");
IPWrite(socket, buf, bytes+9);
return socket;
}
//******************* Telnet Server ************************
#define COMMAND_BUFFER_SIZE 80
#define COMMAND_BUFFER_COUNT 10
static char CommandHistory[400];
static char *CommandPtr[COMMAND_BUFFER_COUNT];
static int CommandIndex;
typedef void (*ConsoleFunc)(IPSocket *socket, char *argv[]);
typedef struct {
char *name;
ConsoleFunc func;
} TelnetFunc_t;
static TelnetFunc_t *TelnetFuncList;
static void TelnetServer(IPSocket *socket)
{
uint8 buf[COMMAND_BUFFER_SIZE+4];
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);
for(j = 0; j < bytes; ++j)
{
if(buf[j] == 255)
return;
if(buf[j] == 8 || (buf[j] == 27 && buf[j+2] == 'D'))
{
if(buf[j] == 27)
j += 2;
if(length)
{
// Backspace
command[--length] = 0;
bufOut[0] = 8;
bufOut[1] = ' ';
bufOut[2] = 8;
IPWrite(socket, (uint8*)bufOut, 3);
}
}
else if(buf[j] == 27)
{
// Command History
if(buf[j+2] == 'A')
{
if(++CommandIndex > COMMAND_BUFFER_COUNT)
CommandIndex = COMMAND_BUFFER_COUNT;
}
else if(buf[j+2] == 'B')
{
if(--CommandIndex < 0)
CommandIndex = 0;
}
else
return;
bufOut[0] = 8;
bufOut[1] = ' ';
bufOut[2] = 8;
for(i = 0; i < length; ++i)
IPWrite(socket, (uint8*)bufOut, 3);
command[0] = 0;
if(CommandIndex && CommandPtr[CommandIndex-1])
strncat(command, CommandPtr[CommandIndex-1], COMMAND_BUFFER_SIZE-1);
length = (int)strlen(command);
IPWrite(socket, (uint8*)command, length);
j += 2;
}
else
{
if(buf[j] == 0)
buf[j] = '\n'; //Linux support
if(length < COMMAND_BUFFER_SIZE-4 || (length <
COMMAND_BUFFER_SIZE-2 && (buf[j] == '\r' || buf[j] == '\n')))
{
IPWrite(socket, buf+j, 1);
command[length] = buf[j];
command[++length] = 0;
}
}
ptr = strstr(command, "\r\n");
if(ptr)
{
// Save command in CommandHistory
ptr[0] = 0;
length = (int)strlen(command);
if(length == 0)
{
IPPrintf(socket, "-> ");
continue;
}
if(length < COMMAND_BUFFER_SIZE)
{
memmove(CommandHistory + length + 1, CommandHistory,
sizeof(CommandHistory) - length - 1);
strcpy(CommandHistory, command);
CommandHistory[sizeof(CommandHistory)-1] = 0;
for(i = COMMAND_BUFFER_COUNT-2; i >= 0; --i)
{
if(CommandPtr[i] == NULL || CommandPtr[i] + length + 1 >=
CommandHistory + sizeof(CommandHistory))
CommandPtr[i+1] = NULL;
else
CommandPtr[i+1] = CommandPtr[i] + length + 1;
}
CommandPtr[0] = CommandHistory;
}
//Start command
for(i = 0; i < 10; ++i)
argv[i] = "";
i = 0;
argv[i++] = command;
for(ptr = command; *ptr && i < 10; ++ptr)
{
if(*ptr == ' ')
{
*ptr = 0;
argv[i++] = ptr + 1;
}
}
if(argv[0][0] == 0)
{
IPPrintf(socket, "-> ");
continue;
}
found = 0;
for(i = 0; TelnetFuncList[i].name; ++i)
{
if(strcmp(command, TelnetFuncList[i].name) == 0 &&
TelnetFuncList[i].func)
{
found = 1;
for(k = 1; k < 10; ++k)
{
if(argv[k][0] == '>' && argv[k][1]) //stdout to file?
{
socket->fileOut = fopen(&argv[k][1], "a");
argv[k] = "";
}
if(argv[k][0] == '<' && argv[k][1]) //stdin from file?
{
socket->fileIn = fopen(&argv[k][1], "r");
argv[k] = "";
}
}
TelnetFuncList[i].func(socket, argv);
if(socket->fileOut)
{
fwrite("\r\n", 1, 2, socket->fileOut);
fclose(socket->fileOut);
}
socket->fileOut = NULL;
break;
}
}
#ifdef DLL_SETUP
if(found == 0)
{
strcpy((char*)buf, "/flash/bin/");
strcat((char*)buf, argv[0]);
argv[0] = (char*)buf;
ConsoleRun(socket, argv);
}
#endif
if(socket->state > IP_TCP)
return;
command[0] = 0;
length = 0;
CommandIndex = 0;
if(socket->dontFlush == 0)
IPPrintf(socket, "\r\n-> ");
} //command entered
} //bytes
IPWriteFlush(socket);
}
}
void TelnetInit(TelnetFunc_t *funcList)
{
IPSocket *socket;
TelnetFuncList = funcList;
socket = IPOpen(IP_MODE_TCP, 0, 23, TelnetServer);
}
//******************* Console ************************
#define STORAGE_SIZE 1024*64
static uint8 *myStorage;
static IPSocket *socketTelnet;
static char storageFilename[60];
static void ConsoleHelp(IPSocket *socket, char *argv[])
{
char buf[200];
int i;
(void)argv;
strcpy(buf, "Commands: ");
for(i = 0; TelnetFuncList[i].name; ++i)
{
if(TelnetFuncList[i].func)
{
if(i)
strcat(buf, ", ");
strcat(buf, TelnetFuncList[i].name);
}
}
IPPrintf(socket, buf);
}
static void ConsoleExit(IPSocket *socket, char *argv[])
{
free(argv[0]);
socket->userPtr = NULL;
IPClose(socket);
}
static void ConsoleCat(IPSocket *socket, char *argv[])
{
FILE *file;
uint8 buf[200];
int bytes;
file = fopen(argv[1], "r");
if(file == NULL)
return;
for(;;)
{
bytes = fread(buf, 1, sizeof(buf), file);
if(bytes == 0)
break;
IPWrite(socket, buf, bytes);
}
fclose(file);
}
static void ConsoleCp(IPSocket *socket, char *argv[])
{
FILE *fileIn, *fileOut;
uint8 buf[200];
int bytes;
(void)socket;
fileIn = fopen(argv[1], "r");
if(fileIn == NULL)
return;
fileOut = fopen(argv[2], "w");
if(fileOut)
{
for(;;)
{
bytes = fread(buf, 1, sizeof(buf), fileIn);
if(bytes == 0)
break;
fwrite(buf, 1, bytes, fileOut);
}
fclose(fileOut);
}
fclose(fileIn);
}
static void ConsoleRm(IPSocket *socket, char *argv[])
{
(void)socket;
OS_fdelete(argv[1]);
}
static void ConsoleMkdir(IPSocket *socket, char *argv[])
{
(void)socket;
OS_fmkdir(argv[1]);
}
static void ConsoleLs(IPSocket *socket, char *argv[])
{
FILE *file;
char buf[200], buf2[80];
int bytes, width;
file = fopen(argv[1], "r");
if(file == NULL)
return;
width = 0;
for(;;)
{
bytes = OS_fdir(file, buf);
if(bytes)
break;
if(buf[0] == 255)
continue;
bytes = OS_flength(buf);
sprintf(buf2, "%s:%d ", buf, bytes);
bytes = strlen(buf2);
bytes -= bytes % 20;
buf2[bytes] = 0;
width += bytes;
if(width == 80)
--bytes;
if(width > 80)
{
IPPrintf(socket, "\n");
width = bytes;
}
IPPrintf(socket, "%s", buf2);
}
fclose(file);
}
#ifdef INCLUDE_FLASH
static void ConsoleFlashErase(IPSocket *socket, char *argv[])
{
int bytes;
(void)argv;
IPPrintf(socket, "\r\nErasing");
for(bytes = 1024*128; bytes < 1024*1024*16; bytes += 1024*128)
{
IPPrintf(socket, ".");
FlashErase(bytes);
}
IPPrintf(socket, "\r\nMust Reboot\r\n");
OS_ThreadSleep(OS_WAIT_FOREVER);
}
#endif
static void ConsoleMath(IPSocket *socket, char *argv[])
{
int v1, v2, ch;
if(argv[3][0] == 0)
{
IPPrintf(socket, "Usage: math <number> <operator> <value>\r\n");
return;
}
v1 = atoi(argv[1]);
ch = argv[2][0];
v2 = atoi(argv[3]);
if(ch == '+')
v1 += v2;
else if(ch == '-')
v1 -= v2;
else if(ch == '*')
v1 *= v2;
else if(ch == '/')
{
if(v2 != 0)
v1 /= v2;
}
IPPrintf(socket, "%d", v1);
}
static void PingCallback(IPSocket *socket)
{
IPSocket *socket2 = socket->userPtr;
IPClose(socket);
if(socket2)
IPPrintf(socket2, "Ping Reply");
else
printf("Ping Reply\n");
}
static void DnsResultCallback(IPSocket *socket, uint32 ip, void *arg)
{
char buf[COMMAND_BUFFER_SIZE];
IPSocket *socketTelnet = arg;
IPSocket *socketPing;
(void)socket;
sprintf(buf, "ip=%d.%d.%d.%d\r\n",
(uint8)(ip >> 24), (uint8)(ip >> 16), (uint8)(ip >> 8), (uint8)ip);
IPPrintf(socketTelnet, buf);
socketPing = IPOpen(IP_MODE_PING, ip, 0, PingCallback);
socketPing->userPtr = socketTelnet;
buf[0] = 'A';
IPWrite(socketPing, (uint8*)buf, 1);
}
static void ConsolePing(IPSocket *socket, char *argv[])
{
int ip0, ip1, ip2, ip3;
if('0' <= argv[1][0] && argv[1][0] <= '9')
{
sscanf(argv[1], "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3);
ip0 = (ip0 << 24) | (ip1 << 16) | (ip2 << 8) | ip3;
DnsResultCallback(socket, ip0, socket);
}
else
{
IPResolve(argv[1], DnsResultCallback, socket);
IPPrintf(socket, "Sent DNS request");
}
}
static void ConsoleTransferDone(uint8 *data, int length)
{
FILE *file;
IPPrintf(socketTelnet, "Transfer Done");
file = fopen(storageFilename, "w");
if(file)
{
fwrite(data, 1, length, file);
fclose(file);
}
if(myStorage)
free(myStorage);
myStorage = NULL;
}
static void ConsoleFtp(IPSocket *socket, char *argv[])
{
int ip0, ip1, ip2, ip3;
if(argv[1][0] == 0)
{
IPPrintf(socket, "ftp #.#.#.# User Password File");
return;
}
sscanf(argv[1], "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3);
ip0 = (ip0 << 24) | (ip1 << 16) | (ip2 << 8) | ip3;
socketTelnet = socket;
if(myStorage == NULL)
myStorage = (uint8*)malloc(STORAGE_SIZE);
if(myStorage == NULL)
return;
strcpy(storageFilename, argv[4]);
FtpTransfer(ip0, argv[2], argv[3], argv[4], myStorage, STORAGE_SIZE-1,
0, ConsoleTransferDone);
}
static void ConsoleTftp(IPSocket *socket, char *argv[])
{
int ip0, ip1, ip2, ip3;
if(argv[1][0] == 0)
{
IPPrintf(socket, "tftp #.#.#.# File");
return;
}
sscanf(argv[1], "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3);
ip0 = (ip0 << 24) | (ip1 << 16) | (ip2 << 8) | ip3;
socketTelnet = socket;
if(myStorage == NULL)
myStorage = (uint8*)malloc(STORAGE_SIZE);
if(myStorage == NULL)
return;
strcpy(storageFilename, argv[2]);
TftpTransfer(ip0, argv[2], myStorage, STORAGE_SIZE-1, ConsoleTransferDone);
}
static void ConsoleMkfile(IPSocket *socket, char *argv[])
{
OS_FILE *file;
(void)argv;
file = fopen("myfile.txt", "w");
fwrite("Hello World!", 1, 12, file);
fclose(file);
IPPrintf(socket, "Created myfile.txt");
}
static void ConsoleUptime(IPSocket *socket, char *argv[])
{
int days, hours, minutes, seconds;
(void)argv;
//ticks per sec = 25E6/2^18 = 95.36743 -> 10.48576 ms/tick
seconds = OS_ThreadTime() / 95;
minutes = seconds / 60 % 60;
hours = seconds / 3600 % 24;
days = seconds / 3600 / 24;
seconds %= 60;
IPPrintf(socket, "%d days %2d:%2d:%2d\n", days, hours, minutes, seconds);
}
static void ConsoleDump(IPSocket *socket, char *argv[])
{
FILE *fileIn;
uint8 buf[16];
int bytes, i, j;
fileIn = fopen(argv[1], "r");
if(fileIn == NULL)
return;
for(j = 0; j < 1024*1024*16; j += 16)
{
bytes = fread(buf, 1, 16, fileIn);
if(bytes == 0)
break;
IPPrintf(socket, "%8x ", j);
for(i = 0; i < bytes; ++i)
IPPrintf(socket, "%2x ", buf[i]);
for( ; i < 16; ++i)
IPPrintf(socket, " ");
for(i = 0; i < bytes; ++i)
{
if(isprint(buf[i]))
IPPrintf(socket, "%c", buf[i]);
else
IPPrintf(socket, ".");
}
IPPrintf(socket, "\n");
}
fclose(fileIn);
}
static void ConsoleGrep(IPSocket *socket, char *argv[])
{
FILE *fileIn;
char buf[200];
int bytes;
char *ptr, *ptrEnd;
if(argv[1][0] == 0 || argv[2][0] == 0)
{
IPPrintf(socket, "Usage: grep pattern file\n");
return;
}
fileIn = fopen(argv[2], "r");
if(fileIn == NULL)
return;
bytes = 0;
for(;;)
{
bytes += fread(buf + bytes, 1, sizeof(buf) - bytes - 1, fileIn);
if(bytes == 0)
break;
buf[bytes] = 0;
ptrEnd = strstr(buf, "\r");
if(ptrEnd == NULL)
ptrEnd = strstr(buf, "\n");
if(ptrEnd)
{
*ptrEnd = 0;
if(*++ptrEnd == '\n')
++ptrEnd;
}
ptr = strstr(buf, argv[1]);
if(ptr)
IPPrintf(socket, "%s\n", buf);
if(ptrEnd)
{
bytes = strlen(ptrEnd);
memcpy(buf, ptrEnd, bytes);
}
else
{
bytes = 0;
}
}
fclose(fileIn);
}
#ifdef DLL_SETUP
#include "dll.h"
static void ConsoleRun(IPSocket *socket, char *argv[])
{
FILE *file;
int bytes, i;
uint8 code[128];
DllFunc funcPtr;
char *command, *ptr;
if(strcmp(argv[0], "run") == 0)
++argv;
file = fopen(argv[0], "r");
if(file == NULL)
{
IPPrintf(socket, "Can't find %s", argv[0]);
return;
}
bytes = fread(code, 1, sizeof(code), file); //load first 128 bytes
if(code[0] >= ' ')
{
socket->fileIn = file; //script file
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);
printf("address=0x%x bytes=%d\n", (int)ptr, bytes);
funcPtr = (DllFunc)ptr;
funcPtr = (DllFunc)funcPtr(DllFuncList); //initialize DLL, find Start()
//Register new command
command = argv[0];
for(;;)
{
ptr = strstr(command, "/");
if(ptr == NULL)
break;
command = ptr + 1;
}
for(i = 0; TelnetFuncList[i].name; ++i)
{
if(TelnetFuncList[i].name[0] == 0 ||
strcmp(TelnetFuncList[i].name, command) == 0)
{
TelnetFuncList[i].name = (char*)malloc(40);
strcpy(TelnetFuncList[i].name, command);
TelnetFuncList[i].func = (ConsoleFunc)funcPtr;
break;
}
}
socket->userFunc = socket->funcPtr;
funcPtr(socket, argv);
}
typedef struct NameValue_t {
struct NameValue_t *next;
void *value;
char name[1];
} NameValue_t;
//Find the value associated with the name
void *IPNameValue(const char *name, void *value)
{
static NameValue_t *head;
NameValue_t *node;
for(node = head; node; node = node->next)
{
if(strcmp(node->name, name) == 0)
break;
}
if(node == NULL)
{
node = (NameValue_t*)malloc(sizeof(NameValue_t) + (int)strlen(name));
if(node == NULL)
return NULL;
strcpy(node->name, name);
node->value = value;
node->next = head;
head = node;
}
if(value)
node->value = value;
return node->value;
}
#endif
#ifdef EDIT_FILE
extern void EditFile(IPSocket *socket, char *argv[]);
#endif
static TelnetFunc_t MyFuncs[] = {
{"cat", ConsoleCat},
{"cp", ConsoleCp},
{"dump", ConsoleDump},
{"exit", ConsoleExit},
#ifdef INCLUDE_FLASH
{"flashErase", ConsoleFlashErase},
#endif
{"ftp", ConsoleFtp},
{"grep", ConsoleGrep},
{"help", ConsoleHelp},
{"ls", ConsoleLs},
{"math", ConsoleMath},
{"mkdir", ConsoleMkdir},
{"mkfile", ConsoleMkfile},
{"ping", ConsolePing},
{"rm", ConsoleRm},
{"tftp", ConsoleTftp},
{"uptime", ConsoleUptime},
#ifdef DLL_SETUP
{"run", ConsoleRun},
#endif
#ifdef EDIT_FILE
{"edit", EditFile},
#endif
{"", NULL},
{"", NULL},
{"", NULL},
{"", NULL},
{"", NULL},
{"", NULL},
{"", NULL},
{"", NULL},
{"", NULL},
{"", NULL},
{"", NULL},
{NULL, NULL}
};
void ConsoleInit(void)
{
FtpdInit(1);
TftpdInit();
TelnetInit(MyFuncs);
}