Root/plasma/kernel/netutil.c

1/*--------------------------------------------------------------------
2 * TITLE: Plasma TCP/IP Network Utilities
3 * AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4 * DATE CREATED: 4/20/07
5 * FILENAME: netutil.c
6 * PROJECT: Plasma CPU core
7 * COPYRIGHT: Software placed into the public domain by the author.
8 * Software 'as is' without warranty. Author liable for nothing.
9 * DESCRIPTION:
10 * Plasma FTP server and FTP client and TFTP server and client
11 * and Telnet server.
12 *--------------------------------------------------------------------*/
13#undef INCLUDE_FILESYS
14#define INCLUDE_FILESYS
15#ifdef WIN32
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <ctype.h>
20#define _LIBC
21#endif
22#include "rtos.h"
23#include "tcpip.h"
24
25#ifdef DLL_SETUP
26static void ConsoleRun(IPSocket *socket, char *argv[]);
27#endif
28
29//******************* FTP Server ************************
30typedef struct {
31   IPSocket *socket;
32   int ip, port, bytes, done, canReceive;
33   FILE *file;
34} FtpdInfo;
35
36static void FtpdSender(IPSocket *socket)
37{
38   unsigned char buf[600];
39   int i, bytes, bytes2;
40   FtpdInfo *info = (FtpdInfo*)socket->userPtr;
41
42   if(info == NULL || info->done)
43      return;
44   fseek(info->file, info->bytes, 0);
45   for(i = 0; i < 100000; ++i)
46   {
47      bytes = fread(buf, 1, 512, info->file);
48      bytes2 = IPWrite(socket, buf, bytes);
49      info->bytes += bytes2;
50      if(bytes != bytes2)
51         return;
52      if(bytes < 512)
53      {
54         fclose(info->file);
55         IPClose(socket);
56         info->done = 1;
57         IPPrintf(info->socket, "226 Done\r\n");
58         return;
59      }
60   }
61}
62
63
64static void FtpdReceiver(IPSocket *socket)
65{
66   unsigned char buf[600];
67   int bytes, state = socket->state;
68   FtpdInfo *info = (FtpdInfo*)socket->userPtr;
69
70   if(info == NULL || info->done)
71      return;
72   do
73   {
74      bytes = IPRead(socket, buf, sizeof(buf));
75      fwrite(buf, 1, bytes, info->file);
76   } while(bytes);
77
78   if(state > IP_TCP)
79   {
80      fclose(info->file);
81      info->done = 1;
82      IPPrintf(info->socket, "226 Done\r\n");
83      IPClose(socket);
84      return;
85   }
86}
87
88
89static void FtpdServer(IPSocket *socket)
90{
91   uint8 buf[600];
92   int bytes;
93   int ip0, ip1, ip2, ip3, port0, port1;
94   IPSocket *socketOut;
95   FtpdInfo *info = (FtpdInfo*)socket->userPtr;
96
97   if(socket == NULL)
98      return;
99   bytes = IPRead(socket, buf, sizeof(buf)-1);
100   buf[bytes] = 0;
101   //printf("(%s)\n", buf);
102   if(socket->userPtr == NULL)
103   {
104      info = (FtpdInfo*)malloc(sizeof(FtpdInfo));
105      if(info == NULL)
106         return;
107      memset(info, 0, sizeof(FtpdInfo));
108      socket->userPtr = info;
109      info->socket = socket;
110      socket->timeoutReset = 60;
111      IPPrintf(socket, "220 Connected to Plasma\r\n");
112   }
113   else if(socket->userPtr == (void*)-1)
114   {
115      return;
116   }
117   else if(strstr((char*)buf, "USER"))
118   {
119      if(strstr((char*)buf, "PlasmaSend"))
120         info->canReceive = 1;
121      IPPrintf(socket, "331 Password?\r\n");
122   }
123   else if(strstr((char*)buf, "PASS"))
124   {
125      IPPrintf(socket, "230 Logged in\r\n");
126   }
127   else if(strstr((char*)buf, "PORT"))
128   {
129      sscanf((char*)buf + 5, "%d,%d,%d,%d,%d,%d", &ip0, &ip1, &ip2, &ip3, &port0, &port1);
130      info->ip = (ip0 << 24) | (ip1 << 16) | (ip2 << 8) | ip3;
131      info->port = (port0 << 8) | port1;
132      //printf("ip=0x%x port=%d\n", info->ip, info->port);
133      IPPrintf(socket, "200 OK\r\n");
134   }
135   else if(strstr((char*)buf, "RETR") || strstr((char*)buf, "STOR"))
136   {
137      char *ptr = strstr((char*)buf, "\r");
138      if(ptr)
139         *ptr = 0;
140      info->file = NULL;
141      info->bytes = 0;
142      info->done = 0;
143      if(strstr((char*)buf, "RETR"))
144         info->file = fopen((char*)buf + 5, "rb");
145      else if(info->canReceive)
146         info->file = fopen((char*)buf + 5, "wb");
147      if(info->file)
148      {
149         IPPrintf(socket, "150 File ready\r\n");
150         if(strstr((char*)buf, "RETR"))
151            socketOut = IPOpen(IP_MODE_TCP, info->ip, info->port, FtpdSender);
152         else
153            socketOut = IPOpen(IP_MODE_TCP, info->ip, info->port, FtpdReceiver);
154         if(socketOut)
155            socketOut->userPtr = info;
156      }
157      else
158      {
159         IPPrintf(socket, "500 Error\r\n");
160      }
161   }
162   else if(strstr((char*)buf, "QUIT"))
163   {
164      if(socket->userPtr)
165         free(socket->userPtr);
166      socket->userPtr = (void*)-1;
167      IPPrintf(socket, "221 Bye\r\n");
168      IPClose(socket);
169   }
170   else if(bytes)
171   {
172      IPPrintf(socket, "500 Error\r\n");
173   }
174}
175
176
177void FtpdInit(int UseFiles)
178{
179   (void)UseFiles;
180   IPOpen(IP_MODE_TCP, 0, 21, FtpdServer);
181}
182
183
184//******************* FTP Client ************************
185
186typedef struct {
187   uint32 ip, port;
188   char user[80], passwd[80], filename[80];
189   uint8 *buf;
190   int size, bytes, send, state;
191} FtpInfo;
192
193
194static void FtpCallbackTransfer(IPSocket *socket)
195{
196   int bytes, state = socket->state;
197   FtpInfo *info = (FtpInfo*)socket->userPtr;
198
199   //printf("FtpCallbackTransfer\n");
200   if(info == NULL)
201      return;
202   bytes = info->size - info->bytes;
203   if(info->send == 0)
204      bytes = IPRead(socket, info->buf + info->bytes, bytes);
205   else
206      bytes = IPWrite(socket, info->buf + info->bytes, bytes);
207   info->bytes += bytes;
208   if(info->bytes == info->size || (bytes == 0 && state > IP_TCP))
209   {
210      socket->userFunc(info->buf, info->bytes);
211      free(info);
212      socket->userPtr = NULL;
213      IPClose(socket);
214   }
215}
216
217
218static void FtpCallback(IPSocket *socket)
219{
220   char buf[600];
221   FtpInfo *info = (FtpInfo*)socket->userPtr;
222   int bytes, value;
223
224   bytes = IPRead(socket, (uint8*)buf, sizeof(buf)-1);
225   if(bytes == 0)
226      return;
227   buf[bytes] = 0;
228   sscanf(buf, "%d", &value);
229   if(bytes > 2)
230      buf[bytes-2] = 0;
231   //printf("FtpCallback(%d:%s)\n", socket->userData, buf);
232   if(value / 100 != 2 && value / 100 != 3)
233      return;
234   buf[0] = 0;
235   switch(socket->userData) {
236   case 0:
237      sprintf(buf, "USER %s\r\n", info->user);
238      socket->userData = 1;
239      break;
240   case 1:
241      sprintf(buf, "PASS %s\r\n", info->passwd);
242      socket->userData = 2;
243      if(value == 331)
244         break; //possible fall-through
245   case 2:
246      sprintf(buf, "PORT %d,%d,%d,%d,%d,%d\r\n",
247         info->ip >> 24, (uint8)(info->ip >> 16),
248         (uint8)(info->ip >> 8), (uint8)info->ip,
249         (uint8)(info->port >> 8), (uint8)info->port);
250      socket->userData = 3;
251      break;
252   case 3:
253      if(info->send == 0)
254         sprintf(buf, "RETR %s\r\n", info->filename);
255      else
256         sprintf(buf, "STOR %s\r\n", info->filename);
257      socket->userData = 4;
258      break;
259   case 4:
260      sprintf(buf, "QUIT\r\n");
261      socket->userData = 9;
262      break;
263   }
264   IPWrite(socket, (uint8*)buf, strlen(buf));
265   IPWriteFlush(socket);
266   if(socket->userData == 9)
267      IPClose(socket);
268}
269
270
271IPSocket *FtpTransfer(uint32 ip, char *user, char *passwd,
272                      char *filename, uint8 *buf, int size,
273                      int send, void (*callback)(uint8 *data, int size))
274{
275   IPSocket *socket, *socketTransfer;
276   FtpInfo *info;
277   uint8 *ptr;
278   info = (FtpInfo*)malloc(sizeof(FtpInfo));
279   if(info == NULL)
280      return NULL;
281   strncpy(info->user, user, 80);
282   strncpy(info->passwd, passwd, 80);
283   strncpy(info->filename, filename, 80);
284   info->buf = buf;
285   info->size = size;
286   info->send = send;
287   info->bytes = 0;
288   info->state = 0;
289   info->port = 2000;
290   socketTransfer = IPOpen(IP_MODE_TCP, 0, info->port, FtpCallbackTransfer);
291   socketTransfer->userPtr = info;
292   socketTransfer->userFunc = callback;
293   socket = IPOpen(IP_MODE_TCP, ip, 21, FtpCallback);
294   socket->userPtr = info;
295   socket->userFunc = callback;
296   ptr = socket->headerSend;
297   info->ip = IPAddressSelf();
298   return socket;
299}
300
301
302//******************* TFTP Server ************************
303
304
305static void TftpdCallback(IPSocket *socket)
306{
307   unsigned char buf[512+4];
308   int bytes, blockNum;
309   FILE *file = (FILE*)socket->userPtr;
310   bytes = IPRead(socket, buf, sizeof(buf));
311   //printf("TfptdCallback bytes=%d\n", bytes);
312   if(bytes < 4 || buf[0])
313      return;
314   if(buf[1] == 1) //RRQ = Read Request
315   {
316      if(file)
317         fclose(file);
318      file = fopen((char*)buf+2, "rb");
319      socket->userPtr = file;
320      if(file == NULL)
321      {
322         buf[0] = 0;
323         buf[1] = 5; //ERROR
324         buf[2] = 0;
325         buf[3] = 0;
326         buf[4] = 'X'; //Error string
327         buf[5] = 0;
328         IPWrite(socket, buf, 6);
329         return;
330      }
331   }
332   if(buf[1] == 1 || buf[1] == 4) //ACK
333   {
334      if(file == NULL)
335         return;
336      if(buf[1] == 1)
337         blockNum = 0;
338      else
339         blockNum = (buf[2] << 8) | buf[3];
340      ++blockNum;
341      buf[0] = 0;
342      buf[1] = 3; //DATA
343      buf[2] = (uint8)(blockNum >> 8);
344      buf[3] = (uint8)blockNum;
345      fseek(file, (blockNum-1)*512, 0);
346      bytes = fread(buf+4, 1, 512, file);
347      IPWrite(socket, buf, bytes+4);
348   }
349}
350
351
352void TftpdInit(void)
353{
354   IPSocket *socket;
355   socket = IPOpen(IP_MODE_UDP, 0, 69, TftpdCallback);
356}
357
358
359//******************* TFTP Client ************************
360
361
362static void TftpCallback(IPSocket *socket)
363{
364   unsigned char buf[512+4];
365   int bytes, blockNum, length;
366
367   bytes = IPRead(socket, buf, sizeof(buf));
368   if(bytes < 4 || buf[0])
369      return;
370   blockNum = (buf[2] << 8) | buf[3];
371   length = blockNum * 512 - 512 + bytes - 4;
372   //printf("TftpCallback(%d,%d)\n", buf[1], blockNum);
373   if(length > (int)socket->userData)
374   {
375      bytes -= length - (int)socket->userData;
376      length = (int)socket->userData;
377   }
378   if(buf[1] == 3) //DATA
379   {
380      memcpy((uint8*)socket->userPtr + blockNum * 512 - 512, buf+4, bytes-4);
381      buf[1] = 4; //ACK
382      IPWrite(socket, buf, 4);
383      if(bytes-4 < 512)
384      {
385         socket->userFunc(socket->userPtr, length);
386         IPClose(socket);
387      }
388   }
389}
390
391
392IPSocket *TftpTransfer(uint32 ip, char *filename, uint8 *buffer, int size,
393                       void (*callback)(uint8 *data, int bytes))
394{
395   IPSocket *socket;
396   uint8 buf[512+4];
397   int bytes;
398   socket = IPOpen(IP_MODE_UDP, ip, 69, TftpCallback);
399   socket->userPtr = buffer;
400   socket->userData = size;
401   socket->userFunc = callback;
402   buf[0] = 0;
403   buf[1] = 1; //read
404   strcpy((char*)buf+2, filename);
405   bytes = strlen(filename);
406   strcpy((char*)buf+bytes+3, "octet");
407   IPWrite(socket, buf, bytes+9);
408   return socket;
409}
410
411
412//******************* Telnet Server ************************
413
414#define COMMAND_BUFFER_SIZE 80
415#define COMMAND_BUFFER_COUNT 10
416static char CommandHistory[400];
417static char *CommandPtr[COMMAND_BUFFER_COUNT];
418static int CommandIndex;
419
420typedef void (*ConsoleFunc)(IPSocket *socket, char *argv[]);
421typedef struct {
422   char *name;
423   ConsoleFunc func;
424} TelnetFunc_t;
425static TelnetFunc_t *TelnetFuncList;
426
427
428static void TelnetServer(IPSocket *socket)
429{
430   uint8 buf[COMMAND_BUFFER_SIZE+4];
431   char bufOut[32];
432   int bytes, i, j, k, length, found;
433   char *ptr, *command = socket->userPtr;
434   char *argv[10];
435
436   if(socket->state > IP_TCP)
437      return;
438   for(;;)
439   {
440      bytes = IPRead(socket, buf, sizeof(buf)-1);
441      if(command == NULL)
442      {
443         socket->userPtr = command = (char*)malloc(COMMAND_BUFFER_SIZE);
444         if(command == NULL)
445         {
446            IPClose(socket);
447            return;
448         }
449         socket->timeoutReset = 300;
450         buf[0] = 255; //IAC
451         buf[1] = 251; //WILL
452         buf[2] = 3; //suppress go ahead
453         buf[3] = 255; //IAC
454         buf[4] = 251; //WILL
455         buf[5] = 1; //echo
456         strcpy((char*)buf+6, "Welcome to Plasma.\r\n-> ");
457         IPWrite(socket, buf, 6+23);
458         IPWriteFlush(socket);
459         command[0] = 0;
460         return;
461      }
462      if(bytes == 0)
463         return;
464      socket->dontFlush = 0;
465      buf[bytes] = 0;
466      length = (int)strlen(command);
467      for(j = 0; j < bytes; ++j)
468      {
469         if(buf[j] == 255)
470            return;
471         if(buf[j] == 8 || (buf[j] == 27 && buf[j+2] == 'D'))
472         {
473            if(buf[j] == 27)
474               j += 2;
475            if(length)
476            {
477               // Backspace
478               command[--length] = 0;
479               bufOut[0] = 8;
480               bufOut[1] = ' ';
481               bufOut[2] = 8;
482               IPWrite(socket, (uint8*)bufOut, 3);
483            }
484         }
485         else if(buf[j] == 27)
486         {
487            // Command History
488            if(buf[j+2] == 'A')
489            {
490               if(++CommandIndex > COMMAND_BUFFER_COUNT)
491                  CommandIndex = COMMAND_BUFFER_COUNT;
492            }
493            else if(buf[j+2] == 'B')
494            {
495               if(--CommandIndex < 0)
496                  CommandIndex = 0;
497            }
498            else
499               return;
500            bufOut[0] = 8;
501            bufOut[1] = ' ';
502            bufOut[2] = 8;
503            for(i = 0; i < length; ++i)
504               IPWrite(socket, (uint8*)bufOut, 3);
505            command[0] = 0;
506            if(CommandIndex && CommandPtr[CommandIndex-1])
507               strncat(command, CommandPtr[CommandIndex-1], COMMAND_BUFFER_SIZE-1);
508            length = (int)strlen(command);
509            IPWrite(socket, (uint8*)command, length);
510            j += 2;
511         }
512         else
513         {
514            if(buf[j] == 0)
515               buf[j] = '\n'; //Linux support
516            if(length < COMMAND_BUFFER_SIZE-4 || (length <
517               COMMAND_BUFFER_SIZE-2 && (buf[j] == '\r' || buf[j] == '\n')))
518            {
519               IPWrite(socket, buf+j, 1);
520               command[length] = buf[j];
521               command[++length] = 0;
522            }
523         }
524         ptr = strstr(command, "\r\n");
525         if(ptr)
526         {
527            // Save command in CommandHistory
528            ptr[0] = 0;
529            length = (int)strlen(command);
530            if(length == 0)
531            {
532               IPPrintf(socket, "-> ");
533               continue;
534            }
535            if(length < COMMAND_BUFFER_SIZE)
536            {
537               memmove(CommandHistory + length + 1, CommandHistory,
538                  sizeof(CommandHistory) - length - 1);
539               strcpy(CommandHistory, command);
540               CommandHistory[sizeof(CommandHistory)-1] = 0;
541               for(i = COMMAND_BUFFER_COUNT-2; i >= 0; --i)
542               {
543                  if(CommandPtr[i] == NULL || CommandPtr[i] + length + 1 >=
544                     CommandHistory + sizeof(CommandHistory))
545                     CommandPtr[i+1] = NULL;
546                  else
547                     CommandPtr[i+1] = CommandPtr[i] + length + 1;
548               }
549               CommandPtr[0] = CommandHistory;
550            }
551   
552            //Start command
553            for(i = 0; i < 10; ++i)
554               argv[i] = "";
555            i = 0;
556            argv[i++] = command;
557            for(ptr = command; *ptr && i < 10; ++ptr)
558            {
559               if(*ptr == ' ')
560               {
561                  *ptr = 0;
562                  argv[i++] = ptr + 1;
563               }
564            }
565            if(argv[0][0] == 0)
566            {
567               IPPrintf(socket, "-> ");
568               continue;
569            }
570            found = 0;
571            for(i = 0; TelnetFuncList[i].name; ++i)
572            {
573               if(strcmp(command, TelnetFuncList[i].name) == 0 &&
574                  TelnetFuncList[i].func)
575               {
576                  found = 1;
577                  for(k = 1; k < 10; ++k)
578                  {
579                     if(argv[k][0] == '>' && argv[k][1]) //stdout to file?
580                     {
581                        socket->fileOut = fopen(&argv[k][1], "a");
582                        argv[k] = "";
583                     }
584                     if(argv[k][0] == '<' && argv[k][1]) //stdin from file?
585                     {
586                        socket->fileIn = fopen(&argv[k][1], "r");
587                        argv[k] = "";
588                     }
589                  }
590                  TelnetFuncList[i].func(socket, argv);
591                  if(socket->fileOut)
592                  {
593                     fwrite("\r\n", 1, 2, socket->fileOut);
594                     fclose(socket->fileOut);
595                  }
596                  socket->fileOut = NULL;
597                  break;
598               }
599            }
600#ifdef DLL_SETUP
601            if(found == 0)
602            {
603               strcpy((char*)buf, "/flash/bin/");
604               strcat((char*)buf, argv[0]);
605               argv[0] = (char*)buf;
606               ConsoleRun(socket, argv);
607            }
608#endif
609            if(socket->state > IP_TCP)
610               return;
611            command[0] = 0;
612            length = 0;
613            CommandIndex = 0;
614            if(socket->dontFlush == 0)
615               IPPrintf(socket, "\r\n-> ");
616         } //command entered
617      } //bytes
618      IPWriteFlush(socket);
619   }
620}
621
622
623void TelnetInit(TelnetFunc_t *funcList)
624{
625   IPSocket *socket;
626   TelnetFuncList = funcList;
627   socket = IPOpen(IP_MODE_TCP, 0, 23, TelnetServer);
628}
629
630
631//******************* Console ************************
632
633#define STORAGE_SIZE 1024*64
634static uint8 *myStorage;
635static IPSocket *socketTelnet;
636static char storageFilename[60];
637
638
639static void ConsoleHelp(IPSocket *socket, char *argv[])
640{
641   char buf[200];
642   int i;
643   (void)argv;
644   strcpy(buf, "Commands: ");
645   for(i = 0; TelnetFuncList[i].name; ++i)
646   {
647      if(TelnetFuncList[i].func)
648      {
649         if(i)
650            strcat(buf, ", ");
651         strcat(buf, TelnetFuncList[i].name);
652      }
653   }
654   IPPrintf(socket, buf);
655}
656
657
658static void ConsoleExit(IPSocket *socket, char *argv[])
659{
660   free(argv[0]);
661   socket->userPtr = NULL;
662   IPClose(socket);
663}
664
665
666static void ConsoleCat(IPSocket *socket, char *argv[])
667{
668   FILE *file;
669   uint8 buf[200];
670   int bytes;
671
672   file = fopen(argv[1], "r");
673   if(file == NULL)
674      return;
675   for(;;)
676   {
677      bytes = fread(buf, 1, sizeof(buf), file);
678      if(bytes == 0)
679         break;
680      IPWrite(socket, buf, bytes);
681   }
682   fclose(file);
683}
684
685
686static void ConsoleCp(IPSocket *socket, char *argv[])
687{
688   FILE *fileIn, *fileOut;
689   uint8 buf[200];
690   int bytes;
691   (void)socket;
692
693   fileIn = fopen(argv[1], "r");
694   if(fileIn == NULL)
695      return;
696   fileOut = fopen(argv[2], "w");
697   if(fileOut)
698   {
699      for(;;)
700      {
701         bytes = fread(buf, 1, sizeof(buf), fileIn);
702         if(bytes == 0)
703            break;
704         fwrite(buf, 1, bytes, fileOut);
705      }
706      fclose(fileOut);
707   }
708   fclose(fileIn);
709}
710
711
712static void ConsoleRm(IPSocket *socket, char *argv[])
713{
714   (void)socket;
715   OS_fdelete(argv[1]);
716}
717
718
719static void ConsoleMkdir(IPSocket *socket, char *argv[])
720{
721   (void)socket;
722   OS_fmkdir(argv[1]);
723}
724
725
726static void ConsoleLs(IPSocket *socket, char *argv[])
727{
728   FILE *file;
729   char buf[200], buf2[80];
730   int bytes, width;
731
732   file = fopen(argv[1], "r");
733   if(file == NULL)
734      return;
735   width = 0;
736   for(;;)
737   {
738      bytes = OS_fdir(file, buf);
739      if(bytes)
740         break;
741      if(buf[0] == 255)
742         continue;
743      bytes = OS_flength(buf);
744      sprintf(buf2, "%s:%d ", buf, bytes);
745      bytes = strlen(buf2);
746      bytes -= bytes % 20;
747      buf2[bytes] = 0;
748      width += bytes;
749      if(width == 80)
750         --bytes;
751      if(width > 80)
752      {
753         IPPrintf(socket, "\n");
754         width = bytes;
755      }
756      IPPrintf(socket, "%s", buf2);
757   }
758   fclose(file);
759}
760
761
762#ifdef INCLUDE_FLASH
763static void ConsoleFlashErase(IPSocket *socket, char *argv[])
764{
765   int bytes;
766   (void)argv;
767   IPPrintf(socket, "\r\nErasing");
768   for(bytes = 1024*128; bytes < 1024*1024*16; bytes += 1024*128)
769   {
770      IPPrintf(socket, ".");
771      FlashErase(bytes);
772   }
773   IPPrintf(socket, "\r\nMust Reboot\r\n");
774   OS_ThreadSleep(OS_WAIT_FOREVER);
775}
776#endif
777
778
779static void ConsoleMath(IPSocket *socket, char *argv[])
780{
781   int v1, v2, ch;
782   if(argv[3][0] == 0)
783   {
784      IPPrintf(socket, "Usage: math <number> <operator> <value>\r\n");
785      return;
786   }
787   v1 = atoi(argv[1]);
788   ch = argv[2][0];
789   v2 = atoi(argv[3]);
790   if(ch == '+')
791      v1 += v2;
792   else if(ch == '-')
793      v1 -= v2;
794   else if(ch == '*')
795      v1 *= v2;
796   else if(ch == '/')
797   {
798      if(v2 != 0)
799         v1 /= v2;
800   }
801   IPPrintf(socket, "%d", v1);
802}
803
804
805static void PingCallback(IPSocket *socket)
806{
807   IPSocket *socket2 = socket->userPtr;
808   IPClose(socket);
809   if(socket2)
810      IPPrintf(socket2, "Ping Reply");
811   else
812      printf("Ping Reply\n");
813}
814
815
816static void DnsResultCallback(IPSocket *socket, uint32 ip, void *arg)
817{
818   char buf[COMMAND_BUFFER_SIZE];
819   IPSocket *socketTelnet = arg;
820   IPSocket *socketPing;
821   (void)socket;
822
823   sprintf(buf, "ip=%d.%d.%d.%d\r\n",
824      (uint8)(ip >> 24), (uint8)(ip >> 16), (uint8)(ip >> 8), (uint8)ip);
825   IPPrintf(socketTelnet, buf);
826   socketPing = IPOpen(IP_MODE_PING, ip, 0, PingCallback);
827   socketPing->userPtr = socketTelnet;
828   buf[0] = 'A';
829   IPWrite(socketPing, (uint8*)buf, 1);
830}
831
832
833static void ConsolePing(IPSocket *socket, char *argv[])
834{
835   int ip0, ip1, ip2, ip3;
836
837   if('0' <= argv[1][0] && argv[1][0] <= '9')
838   {
839      sscanf(argv[1], "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3);
840      ip0 = (ip0 << 24) | (ip1 << 16) | (ip2 << 8) | ip3;
841      DnsResultCallback(socket, ip0, socket);
842   }
843   else
844   {
845      IPResolve(argv[1], DnsResultCallback, socket);
846      IPPrintf(socket, "Sent DNS request");
847   }
848}
849
850
851static void ConsoleTransferDone(uint8 *data, int length)
852{
853   FILE *file;
854   IPPrintf(socketTelnet, "Transfer Done");
855   file = fopen(storageFilename, "w");
856   if(file)
857   {
858      fwrite(data, 1, length, file);
859      fclose(file);
860   }
861   if(myStorage)
862      free(myStorage);
863   myStorage = NULL;
864}
865
866
867static void ConsoleFtp(IPSocket *socket, char *argv[])
868{
869   int ip0, ip1, ip2, ip3;
870   if(argv[1][0] == 0)
871   {
872      IPPrintf(socket, "ftp #.#.#.# User Password File");
873      return;
874   }
875   sscanf(argv[1], "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3);
876   ip0 = (ip0 << 24) | (ip1 << 16) | (ip2 << 8) | ip3;
877   socketTelnet = socket;
878   if(myStorage == NULL)
879      myStorage = (uint8*)malloc(STORAGE_SIZE);
880   if(myStorage == NULL)
881      return;
882   strcpy(storageFilename, argv[4]);
883   FtpTransfer(ip0, argv[2], argv[3], argv[4], myStorage, STORAGE_SIZE-1,
884      0, ConsoleTransferDone);
885}
886
887
888static void ConsoleTftp(IPSocket *socket, char *argv[])
889{
890   int ip0, ip1, ip2, ip3;
891   if(argv[1][0] == 0)
892   {
893      IPPrintf(socket, "tftp #.#.#.# File");
894      return;
895   }
896   sscanf(argv[1], "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3);
897   ip0 = (ip0 << 24) | (ip1 << 16) | (ip2 << 8) | ip3;
898   socketTelnet = socket;
899   if(myStorage == NULL)
900      myStorage = (uint8*)malloc(STORAGE_SIZE);
901   if(myStorage == NULL)
902      return;
903   strcpy(storageFilename, argv[2]);
904   TftpTransfer(ip0, argv[2], myStorage, STORAGE_SIZE-1, ConsoleTransferDone);
905}
906
907
908static void ConsoleMkfile(IPSocket *socket, char *argv[])
909{
910   OS_FILE *file;
911   (void)argv;
912   file = fopen("myfile.txt", "w");
913   fwrite("Hello World!", 1, 12, file);
914   fclose(file);
915   IPPrintf(socket, "Created myfile.txt");
916}
917
918
919static void ConsoleUptime(IPSocket *socket, char *argv[])
920{
921   int days, hours, minutes, seconds;
922   (void)argv;
923   //ticks per sec = 25E6/2^18 = 95.36743 -> 10.48576 ms/tick
924   seconds = OS_ThreadTime() / 95;
925   minutes = seconds / 60 % 60;
926   hours = seconds / 3600 % 24;
927   days = seconds / 3600 / 24;
928   seconds %= 60;
929   IPPrintf(socket, "%d days %2d:%2d:%2d\n", days, hours, minutes, seconds);
930}
931
932
933static void ConsoleDump(IPSocket *socket, char *argv[])
934{
935   FILE *fileIn;
936   uint8 buf[16];
937   int bytes, i, j;
938
939   fileIn = fopen(argv[1], "r");
940   if(fileIn == NULL)
941      return;
942   for(j = 0; j < 1024*1024*16; j += 16)
943   {
944      bytes = fread(buf, 1, 16, fileIn);
945      if(bytes == 0)
946         break;
947      IPPrintf(socket, "%8x ", j);
948      for(i = 0; i < bytes; ++i)
949         IPPrintf(socket, "%2x ", buf[i]);
950      for( ; i < 16; ++i)
951         IPPrintf(socket, " ");
952      for(i = 0; i < bytes; ++i)
953      {
954         if(isprint(buf[i]))
955            IPPrintf(socket, "%c", buf[i]);
956         else
957            IPPrintf(socket, ".");
958      }
959      IPPrintf(socket, "\n");
960   }
961   fclose(fileIn);
962}
963
964
965static void ConsoleGrep(IPSocket *socket, char *argv[])
966{
967   FILE *fileIn;
968   char buf[200];
969   int bytes;
970   char *ptr, *ptrEnd;
971
972   if(argv[1][0] == 0 || argv[2][0] == 0)
973   {
974      IPPrintf(socket, "Usage: grep pattern file\n");
975      return;
976   }
977   fileIn = fopen(argv[2], "r");
978   if(fileIn == NULL)
979      return;
980   bytes = 0;
981   for(;;)
982   {
983      bytes += fread(buf + bytes, 1, sizeof(buf) - bytes - 1, fileIn);
984      if(bytes == 0)
985         break;
986      buf[bytes] = 0;
987      ptrEnd = strstr(buf, "\r");
988      if(ptrEnd == NULL)
989         ptrEnd = strstr(buf, "\n");
990      if(ptrEnd)
991      {
992         *ptrEnd = 0;
993         if(*++ptrEnd == '\n')
994            ++ptrEnd;
995      }
996      ptr = strstr(buf, argv[1]);
997      if(ptr)
998         IPPrintf(socket, "%s\n", buf);
999      if(ptrEnd)
1000      {
1001         bytes = strlen(ptrEnd);
1002         memcpy(buf, ptrEnd, bytes);
1003      }
1004      else
1005      {
1006         bytes = 0;
1007      }
1008   }
1009   fclose(fileIn);
1010}
1011
1012
1013#ifdef DLL_SETUP
1014#include "dll.h"
1015
1016static void ConsoleRun(IPSocket *socket, char *argv[])
1017{
1018   FILE *file;
1019   int bytes, i;
1020   uint8 code[128];
1021   DllFunc funcPtr;
1022   char *command, *ptr;
1023
1024   if(strcmp(argv[0], "run") == 0)
1025      ++argv;
1026   file = fopen(argv[0], "r");
1027   if(file == NULL)
1028   {
1029      IPPrintf(socket, "Can't find %s", argv[0]);
1030      return;
1031   }
1032
1033   bytes = fread(code, 1, sizeof(code), file); //load first 128 bytes
1034   if(code[0] >= ' ')
1035   {
1036      socket->fileIn = file; //script file
1037      fseek(file, 0, 0);
1038      return;
1039   }
1040
1041   funcPtr = (DllFunc)code;
1042   ptr = funcPtr(NULL); //determine load address
1043
1044   memcpy(ptr, code, bytes); //copy to correct address
1045   bytes += fread(ptr + bytes, 1, 1024*1024*8, file);
1046   fclose(file);
1047   printf("address=0x%x bytes=%d\n", (int)ptr, bytes);
1048   funcPtr = (DllFunc)ptr;
1049   funcPtr = (DllFunc)funcPtr(DllFuncList); //initialize DLL, find Start()
1050
1051   //Register new command
1052   command = argv[0];
1053   for(;;)
1054   {
1055      ptr = strstr(command, "/");
1056      if(ptr == NULL)
1057         break;
1058      command = ptr + 1;
1059   }
1060   for(i = 0; TelnetFuncList[i].name; ++i)
1061   {
1062      if(TelnetFuncList[i].name[0] == 0 ||
1063         strcmp(TelnetFuncList[i].name, command) == 0)
1064      {
1065         TelnetFuncList[i].name = (char*)malloc(40);
1066         strcpy(TelnetFuncList[i].name, command);
1067         TelnetFuncList[i].func = (ConsoleFunc)funcPtr;
1068         break;
1069      }
1070   }
1071
1072   socket->userFunc = socket->funcPtr;
1073   funcPtr(socket, argv);
1074}
1075
1076
1077typedef struct NameValue_t {
1078   struct NameValue_t *next;
1079   void *value;
1080   char name[1];
1081} NameValue_t;
1082
1083//Find the value associated with the name
1084void *IPNameValue(const char *name, void *value)
1085{
1086   static NameValue_t *head;
1087   NameValue_t *node;
1088   for(node = head; node; node = node->next)
1089   {
1090      if(strcmp(node->name, name) == 0)
1091         break;
1092   }
1093   if(node == NULL)
1094   {
1095      node = (NameValue_t*)malloc(sizeof(NameValue_t) + (int)strlen(name));
1096      if(node == NULL)
1097         return NULL;
1098      strcpy(node->name, name);
1099      node->value = value;
1100      node->next = head;
1101      head = node;
1102   }
1103   if(value)
1104      node->value = value;
1105   return node->value;
1106}
1107#endif
1108
1109
1110#ifdef EDIT_FILE
1111extern void EditFile(IPSocket *socket, char *argv[]);
1112#endif
1113
1114static TelnetFunc_t MyFuncs[] = {
1115   {"cat", ConsoleCat},
1116   {"cp", ConsoleCp},
1117   {"dump", ConsoleDump},
1118   {"exit", ConsoleExit},
1119#ifdef INCLUDE_FLASH
1120   {"flashErase", ConsoleFlashErase},
1121#endif
1122   {"ftp", ConsoleFtp},
1123   {"grep", ConsoleGrep},
1124   {"help", ConsoleHelp},
1125   {"ls", ConsoleLs},
1126   {"math", ConsoleMath},
1127   {"mkdir", ConsoleMkdir},
1128   {"mkfile", ConsoleMkfile},
1129   {"ping", ConsolePing},
1130   {"rm", ConsoleRm},
1131   {"tftp", ConsoleTftp},
1132   {"uptime", ConsoleUptime},
1133#ifdef DLL_SETUP
1134   {"run", ConsoleRun},
1135#endif
1136#ifdef EDIT_FILE
1137   {"edit", EditFile},
1138#endif
1139   {"", NULL},
1140   {"", NULL},
1141   {"", NULL},
1142   {"", NULL},
1143   {"", NULL},
1144   {"", NULL},
1145   {"", NULL},
1146   {"", NULL},
1147   {"", NULL},
1148   {"", NULL},
1149   {"", NULL},
1150   {NULL, NULL}
1151};
1152
1153
1154void ConsoleInit(void)
1155{
1156   FtpdInit(1);
1157   TftpdInit();
1158   TelnetInit(MyFuncs);
1159}
1160

Archive Download this file

Branches:
master



interactive