From 540b7c48c9e13910105ab67146b54a43db9fc253 Mon Sep 17 00:00:00 2001 From: patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> Date: Sat, 28 Mar 2009 19:49:28 +0000 Subject: [PATCH] Add wget command to NSH git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1657 42af7a65-404d-4744-a932-0658087f49c3 --- ChangeLog | 8 +- Documentation/NuttShell.html | 46 +++++++- Documentation/NuttX.html | 8 +- Documentation/NuttxPortingGuide.html | 2 +- TODO | 28 +++-- examples/nsh/README.txt | 19 +++- examples/nsh/nsh.h | 5 + examples/nsh/nsh_main.c | 6 ++ examples/nsh/nsh_netcmds.c | 154 ++++++++++++++++++++++++++- examples/wget/host.c | 5 +- examples/wget/target.c | 5 +- include/net/uip/webclient.h | 5 +- netutils/webclient/webclient.c | 4 +- 13 files changed, 265 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index e250ac7ef9..922ba77cf8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -672,6 +672,10 @@ (submitted by JPelletier). The is the same fix that was needed for the eZ80 and fixed in 0.4.2. * netutils: Added logic to support a simple wget() function - * examples/wget: Added a test for wget() (Not yet tested because of - some current networking limitations). + * examples/wget: Added a test for wget() -- NOTE * lib/strncasecmp: Fix cut'n'paste error in function name. + * NSH: Added wget command (untested and temorarily disabled)-- see NOTE. + + NOTE: Features related to wget are not tested on the target platform in this + release and, hence, most likely have problems. I don't have the correct network + settup to perform that testing now (I'm in a hotel). diff --git a/Documentation/NuttShell.html b/Documentation/NuttShell.html index c5c5c921be..2ebad0a744 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: November 15, 2008</p> + <p>Last Updated: March 28, 2009</p> </td> </tr> </table> @@ -275,7 +275,13 @@ <tr> <td><br></td> <td> - <a href="#cmdxd">2.33 Hexadecimal Dump (xd)</a> + <a href="#cmdwget">2.33 Get File Via HTTP (wget)</a> + </td> +</tr> +<tr> + <td><br></td> + <td> + <a href="#cmdxd">2.34 Hexadecimal Dump (xd)</a> </td> </tr> <tr> @@ -1673,7 +1679,34 @@ usleep <usec> <table width ="100%"> <tr bgcolor="#e4e4e4"> <td> - <a name="cmdxd"><h2>2.33 Hexadecimal dump (xd)</h2></a> + <a name="cmdwget">2.33 Get File Via HTTP (wget)</a> + </td> + </tr> +</table> + +<a <p><b>Command Syntax:</b></p> +<ul><pre> +wget [-o <local-path>] <url> +</pre></ul> +<p> + <b>Synopsis</b>. + Use HTTP to copy the file at <code><url></code> to the current directory. +</p> +<p><b>Options:</b></p> +<ul><table> + <tr> + <td><b><code>-o <local-path></code></b></td> + <td> + The file will be saved relative to the current working directory + and with the same name as on the HTTP server unless <code><local-path></code> is provided. + </td> + </tr> +</table></ul> + +<table width ="100%"> + <tr bgcolor="#e4e4e4"> + <td> + <a name="cmdxd"><h2>2.34 Hexadecimal dump (xd)</h2></a> </td> </tr> </table> @@ -1909,6 +1942,12 @@ nsh> <td>!<code>CONFIG_DISABLE_SIGNALS</code></td> <td><code>CONFIG_EXAMPLES_NSH_DISABLE_USLEEP</code></td> </tr> + <tr> + <td><b><code>wget</code></b></td> + <td><code>CONFIG_NET</code> && <code>CONFIG_NET_TCP</code> && + <code>CONFIG_NFILE_DESCRIPTORS</code> > 0</td> + <td><code>CONFIG_EXAMPLES_NSH_DISABLE_WGET</code></td> + </tr> <tr> <td><b><code>xd</code></b></td> <td><br></td> @@ -2255,6 +2294,7 @@ nsh> <li><a href="#cmdunmount"><code>umount</code></a></li> <li><a href="#cmdunset"><code>unset</code></a></li> <li><a href="#cmdusleep"><code>usleep</code></a></li> + <li><a href="#cmdwget"><code>wget</code></a></li> <li><a href="#cmdxd"><code>xd</code></a></li> </ul></td> </tr></table> diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html index a592cf57a5..382c2d3ad4 100644 --- a/Documentation/NuttX.html +++ b/Documentation/NuttX.html @@ -1363,9 +1363,13 @@ nuttx-0.4.4 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> (submitted by JPelletier). The is the same fix that was needed for the eZ80 and fixed in 0.4.2. * netutils: Added logic to support a simple wget() function - * examples/wget: Added a test for wget() (Not yet tested because of - some current networking limitations). + * examples/wget: Added a test for wget() -- NOTE * lib/strncasecmp: Fix cut'n'paste error in function name. + * NSH: Added wget command (untested and temorarily disabled)-- see NOTE. + + NOTE: Features related to wget are not tested on the target platform in this + release and, hence, most likely have problems. I don't have the correct network + settup to perform that testing now (I'm in a hotel). pascal-0.1.3 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> diff --git a/Documentation/NuttxPortingGuide.html b/Documentation/NuttxPortingGuide.html index 93a2e3b2ee..1d790ee25d 100644 --- a/Documentation/NuttxPortingGuide.html +++ b/Documentation/NuttxPortingGuide.html @@ -817,7 +817,7 @@ include/ <h2>2.12 <a name="DirStructNetUtils">netutils</a></h2> <p> This directory contains most of the network applications. - Some of these are original with NuttX (like tftpc) and others were leveraged from the uIP-1.0 apps directory. + Some of these are original with NuttX (like tftpc and dhcpd) and others were leveraged from the uIP-1.0 apps directory. As the uIP apps/README says, these applications "are not all heavily tested." </p> <ul><pre> diff --git a/TODO b/TODO index 763d088893..32aee97ece 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,5 @@ -NuttX TODO List (Last updated February 19, 2009) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +NuttX TODO List (Last updated March 28, 2009) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (6) Task/Scheduler (sched/) (1) Dynamic loader (N/A) @@ -16,7 +16,7 @@ NuttX TODO List (Last updated February 19, 2009) (2) Documentation (Documentation/) (5) Build system / Toolchains (2) NuttShell (NSH) (examples/nsh) - (1) Other Applications & Tests (examples/) + (2) Other Applications & Tests (examples/) (1) Linux/Cywgin simulation (arch/sim) (2) ARM (arch/arm/) (1) ARM/C5471 (arch/arm/src/c5471/) @@ -120,8 +120,10 @@ o Network (net/, netutils/) ^^^^^^^^^^^^^^^^^^^^^^^^^ Description: Several of the netutils/ apps are untested. These include - uIP's netutils/smtp, dhcpd, resolv, webclient. Only minimal - testing of the others has been performed. + uIP's netutils/smtp and resolv. The webclient code has been + tested on host using gethosbyname(), but not depends on the + untested resolve logic. Only minimal testing of the others + has been performed. Status: Open Priority: Medium, Important but not core NuttX functionality @@ -381,10 +383,13 @@ o NuttShell (NSH) (examples/nsh) Status: Open Priority: Low - Description: Here are some commands that would be good to have in NSH: - ping + Description: The wget command has been incorporated into NSH, however + it is still untested as of this writing (only because I + have not had the correct network setup for the testing + yet). Since wget depends on the also untest uIP resolv/ + logic, it is like non-functional. Status: Open - Priority: Low + Priority: Med-High o Other Applications & Tests (examples/) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -392,6 +397,13 @@ o Other Applications & Tests (examples/) Description: The redirection test (part of examples/pipe) terminates incorrectly on the Cywgin-based simulation platform (but works fine on the Linux-based simulation platform). + Status: Open + Priority: Low + + Description: examples/wget is untested on the target (it has been tested + on the host, but not in the target using the uIP resolv logic). + Status: Open + Priority: Med o Linux/Cywgin simulation (arch/sim) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/nsh/README.txt b/examples/nsh/README.txt index 8bdd14eb50..2a8d43f48b 100644 --- a/examples/nsh/README.txt +++ b/examples/nsh/README.txt @@ -303,8 +303,8 @@ o exit 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: + Use TFTP to 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 @@ -717,6 +717,16 @@ o usleep <usec> Pause execution (sleep) of <usec> microseconds. +o wget [-o <local-path>] <url> + + Use HTTP to copy the file at <url> to the current directory. + Options: + + -o <local-path> + The file will be saved relative to the current working directory + and with the same name as on the HTTP server unless <local-path> + is provided. + o xd <hex-address> <byte-count> Dump <byte-count> bytes of data from address <hex-address> @@ -780,10 +790,11 @@ Command Dependencies on Configuration Settings umount !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_READABLE unset !CONFIG_DISABLE_ENVIRON usleep !CONFIG_DISABLE_SIGNALS + get CONFIG_NET && CONFIG_NET_TCP && CONFIG_NFILE_DESCRIPTORS > 0 xd --- * NOTES: - 1. Because of hardware padding, the actual required for put and get + 1. Because of hardware padding, the actual buffersize required for put and get operations size may be larger. 2. Special TFTP server start-up optionss will probably be required to permit creation of file for the correct operation of the put command. @@ -808,7 +819,7 @@ also allow it to squeeze into very small memory footprints. CONFIG_EXAMPLES_NSH_DISABLE_PWD, CONFIG_EXAMPLES_NSH_DISABLE_RM, CONFIG_EXAMPLES_NSH_DISABLE_RMDIR, CONFIG_EXAMPLES_NSH_DISABLE_SET, CONFIG_EXAMPLES_NSH_DISABLE_SH, CONFIG_EXAMPLES_NSH_DISABLE_SLEEP, CONFIG_EXAMPLES_NSH_DISABLE_TEST, CONFIG_EXAMPLES_NSH_DISABLE_UMOUNT, CONFIG_EXAMPLES_NSH_DISABLE_UNSET, - CONFIG_EXAMPLES_NSH_DISABLE_USLEEP, CONFIG_EXAMPLES_NSH_DISABLE_XD + CONFIG_EXAMPLES_NSH_DISABLE_USLEEP, CONFIG_EXAMPLES_NSH_DISABLE_WGET, CONFIG_EXAMPLES_NSH_DISABLE_XD NSH-Specific Configuration Settings ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/nsh/nsh.h b/examples/nsh/nsh.h index 0ef0baaecc..4a986a9965 100644 --- a/examples/nsh/nsh.h +++ b/examples/nsh/nsh.h @@ -434,6 +434,11 @@ extern int cmd_lbracket(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 #endif +#if defined(CONFIG_NET_TCP) && CONFIG_NFILE_DESCRIPTORS > 0 +# ifndef CONFIG_EXAMPLES_NSH_DISABLE_WGET + extern int cmd_wget(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +# endif +#endif #if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) && \ !defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_DISABLE_SIGNALS) # ifndef CONFIG_EXAMPLES_NSH_DISABLE_PING diff --git a/examples/nsh/nsh_main.c b/examples/nsh/nsh_main.c index db116b5c05..edcdf131da 100644 --- a/examples/nsh/nsh_main.c +++ b/examples/nsh/nsh_main.c @@ -317,6 +317,12 @@ static const struct cmdmap_s g_cmdmap[] = # endif #endif +#if defined(CONFIG_NET_TCP) && CONFIG_NFILE_DESCRIPTORS > 0 +# ifndef CONFIG_EXAMPLES_NSH_DISABLE_GET + { "wget", cmd_wget, 2, 3, "[-o <local-path>] <url>" }, +# endif +#endif + #ifndef CONFIG_EXAMPLES_NSH_DISABLE_XD { "xd", cmd_xd, 3, 3, "<hex-address> <byte-count>" }, #endif diff --git a/examples/nsh/nsh_netcmds.c b/examples/nsh/nsh_netcmds.c index f95e450171..f9e0acc6c2 100644 --- a/examples/nsh/nsh_netcmds.c +++ b/examples/nsh/nsh_netcmds.c @@ -1,7 +1,7 @@ /**************************************************************************** * examples/nsh/nsh_netcmds.c * - * Copyright (C) 2007, 2008, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -41,12 +41,14 @@ #ifdef CONFIG_NET #include <sys/types.h> +#include <sys/stat.h> /* Needed for open */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sched.h> -#include <libgen.h> +#include <fcntl.h> /* Needed for open */ +#include <libgen.h> /* Needed for basename */ #include <errno.h> #include <nuttx/net.h> @@ -70,6 +72,13 @@ # include <net/uip/tftp.h> #endif +#if defined(CONFIG_NET_TCP) && CONFIG_NFILE_DESCRIPTORS > 0 +# ifndef CONFIG_EXAMPLES_NSH_DISABLE_WGET +# include <net/uip/uip-lib.h> +# include <net/uip/webclient.h> +# endif +#endif + #include "nsh.h" /**************************************************************************** @@ -302,9 +311,11 @@ int tftpc_parseargs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv, case ':': fmt = g_fmtargrequired; + goto errout; case '?': default: + fmt = g_fmtarginvalid; goto errout; } } @@ -378,6 +389,20 @@ errout: } #endif +/**************************************************************************** + * Name: wget_callback + ****************************************************************************/ + +#if defined(CONFIG_NET_TCP) && CONFIG_NFILE_DESCRIPTORS > 0 +#ifndef CONFIG_EXAMPLES_NSH_DISABLE_WGET +static void wget_callback(FAR char **buffer, int offset, int datend, + FAR int *buflen, FAR void *arg) +{ + (void)write((int)arg, &((*buffer)[offset]), datend - offset); +} +#endif +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -626,4 +651,129 @@ int cmd_put(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) #endif #endif +/**************************************************************************** + * Name: cmd_wget + ****************************************************************************/ + +#if defined(CONFIG_NET_TCP) && CONFIG_NFILE_DESCRIPTORS > 0 +#ifndef CONFIG_EXAMPLES_NSH_DISABLE_WGET +int cmd_wget(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + char *localfile = NULL; + char *allocfile = NULL; + char *buffer = NULL; + char *fullpath = NULL; + char *url; + char *fmt; + int option; + int fd = -1; + int ret; + + /* Get the wget options */ + + while ((option = getopt(argc, argv, ":o:")) != ERROR) + { + switch (option) + { + case 'o': + localfile = optarg; + break; + + case ':': + fmt = g_fmtargrequired; + goto errout; + + case '?': + default: + fmt = g_fmtarginvalid; + goto errout; + } + } + + /* There should be exactly on parameter left on the command-line */ + + if (optind == argc-1) + { + url = argv[optind]; + } + else if (optind >= argc) + { + fmt = g_fmttoomanyargs; + goto errout; + } + else + { + fmt = g_fmtargrequired; + goto errout; + } + + /* Get the local file name */ + + if (!localfile) + { + allocfile = strdup(url); + localfile = basename(allocfile); + } + + /* Get the full path to the local file */ + + fullpath = nsh_getfullpath(vtbl, localfile); + + /* Open the the local file for writing */ + + fd = open(fullpath, O_WRONLY|O_CREAT|O_TRUNC, 0644); + if (fd < 0) + { + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO); + ret = ERROR; + goto exit; + } + + /* Allocate an I/O buffer */ + + buffer = malloc(512); + if (!buffer) + { + fmt = g_fmtcmdoutofmemory; + goto errout; + } + + /* And perform the wget */ + + ret = wget(argv[1], buffer, 512, wget_callback, (FAR void *)fd); + if (ret < 0) + { + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "wget", NSH_ERRNO); + goto exit; + } + + /* Free allocated resources */ + +exit: + if (fd >= 0) + { + close(fd); + } + if (allocfile) + { + free(allocfile); + } + if (fullpath) + { + free(fullpath); + } + if (buffer) + { + free(buffer); + } + return ret; + +errout: + nsh_output(vtbl, fmt, argv[0]); + ret = ERROR; + goto exit; +} +#endif +#endif + #endif /* CONFIG_NET */ diff --git a/examples/wget/host.c b/examples/wget/host.c index 6d59e0eb10..40fda1af98 100644 --- a/examples/wget/host.c +++ b/examples/wget/host.c @@ -56,7 +56,8 @@ * Name: callback ****************************************************************************/ -static void callback(FAR char **buffer, int offset, int datend, FAR int *buflen) +static void callback(FAR char **buffer, int offset, int datend, + FAR int *buflen, FAR void *arg) { (void)write(1, &((*buffer)[offset]), datend - offset); } @@ -89,7 +90,7 @@ int main(int argc, char **argv, char **envp) } printf("WGET: Getting %s\n", argv[1]); - ret = wget(argv[1], buffer, 1024, callback); + ret = wget(argv[1], buffer, 1024, callback, NULL); if (ret < 0) { fprintf(stderr, "WGET: wget failed: %s\n", strerror(errno)); diff --git a/examples/wget/target.c b/examples/wget/target.c index 89716014c6..9d34769641 100644 --- a/examples/wget/target.c +++ b/examples/wget/target.c @@ -94,7 +94,8 @@ static char g_iobuffer[512]; * Name: callback ****************************************************************************/ -static void callback(FAR char **buffer, int offset, int datend, FAR int *buflen) +static void callback(FAR char **buffer, int offset, int datend, + FAR int *buflen, FAR void *arg) { (void)write(1, &((*buffer)[offset]), datend - offset); } @@ -155,6 +156,6 @@ int user_start(int argc, char *argv[]) /* Then start the server */ - wget(CONFIG_EXAMPLE_WGET_URL, g_iobuffer, 512, callback); + wget(CONFIG_EXAMPLE_WGET_URL, g_iobuffer, 512, callback, NULL); return 0; } diff --git a/include/net/uip/webclient.h b/include/net/uip/webclient.h index 053dd5613e..13787e2db3 100644 --- a/include/net/uip/webclient.h +++ b/include/net/uip/webclient.h @@ -96,7 +96,7 @@ */ typedef void (*wget_callback_t)(FAR char **buffer, int offset, - int datend, FAR int *buflen); + int datend, FAR int *buflen, FAR void *arg); /**************************************************************************** * Public Function Prototypes @@ -130,6 +130,7 @@ extern "C" { * buflen - The size of the user provided buffer * callback - As data is obtained from the host, this function is * to dispose of each block of file data as it is received. + * arg - User argument passed to callback. * * Returned Value: * 0: if the GET operation completed successfully; @@ -138,7 +139,7 @@ extern "C" { ****************************************************************************/ EXTERN int wget(FAR const char *url, FAR char *buffer, int buflen, - wget_callback_t callback); + wget_callback_t callback, FAR void *arg); #undef EXTERN #ifdef __cplusplus diff --git a/netutils/webclient/webclient.c b/netutils/webclient/webclient.c index 2a2e2ddf81..3c31e6ad2f 100644 --- a/netutils/webclient/webclient.c +++ b/netutils/webclient/webclient.c @@ -404,7 +404,7 @@ exit: ****************************************************************************/ int wget(FAR const char *url, FAR char *buffer, int buflen, - wget_callback_t callback) + wget_callback_t callback, FAR void *arg) { struct sockaddr_in server; struct wget_s ws; @@ -559,7 +559,7 @@ int wget(FAR const char *url, FAR char *buffer, int buflen, { /* Let the client decide what to do with the received file */ - callback(&ws.buffer, ws.offset, ws.datend, &buflen); + callback(&ws.buffer, ws.offset, ws.datend, &buflen, arg); } else { -- GitLab