diff options
Diffstat (limited to 'nuttx/examples/nsh')
-rw-r--r-- | nuttx/examples/nsh/README.txt | 26 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh.h | 10 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_main.c | 8 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_netcmds.c | 212 |
4 files changed, 251 insertions, 5 deletions
diff --git a/nuttx/examples/nsh/README.txt b/nuttx/examples/nsh/README.txt index 366be8a3c..fd0c4884b 100644 --- a/nuttx/examples/nsh/README.txt +++ b/nuttx/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/nuttx/examples/nsh/nsh.h b/nuttx/examples/nsh/nsh.h index 861be30c2..f468a264a 100644 --- a/nuttx/examples/nsh/nsh.h +++ b/nuttx/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/nuttx/examples/nsh/nsh_main.c b/nuttx/examples/nsh/nsh_main.c index ba7ad389f..f2890159c 100644 --- a/nuttx/examples/nsh/nsh_main.c +++ b/nuttx/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/nuttx/examples/nsh/nsh_netcmds.c b/nuttx/examples/nsh/nsh_netcmds.c index 01f472a31..33eeb9966 100644 --- a/nuttx/examples/nsh/nsh_netcmds.c +++ b/nuttx/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 ****************************************************************************/ @@ -243,10 +262,159 @@ int ifconfig_callback(FAR struct uip_driver_s *dev, void *arg) } /**************************************************************************** + * 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 */ |