From b7d9a67870635afaec2eee9bea079ba684d81fa6 Mon Sep 17 00:00:00 2001 From: patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> Date: Sat, 6 Sep 2008 00:16:09 +0000 Subject: [PATCH] Add get and put commands to NSH git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@880 42af7a65-404d-4744-a932-0658087f49c3 --- ChangeLog | 1 + Documentation/NuttShell.html | 178 ++++++++++++++++++++++------- Documentation/NuttX.html | 1 + examples/nsh/README.txt | 26 +++++ examples/nsh/nsh.h | 10 +- examples/nsh/nsh_main.c | 8 +- examples/nsh/nsh_netcmds.c | 212 ++++++++++++++++++++++++++++++++++- netutils/tftpc/tftpc_get.c | 2 +- netutils/tftpc/tftpc_put.c | 3 +- 9 files changed, 390 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index f35cef7ead..a3ebf96e79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -450,4 +450,5 @@ * Correct IP checksum calculation in ICMP and UDP message send logic. * NSH: Created an HTML document and a more detailed README file describing NSH. * Added basic TFTP client logic (netutils/tftpc). Untested as of initial check-in. + * NSH: Add get and put commands to support TFTP get and put operations. diff --git a/Documentation/NuttShell.html b/Documentation/NuttShell.html index c689cbb468..e9d363dc97 100644 --- a/Documentation/NuttShell.html +++ b/Documentation/NuttShell.html @@ -8,7 +8,7 @@ <tr align="center" bgcolor="#e4e4e4"> <td> <h1><big><font color="#3c34ec"><i>NuttShell (NSH)</i></font></big></h1> - <p>Last Updated: September 3, 2008</p> + <p>Last Updated: September 5, 2008</p> </td> </tr> </table> @@ -113,127 +113,139 @@ <tr> <td><br></td> <td> - <a href="#cmdexit">2.7 Exit NSH (exit)</a> + <a href="#cmdget">2.7 Get File Via TFTP (get)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdhelp">2.8 Show Usage Command Usage (help)</a> + <a href="#cmdexit">2.8 Exit NSH (exit)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdifconfig">2.9 Show Network Configuration (ifconfig)</a> + <a href="#cmdhelp">2.9 Show Usage Command Usage (help)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdls">2.10 List Directory Contents (ls)</a> + <a href="#cmdifconfig">2.10 Show Network Configuration (ifconfig)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdmbhw">2.11 Access Memory (mb, mh, and mw)</a> + <a href="#cmdls">2.11 List Directory Contents (ls)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdmem">2.12 Show Memory Manager Status (mem)</a> + <a href="#cmdmbhw">2.12 Access Memory (mb, mh, and mw)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdps">2.13 Show Current Tasks and Threads (ps)</a> + <a href="#cmdmem">2.13 Show Memory Manager Status (mem)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdmkdir">2.14 Create a Directory (mkdir)</a> + <a href="#cmdps">2.14 Show Current Tasks and Threads (ps)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdmkfatfs">2.15 Create a FAT Filesystem (mkfatfs)</a> + <a href="#cmdmkdir">2.15 Create a Directory (mkdir)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdmkfifo">2.16 Create a FIFO (mkfifo)</a> + <a href="#cmdmkfatfs">2.16 Create a FAT Filesystem (mkfatfs)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdmount">2.17 Mount a File System (mount)</a> + <a href="#cmdmkfifo">2.17 Create a FIFO (mkfifo)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdping">2.18 Check Network Peer (ping)</a> + <a href="#cmdmount">2.18 Mount a File System (mount)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdpwd">2.19 Show Current Working Directory (pwd)</a> + <a href="#cmdping">2.19 Check Network Peer (ping)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdrm">2.20 Remove a File (rm)</a> + <a href="#cmdput">2.20 Send File Via TFTP (put)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdrmdir">2.21 Remove a Directory (rmdir)</a> + <a href="#cmdpwd">2.21 Show Current Working Directory (pwd)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdset">2.22 Set an Environment Variable (set)</a> + <a href="#cmdrm">2.22 Remove a File (rm)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdsh">2.23 Execute an NSH Script (sh)</a> + <a href="#cmdrmdir">2.23 Remove a Directory (rmdir)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdsleep">2.24 Wait for Seconds (sleep)</a> + <a href="#cmdset">2.24 Set an Environment Variable (set)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdunmount">2.25 Unmount a File System (umount)</a> + <a href="#cmdsh">2.25 Execute an NSH Script (sh)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdunset">2.26 Unset an Environment Variable (unset)</a> + <a href="#cmdsleep">2.26 Wait for Seconds (sleep)</a> </td> </tr> <tr> <td><br></td> <td> - <a href="#cmdusleep">2.27 Wait for Microseconds (usleep)</a> + <a href="#cmdunmount">2.27 Unmount a File System (umount)</a> + </td> +</tr> +<tr> + <td><br></td> + <td> + <a href="#cmdunset">2.28 Unset an Environment Variable (unset)</a> + </td> +</tr> +<tr> + <td><br></td> + <td> + <a href="#cmdusleep">2.29 Wait for Microseconds (usleep)</a> </td> </tr> <tr> @@ -621,7 +633,42 @@ exec <hex-address> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdexit"><h2>2.7 Exit NSH (exit)</h2></a> + <a name="cmdget"><h2>2.7 Get File Via TFTP (get)</h2></a> + </td> + </tr> +</table> + +<a <p><b>Command Syntax:</b></p> +<ul><pre> +get [-b|-n] [-f <local-path>] -h <ip-address> <remote-path> +</pre></ul> +<p> + <b>Synopsis</b>. + Copy the file at <code><remote-address></code> from the host whose IP address is + identified by <code><ip-address></code>. +</p> +<p><b>Other options:</b></p> +<ul><table> + <tr> + <td><b><code>-f <local-path></code></b></td> + <td> + The file will be saved relative to the current working directory + unless <code><local-path></code> is provided. + </td> + </tr> + <tr> + <td><b><code>-b|-n</code></b></td> + <td> + Selects either binary ("octect") or test ("netascii") transfer + mode. Default: text. + </td> + </tr> +</table></ul> + +<table width ="100%"> + <tr bgcolor="#e4e4e4"> + <td> + <a name="cmdexit"><h2>2.8 Exit NSH (exit)</h2></a> </td> </tr> </table> @@ -640,7 +687,7 @@ exit <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdhelp"><h2>2.8 Show Usage Command Usage (help)</h2></a> + <a name="cmdhelp"><h2>2.9 Show Usage Command Usage (help)</h2></a> </td> </tr> </table> @@ -657,7 +704,7 @@ help <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdifconfig"><h2>2.9 Show Network Configuration (ifconfig)</h2></a> + <a name="cmdifconfig"><h2>2.10 Show Network Configuration (ifconfig)</h2></a> </td> </tr> </table> @@ -683,7 +730,7 @@ eth0 HWaddr 00:18:11:80:10:06 <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdls"><h2>2.10 List Directory Contents (ls)</h2></a> + <a name="cmdls"><h2>2.11 List Directory Contents (ls)</h2></a> </td> </tr> </table> @@ -720,7 +767,7 @@ ls [-lRs] <dir-path> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdmbhw"><h2>2.11 Access Memory (mb, mh, and mw)</h2></a> + <a name="cmdmbhw"><h2>2.12 Access Memory (mb, mh, and mw)</h2></a> </td> </tr> </table> @@ -774,7 +821,7 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdmem"><h2>2.12 Show Memory Manager Status (mem)</h2></a> + <a name="cmdmem"><h2>2.13 Show Memory Manager Status (mem)</h2></a> </td> </tr> </table> @@ -823,7 +870,7 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdps"><h2>2.13 Show Current Tasks and Threads (ps)</h2></a> + <a name="cmdps"><h2>2.14 Show Current Tasks and Threads (ps)</h2></a> </td> </tr> </table> @@ -849,7 +896,7 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdmkdir"><h2>2.14 Create a Directory (mkdir)</h2></a> + <a name="cmdmkdir"><h2>2.15 Create a Directory (mkdir)</h2></a> </td> </tr> </table> @@ -884,7 +931,7 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdmkfatfs"><h2>2.15 Create a FAT Filesystem (mkfatfs)</h2></a> + <a name="cmdmkfatfs"><h2>2.16 Create a FAT Filesystem (mkfatfs)</h2></a> </td> </tr> </table> @@ -904,7 +951,7 @@ mkfatfs <path> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdmkfifo"><h2>2.16 Create a FIFO (mkfifo)</h2></a> + <a name="cmdmkfifo"><h2>2.17 Create a FIFO (mkfifo)</h2></a> </td> </tr> </table> @@ -942,7 +989,7 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdmount"><h2>2.17 Mount a File System (mount)</h2></a> + <a name="cmdmount"><h2>2.18 Mount a File System (mount)</h2></a> </td> </tr> </table> @@ -1009,7 +1056,7 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdping"><h2>2.18 Check Network Peer (ping)</h2></a> + <a name="cmdping"><h2>2.19 Check Network Peer (ping)</h2></a> </td> </tr> </table> @@ -1042,7 +1089,42 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdpwd"><h2>2.19 Show Current Working Directory (pwd)</h2></a> + <a name="cmdput"><h2>2.20 Send File Via TFTP (put)</h2></a> + </td> + </tr> +</table> + +<a <p><b>Command Syntax:</b></p> +<ul><pre> +put [-b|-n] [-f <remote-path>] -h <ip-address> <local-path> +</pre></ul> +<p> + <b>Synopsis</b>. + Copy the file at <code><local-address></code> to the host whose IP address is + identified by <code><ip-address></code>. +</p> +<p><b>Other options:</b></p> +<ul><table> + <tr> + <td><b><code>-f <remote-path></code></b></td> + <td> + The file will be saved relative with the same name on the host + unless <code><remote-path></code> is provided. + </td> + </tr> + <tr> + <td><b><code>-b|-n</code></b></td> + <td> + Selects either binary ("octect") or test ("netascii") transfer + mode. Default: text. + </td> + </tr> +</table></ul> + +<table width ="100%"> + <tr bgcolor="#e4e4e4"> + <td> + <a name="cmdpwd"><h2>2.21 Show Current Working Directory (pwd)</h2></a> </td> </tr> </table> @@ -1072,7 +1154,7 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdrm"><h2>2.20 Remove a File (rm)</h2></a> + <a name="cmdrm"><h2>2.22 Remove a File (rm)</h2></a> </td> </tr> </table> @@ -1106,7 +1188,7 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdrmdir"><h2>2.21 Remove a Directory (rmdir)</h2></a> + <a name="cmdrmdir"><h2>2.23 Remove a Directory (rmdir)</h2></a> </td> </tr> </table> @@ -1141,7 +1223,7 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdset"><h2>2.22 Set an Environment Variable (set)</h2></a> + <a name="cmdset"><h2>2.24 Set an Environment Variable (set)</h2></a> </td> </tr> </table> @@ -1167,7 +1249,7 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdsh"><h2>2.23 Execute an NSH Script (sh)</h2></a> + <a name="cmdsh"><h2>2.25 Execute an NSH Script (sh)</h2></a> </td> </tr> </table> @@ -1185,7 +1267,7 @@ sh <script-path> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdsleep"><h2>2.24 Wait for Seconds (sleep)</h2></a> + <a name="cmdsleep"><h2>2.26 Wait for Seconds (sleep)</h2></a> </td> </tr> </table> @@ -1202,7 +1284,7 @@ sleep <sec> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdunmount"><h2>2.25 Unmount a File System (umount)</h2></a> + <a name="cmdunmount"><h2>2.27 Unmount a File System (umount)</h2></a> </td> </tr> </table> @@ -1232,7 +1314,7 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdunset"><h2>2.26 Unset an Environment Variable (unset)</h2></a> + <a name="cmdunset"><h2>2.28 Unset an Environment Variable (unset)</h2></a> </td> </tr> </table> @@ -1258,7 +1340,7 @@ nsh> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdusleep"><h2>2.27 Wait for Microseconds (usleep)</h2></a> + <a name="cmdusleep"><h2>2.29 Wait for Microseconds (usleep)</h2></a> </td> </tr> </table> @@ -1331,6 +1413,10 @@ usleep <usec> <td><b><code>exit</code></b></td> <td><br></td> </tr> + <tr> + <td><b><code>get</code></b></td> + <td><code>CONFIG_NET</code> && <code>CONFIG_NET_UDP</code> && <code>CONFIG_NFILE_DESCRIPTORS</code> > 0</td> + </tr> <tr> <td><b><code>help</code></b></td> <td><br></td> @@ -1375,6 +1461,10 @@ usleep <usec> <td><b><code>ps</code></b></td> <td><br></td> </tr> + <tr> + <td><b><code>put</code></b></td> + <td><code>CONFIG_NET</code> && <code>CONFIG_NET_UDP</code> && <code>CONFIG_NFILE_DESCRIPTORS</code> > 0</td> + </tr> <tr> <td><b><code>pwd</code></b></td> <td>!<code>CONFIG_DISABLE_ENVIRON</code> && <code>CONFIG_NFILE_DESCRIPTORS</code> > 0</td> @@ -1602,6 +1692,7 @@ usleep <usec> <li><a href="#environvars">Environment Variables</a></li> <li><a href="#cmdexec"><code>exec</code></a></li> <li><a href="#cmdexit"><code>exit</code></a></li> + <li><a href="#cmdget"><code>get</code></a></li> </ul></td> <td></ul> <li><a href="#frontend">Greeting</a></li> @@ -1623,6 +1714,7 @@ usleep <usec> <li><a href="#cmdping"><code>ping</code></a></li> <li><a href="#frontend">Prompt</a></li> <li><a href="#cmdps"><code>ps</code></a></li> + <li><a href="#cmdput"><code>put</code></a></li> <li><a href="#cmdpwd"><code>pwd</code></a></li> <li><a href="#environvars"><code>PWD</code></a></li> <li><a href="#cmdoverview">Re-directed commands</a></li> diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html index d8edf1eb2c..2e936dee9e 100644 --- a/Documentation/NuttX.html +++ b/Documentation/NuttX.html @@ -1077,6 +1077,7 @@ nuttx-0.3.14 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> * Correct IP checksum calculation in ICMP and UDP message send logic. * NSH: Created an HTML document and a more detailed README file describing NSH. * Added basic TFTP client logic (netutils/tftpc). Untested as of initial check-in. + * NSH: Add get and put commands to support TFTP get and put operations. pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> diff --git a/examples/nsh/README.txt b/examples/nsh/README.txt index 366be8a3ce..fd0c4884b2 100644 --- a/examples/nsh/README.txt +++ b/examples/nsh/README.txt @@ -173,6 +173,18 @@ o exit using the 'exec' command') and you would like to have NSH out of the way. +o get [-b|-n] [-f <local-path>] -h <ip-address> <remote-path> + + Copy the file at <remote-address> from the host whose IP address is + identified by <ip-address>. Other options: + + -f <local-path> + The file will be saved relative to the current working directory + unless <local-path> is provided. + -b|-n + Selects either binary ("octect") or test ("netascii") transfer + mode. Default: text. + o help Presents summary information about each command to console. @@ -393,6 +405,18 @@ o ping [-c <count>] [-i <interval>] <ip-address> 10 packets transmitted, 10 received, 0% packet loss, time 10190 ms nsh> +o put [-b|-n] [-f <remote-path>] -h <ip-address> <local-path> + + Copy the file at <local-address> to the host whose IP address is + identified by <ip-address>. Other options: + + -f <remote-path> + The file will be saved with the same name on the host unless + unless <local-path> is provided. + -b|-n + Selects either binary ("octect") or test ("netascii") transfer + mode. Default: text. + o pwd Show the current working directory. @@ -511,6 +535,7 @@ Command Dependencies on Configuration Settings echo -- exec -- exit -- + get CONFIG_NET && CONFIG_NET_UDP && CONFIG_NFILE_DESCRIPTORS > 0 help -- ifconfig CONFIG_NET ls CONFIG_NFILE_DESCRIPTORS > 0 @@ -522,6 +547,7 @@ Command Dependencies on Configuration Settings mount !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_FAT ping CONFIG_NET && CONFIG_NET_ICMP && CONFIG_NET_ICMP_PING && !CONFIG_DISABLE_CLOCK && !CONFIG_DISABLE_SIGNALS ps -- + put CONFIG_NET && CONFIG_NET_UDP && CONFIG_NFILE_DESCRIPTORS > 0 pwd !CONFIG_DISABLE_ENVIRON && CONFIG_NFILE_DESCRIPTORS > 0 rm !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 rmdir !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 diff --git a/examples/nsh/nsh.h b/examples/nsh/nsh.h index 861be30c2d..f468a264a4 100644 --- a/examples/nsh/nsh.h +++ b/examples/nsh/nsh.h @@ -73,9 +73,11 @@ */ #ifdef CONFIG_EXAMPLES_NSH_STRERROR -# define NSH_ERRNO strerror(errno) +# define NSH_ERRNO strerror(errno) +# define NSH_ERRNO_OF(err) strerror(err) #else -# define NSH_ERRNO errno +# define NSH_ERRNO (errno) +# define NSH_ERRNO_OF(err) (err) #endif /* Maximum size of one command line (telnet or serial) */ @@ -298,6 +300,10 @@ extern int cmd_lbracket(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #if defined(CONFIG_NET) extern int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0 + extern int cmd_get(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); + extern int cmd_put(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif #if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) && \ !defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_DISABLE_SIGNALS) extern int cmd_ping(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); diff --git a/examples/nsh/nsh_main.c b/examples/nsh/nsh_main.c index ba7ad389fc..f2890159c6 100644 --- a/examples/nsh/nsh_main.c +++ b/examples/nsh/nsh_main.c @@ -145,6 +145,9 @@ static const struct cmdmap_s g_cmdmap[] = #endif { "exec", cmd_exec, 2, 3, "<hex-address>" }, { "exit", cmd_exit, 1, 1, NULL }, +#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0 + { "get", cmd_get, 4, 7, "[-b|-n] [-f <local-path>] -h <ip-address> <remote-path>" }, +#endif { "help", cmd_help, 1, 1, NULL }, #ifdef CONFIG_NET { "ifconfig", cmd_ifconfig, 1, 1, NULL }, @@ -173,6 +176,9 @@ static const struct cmdmap_s g_cmdmap[] = !defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_DISABLE_SIGNALS) { "ping", cmd_ping, 2, 6, "[-c <count>] [-i <interval>] <ip-address>" }, #endif +#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0 + { "put", cmd_put, 4, 7, "[-b|-n] [-f <remote-path>] -h <ip-address> <local-path>" }, +#endif #if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON) { "pwd", cmd_pwd, 1, 1, NULL }, #endif @@ -1122,7 +1128,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline) ret = pthread_create(&thread, &attr, nsh_child, (pthread_addr_t)args); if (ret != 0) { - nsh_output(vtbl, g_fmtcmdfailed, cmd, "pthread_create", ret); + nsh_output(vtbl, g_fmtcmdfailed, cmd, "pthread_create", NSH_ERRNO_OF(ret)); nsh_releaseargs(args); nsh_release(bkgvtbl); goto errout; diff --git a/examples/nsh/nsh_netcmds.c b/examples/nsh/nsh_netcmds.c index 01f472a319..33eeb9966b 100644 --- a/examples/nsh/nsh_netcmds.c +++ b/examples/nsh/nsh_netcmds.c @@ -44,7 +44,10 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include <string.h> #include <sched.h> +#include <libgen.h> +#include <errno.h> #include <nuttx/net.h> #include <nuttx/clock.h> @@ -54,12 +57,17 @@ #include <netinet/ether.h> #ifdef CONFIG_NET_STATISTICS -#include <net/uip/uip.h> +# include <net/uip/uip.h> #endif #if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) && \ !defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_DISABLE_SIGNALS) -#include <net/uip/uip-lib.h> +# include <net/uip/uip-lib.h> +#endif + +#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0 +# include <net/uip/uip-lib.h> +# include <net/uip/tftp.h> #endif #include "nsh.h" @@ -74,6 +82,17 @@ * Private Types ****************************************************************************/ +#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0 +struct tftpc_args_s +{ + boolean binary; /* TRUE:binary ("octect") FALSE:text ("netascii") */ + boolean allocated; /* TRUE: destpath is allocated */ + char *destpath; /* Path at destination */ + const char *srcpath; /* Path at src */ + in_addr_t ipaddr; /* Host IP address */ +}; +#endif + /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -242,10 +261,159 @@ int ifconfig_callback(FAR struct uip_driver_s *dev, void *arg) return OK; } +/**************************************************************************** + * Name: tftpc_parseargs + ****************************************************************************/ + +#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0 +int tftpc_parseargs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv, + struct tftpc_args_s *args) +{ + FAR const char *fmt = g_fmtarginvalid; + int option; + + /* Get the ping options */ + + memset(args, 0, sizeof(struct tftpc_args_s)); + while ((option = getopt(argc, argv, ":bnf:h:")) != ERROR) + { + switch (option) + { + case 'b': + args->binary = TRUE; + break; + + case 'n': + args->binary = FALSE; + break; + + case 'f': + args->destpath = optarg; + break; + + case 'h': + if (!uiplib_ipaddrconv(optarg, (FAR unsigned char*)&args->ipaddr)) + { + nsh_output(vtbl, g_fmtarginvalid, argv[0]); + goto errout; + } + break; + + case ':': + fmt = g_fmtargrequired; + + case '?': + default: + goto errout; + } + } + + /* There should be exactly on parameter left on the command-line */ + + if (optind == argc-1) + { + args->srcpath = argv[optind]; + } + else if (optind >= argc) + { + fmt = g_fmttoomanyargs; + goto errout; + } + else + { + fmt = g_fmtargrequired; + goto errout; + } + + /* The HOST IP address is also required */ + + if (!args->ipaddr) + { + fmt = g_fmtargrequired; + goto errout; + } + + /* If the destpath was not provided, then we have do a little work. */ + + if (!args->destpath) + { + char *tmp1; + char *tmp2; + + /* Copy the srcpath... baseanme might modify it */ + + fmt = g_fmtcmdoutofmemory; + tmp1 = strdup(args->srcpath); + if (!tmp1) + { + goto errout; + } + + /* Get the basename of the srcpath */ + + tmp2 = basename(tmp1); + if (!tmp2) + { + free(tmp1); + goto errout; + } + + /* Use that basename as the destpath */ + + args->destpath = strdup(tmp2); + free(tmp1); + if (!args->destpath) + { + goto errout; + } + args->allocated = TRUE; + } + + return OK; + +errout: + nsh_output(vtbl, fmt, argv[0]); + return ERROR; +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: cmd_get + ****************************************************************************/ + +#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0 +int cmd_get(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + struct tftpc_args_s args; + + /* Parse the input parameter list */ + + if (tftpc_parseargs(vtbl, argc, argv, &args) != OK) + { + return ERROR; + } + + /* Then perform the TFTP get operation */ + + if (tftpget(args.srcpath, args.destpath, args.ipaddr, args.binary) != OK) + { + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "tftpget", NSH_ERRNO); + } + + /* Release any allocated memory */ + + if (args.allocated) + { + free(args.destpath); + } + return OK; +} +#endif + /**************************************************************************** * Name: cmd_ifconfig ****************************************************************************/ @@ -403,4 +571,44 @@ errout: return ERROR; } #endif /* CONFIG_NET_ICMP && CONFIG_NET_ICMP_PING */ + +/**************************************************************************** + * Name: cmd_put + ****************************************************************************/ + +#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0 +int cmd_put(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + struct tftpc_args_s args; + char *fullpath; + + /* Parse the input parameter list */ + + if (tftpc_parseargs(vtbl, argc, argv, &args) != OK) + { + return ERROR; + } + + /* Get the full path to the local file */ + + fullpath = nsh_getfullpath(vtbl, args.srcpath); + + /* Then perform the TFTP put operation */ + + if (tftpput(fullpath, args.destpath, args.ipaddr, args.binary) != OK) + { + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "tftpput", NSH_ERRNO); + } + + /* Release any allocated memory */ + + if (args.allocated) + { + free(args.destpath); + } + free(fullpath); + return OK; +} +#endif + #endif /* CONFIG_NET */ diff --git a/netutils/tftpc/tftpc_get.c b/netutils/tftpc/tftpc_get.c index 49c39a2cbb..bb2f96267b 100644 --- a/netutils/tftpc/tftpc_get.c +++ b/netutils/tftpc/tftpc_get.c @@ -323,7 +323,7 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar */ #if CONFIG_NETUTILS_TFTP_ACKPACKETS > 1 - if (ndatabytes < blockno != lastacked) + if (ndatabytes < TFTP_DATASIZE && blockno != lastacked) { len = tftp_mkackpacket(packet, blockno); ret = tftp_sendto(sd, packet, len, &server); diff --git a/netutils/tftpc/tftpc_put.c b/netutils/tftpc/tftpc_put.c index 73004bdbc2..1d19a2d749 100644 --- a/netutils/tftpc/tftpc_put.c +++ b/netutils/tftpc/tftpc_put.c @@ -402,7 +402,7 @@ int tftpput(const char *local, const char *remote, in_addr_t addr, boolean binar #if CONFIG_NETUTILS_TFTP_ACKPACKETS > 1 /* Construct the next data packet */ - packetlen = tftp_mkdatapacket(fd, offset[tail], packet, blockno); + packetlen = tftp_mkdatapacket(fd, offsets[tail], packet, blockno); if (packetlen < 0) { goto errout_with_sd; @@ -474,7 +474,6 @@ int tftpput(const char *local, const char *remote, in_addr_t addr, boolean binar #if CONFIG_NETUTILS_TFTP_ACKPACKETS > 1 if (blockno - hblockno >= CONFIG_NETUTILS_TFTP_ACKPACKETS || eof) { - uint16 rblockno; int ndx; /* Get the next ACK from the wire */ -- GitLab