summaryrefslogtreecommitdiff
path: root/apps/system/zmodem
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-07-12 19:06:00 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-07-12 19:06:00 -0600
commit92c70c86d8d7c023e16c87a1bd39cc0d7981d017 (patch)
tree8ed4dbf5116f25acc765d05caacd43e24835e809 /apps/system/zmodem
parente77e09228c953f36872e0674ba98e4358f46b109 (diff)
downloadnuttx-92c70c86d8d7c023e16c87a1bd39cc0d7981d017.tar.gz
nuttx-92c70c86d8d7c023e16c87a1bd39cc0d7981d017.tar.bz2
nuttx-92c70c86d8d7c023e16c87a1bd39cc0d7981d017.zip
More Zmodem-related changes
Diffstat (limited to 'apps/system/zmodem')
-rw-r--r--apps/system/zmodem/sz_main.c180
-rw-r--r--apps/system/zmodem/zm.h2
-rw-r--r--apps/system/zmodem/zm_proto.c14
3 files changed, 176 insertions, 20 deletions
diff --git a/apps/system/zmodem/sz_main.c b/apps/system/zmodem/sz_main.c
index 6f77042c1..c6693f0b5 100644
--- a/apps/system/zmodem/sz_main.c
+++ b/apps/system/zmodem/sz_main.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * system/xmodem/sz_main.c
+ * system/zmodem/sz_main.c
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@@ -40,28 +40,182 @@
#include <nuttx/config.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <time.h>
+#include <errno.h>
#include <apps/zmodem.h>
/****************************************************************************
- * Definitions
+ * Private Functions
****************************************************************************/
-/****************************************************************************
- * Private Data
- ****************************************************************************/
+static void show_usage(FAR const char *progname, int errcode)
+{
+ fprintf(stderr, "USAGE: %s [OPTIONS] <lname> [<lname> [<lname> ...]]\n", progname);
+ fprintf(stderr, "\nWhere:\n");
+ fprintf(stderr, "\t<lname> is the local file name\n");
+ fprintf(stderr, "\nand OPTIONS include the following:\n");
+ fprintf(stderr, "\t-d <device>: Communication device to use. Default /dev/console\n");
+ fprintf(stderr, "\t-r <rname>: Remote file name. Default <lname>\n");
+ fprintf(stderr, "\t-x <mode>: Transfer type\n");
+ fprintf(stderr, "\t\t0: Normal file (default)\n");
+ fprintf(stderr, "\t\t1: Binary file\n");
+ fprintf(stderr, "\t\t2: Convert \\n to local EOF convention\n");
+ fprintf(stderr, "\t\t3: Resume or append to existing file\n");
+ fprintf(stderr, "\t-o <option>: Transfer option\n");
+ fprintf(stderr, "\t\t0: Implementation dependent\n");
+ fprintf(stderr, "\t\t1: Transfer if source newer or longer\n");
+ fprintf(stderr, "\t\t2: Transfer if different CRC or length\n");
+ fprintf(stderr, "\t\t3: Append to existing file, if any\n");
+ fprintf(stderr, "\t\t4: Replace existing file (default)\n");
+ fprintf(stderr, "\t\t5: Transfer if source is newer\n");
+ fprintf(stderr, "\t\t6: Transfer if dates or lengths different\n");
+ fprintf(stderr, "\t\t7: Protect: transfer only if dest doesn't exist\n");
+ fprintf(stderr, "\t\t8: Change filename if destination exists\n");
+ fprintf(stderr, "\t-s: Skip if file not present at receiving end\n");
+ fprintf(stderr, "\t-h: Show this text and exit\n");
+ exit(errcode);
+}
/****************************************************************************
* Public Functions
****************************************************************************/
-/****************************************************************************
- * Name: sz_main
- ****************************************************************************/
-
-int sz_main(int argc, char *argv[])
+int sz_main(int argc, FAR char **argv)
{
- printf("Not yet implemented!!\n");
- return 0;
-}
+ enum zm_xfertype_e xfrtype = XM_XFERTYPE_NORMAL;
+ enum zm_option_e xfroption = XM_OPTION_REPLACE;
+ ZMSHANDLE handle;
+ FAR const char *rname = NULL;
+ FAR const char *devname = "/dev/console";
+ FAR char *endptr;
+ bool skip = false;
+ long tmp;
+ int exitcode = EXIT_FAILURE;
+ int option;
+ int ret;
+ int fd;
+
+ /* Parse input parameters */
+
+ while ((option = getopt(argc, argv, ":d:ho:r:sx:")) != ERROR)
+ {
+ switch (option)
+ {
+ case 'd':
+ devname = optarg;
+ break;
+
+ case 'h':
+ show_usage(argv[0], EXIT_SUCCESS);
+ break;
+
+ case 'o':
+ tmp = strtol(optarg, &endptr, 10);
+ if (tmp < 0 || tmp > 8)
+ {
+ fprintf(stderr, "ERROR: Transfer option out of range: %ld\n", tmp);
+ show_usage(argv[0], EXIT_FAILURE);
+ }
+ else
+ {
+ xfroption = (enum zm_option_e)tmp;
+ }
+ break;
+
+ case 'r':
+ rname = optarg;
+ break;
+
+ case 's':
+ skip = true;
+ break;
+
+ case 'x':
+ tmp = strtol(optarg, &endptr, 10);
+ if (tmp < 0 || tmp > 3)
+ {
+ fprintf(stderr, "ERROR: Transfer type out of range: %ld\n", tmp);
+ show_usage(argv[0], EXIT_FAILURE);
+ }
+ else
+ {
+ xfrtype = (enum zm_xfertype_e)tmp;
+ }
+ break;
+ case ':':
+ fprintf(stderr, "ERROR: Missing required argument\n");
+ show_usage(argv[0], EXIT_FAILURE);
+ break;
+
+ default:
+ case '?':
+ fprintf(stderr, "ERROR: Unrecognized option\n");
+ show_usage(argv[0], EXIT_FAILURE);
+ break;
+ }
+ }
+
+ /* There should be one final parameters remaining on the command line */
+
+ if (optind >= argc)
+ {
+ printf("ERROR: Missing required 'lname' argument\n");
+ show_usage(argv[0], EXIT_FAILURE);
+ }
+
+ /* Open the device for read/write access */
+
+ fd = open(devname, O_RDWR);
+ if (fd < 0)
+ {
+ fprintf(stderr, "ERROR: Failed to open %s\n", devname);
+ goto errout;
+ }
+
+ /* Get the Zmodem handle */
+
+ handle = zms_initialize(fd);
+ if (!handle)
+ {
+ fprintf(stderr, "ERROR: Failed to get Zmodem handle\n");
+ goto errout_with_device;
+ }
+
+ /* And perform the transfer(s) */
+
+ for (; optind < argc; optind++)
+ {
+ /* By the default, the remote file name is the same as the local file
+ * name. This will, of course, fail miserably if rname is specified
+ * and there more than one lnames on the command line. Don't do that.
+ */
+
+ FAR const char *nextlname = argv[optind];
+ FAR const char *nextrname = rname ? rname : nextlname;
+
+ /* Transfer the file */
+
+ ret = zms_send(handle, nextlname, nextrname, xfrtype, xfroption, skip);
+ if (ret < 0)
+ {
+ fprintf(stderr, "ERROR: Transfer of %s failed: %d\n",
+ nextlname, errno);
+ goto errout_with_zmodem;
+ }
+ }
+
+ exitcode = EXIT_SUCCESS;
+
+errout_with_zmodem:
+ (void)zms_release(handle);
+errout_with_device:
+ (void)close(fd);
+errout:
+ return exitcode;
+}
diff --git a/apps/system/zmodem/zm.h b/apps/system/zmodem/zm.h
index 3747b0feb..e0caf8837 100644
--- a/apps/system/zmodem/zm.h
+++ b/apps/system/zmodem/zm.h
@@ -603,7 +603,7 @@ FAR uint8_t *zm_putzdle(FAR struct zm_state_s *pzm, FAR uint8_t *buffer,
*
* Input Parameters:
* pzm - Zmodem session state
- * buffer - Buffer of data to be sent (must not be pzm->rcvbuf)
+ * buffer - Buffer of data to be sent
* buflen - The number of bytes in buffer to be sent
*
****************************************************************************/
diff --git a/apps/system/zmodem/zm_proto.c b/apps/system/zmodem/zm_proto.c
index 4ef1c143d..9af600f8a 100644
--- a/apps/system/zmodem/zm_proto.c
+++ b/apps/system/zmodem/zm_proto.c
@@ -169,8 +169,8 @@ FAR uint8_t *zm_putzdle(FAR struct zm_state_s *pzm, FAR uint8_t *buffer,
* (ZBIN or ZBIN32 format assumed, ZCRCW terminator is always used)
*
* Input Parameters:
- * pzm - Zmodem session state
- * buffer - Buffer of data to be sent (must not be pzm->rcvbuf)
+ * pzm - Zmodem session state
+ * buffer - Buffer of data to be sent
* buflen - The number of bytes in buffer to be sent
*
****************************************************************************/
@@ -178,21 +178,24 @@ FAR uint8_t *zm_putzdle(FAR struct zm_state_s *pzm, FAR uint8_t *buffer,
int zm_senddata(FAR struct zm_state_s *pzm, FAR const uint8_t *buffer,
size_t buflen)
{
- uint8_t *ptr = pzm->rcvbuf;
+ uint8_t *ptr = pzm->scratch;
ssize_t nwritten;
uint32_t crc;
uint8_t zbin;
uint8_t term;
+ int i;
/* Make select ZBIN or ZBIN32 format and the ZCRCW terminator */
if ((pzm->flags & ZM_FLAG_CRC32) != 0)
{
zbin = ZBIN32;
+ crc = 0xffffffff;
}
else
{
zbin = ZBIN;
+ crc = 0;
}
term = ZCRCW;
@@ -200,7 +203,6 @@ int zm_senddata(FAR struct zm_state_s *pzm, FAR const uint8_t *buffer,
/* Transfer the data to the I/O buffer, accumulating the CRC */
- crc = (zbin == ZBIN) ? 0 : 0xffffffff;
while (buflen-- > 0)
{
if (zbin == ZBIN)
@@ -243,7 +245,7 @@ int zm_senddata(FAR struct zm_state_s *pzm, FAR const uint8_t *buffer,
else
{
crc = ~crc;
- for (buflen = 4; --buflen >= 0; crc >>= 8)
+ for (i = 0; i < 4; i++, crc >>= 8)
{
ptr = zm_putzdle(pzm, ptr, crc & 0xff);
}
@@ -251,7 +253,7 @@ int zm_senddata(FAR struct zm_state_s *pzm, FAR const uint8_t *buffer,
/* Send the header */
- nwritten = zm_remwrite(pzm->remfd, pzm->rcvbuf, ptr - pzm->rcvbuf);
+ nwritten = zm_remwrite(pzm->remfd, pzm->scratch, ptr - pzm->scratch);
return nwritten < 0 ? (int)nwritten : OK;
}