Bump to version 1.22.1
[platform/upstream/busybox.git] / miscutils / rx.c
index 3a8b6a8..1dffb59 100644 (file)
  *
  * Copyright (C) 2001 Hewlett-Packard Laboratories
  *
- * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  *
  * This was originally written for blob and then adapted for busybox.
  */
 
+//usage:#define rx_trivial_usage
+//usage:       "FILE"
+//usage:#define rx_full_usage "\n\n"
+//usage:       "Receive a file using the xmodem protocol"
+//usage:
+//usage:#define rx_example_usage
+//usage:       "$ rx /tmp/foo\n"
+
 #include "libbb.h"
 
 #define SOH 0x01
@@ -100,12 +108,10 @@ static int receive(/*int read_fd, */int file_fd)
                        }
                }
                /* Write previously received block */
-               if (blockLength) {
-                       errno = 0;
-                       if (full_write(file_fd, blockBuf, blockLength) != blockLength) {
-                               bb_perror_msg("can't write to file");
-                               goto fatal;
-                       }
+               errno = 0;
+               if (full_write(file_fd, blockBuf, blockLength) != blockLength) {
+                       bb_perror_msg(bb_msg_write_error);
+                       goto fatal;
                }
 
                timeout = TIMEOUT;
@@ -147,23 +153,20 @@ static int receive(/*int read_fd, */int file_fd)
                        blockBuf[i] = cc;
                }
 
+               cksum_or_crc = read_byte(TIMEOUT);
+               if (cksum_or_crc < 0)
+                       goto timeout;
                if (do_crc) {
-                       cksum_or_crc = read_byte(TIMEOUT);
-                       if (cksum_or_crc < 0)
-                               goto timeout;
                        cksum_or_crc = (cksum_or_crc << 8) | read_byte(TIMEOUT);
                        if (cksum_or_crc < 0)
                                goto timeout;
-               } else {
-                       cksum_or_crc = read_byte(TIMEOUT);
-                       if (cksum_or_crc < 0)
-                               goto timeout;
                }
 
                if (blockNo == ((wantBlockNo - 1) & 0xff)) {
                        /* a repeat of the last block is ok, just ignore it. */
                        /* this also ignores the initial block 0 which is */
                        /* meta data. */
+                       blockLength = 0;
                        goto next;
                }
                if (blockNo != (wantBlockNo & 0xff)) {
@@ -190,8 +193,8 @@ static int receive(/*int read_fd, */int file_fd)
                }
                if (cksum_or_crc != expected) {
                        bb_error_msg(do_crc ? "crc error, expected 0x%04x, got 0x%04x"
-                                          : "checksum error, expected 0x%02x, got 0x%02x",
-                                       expected, cksum_or_crc);
+                                       : "checksum error, expected 0x%02x, got 0x%02x",
+                               expected, cksum_or_crc);
                        goto error;
                }
 
@@ -204,6 +207,7 @@ static int receive(/*int read_fd, */int file_fd)
                continue;
  error:
  timeout:
+               blockLength = 0;
                errors++;
                if (errors == MAXERRORS) {
                        /* Abort */
@@ -234,21 +238,18 @@ static void sigalrm_handler(int UNUSED_PARAM signum)
 }
 
 int rx_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-int rx_main(int argc, char **argv)
+int rx_main(int argc UNUSED_PARAM, char **argv)
 {
        struct termios tty, orig_tty;
        int termios_err;
        int file_fd;
        int n;
 
-       if (argc != 2)
-               bb_show_usage();
-
        /* Disabled by vda:
         * why we can't receive from stdin? Why we *require*
         * controlling tty?? */
        /*read_fd = xopen(CURRENT_TTY, O_RDWR);*/
-       file_fd = xopen(argv[1], O_RDWR|O_CREAT|O_TRUNC);
+       file_fd = xopen(single_argv(argv), O_RDWR|O_CREAT|O_TRUNC);
 
        termios_err = tcgetattr(read_fd, &tty);
        if (termios_err == 0) {