+/* vi: set sw=4 ts=4: */
/*-------------------------------------------------------------------------
* Filename: xmodem.c
- * Version: $Id: rx.c,v 1.1 2003/12/20 07:30:35 bug1 Exp $
+ * Version: $Id: rx.c,v 1.2 2004/03/15 08:28:46 andersen Exp $
* Copyright: Copyright (C) 2001, Hewlett-Packard Company
* Author: Christopher Hoover <ch@hpl.hp.com>
- * Description: xmodem functionality for uploading of kernels
+ * Description: xmodem functionality for uploading of kernels
* and the like
* Created at: Thu Dec 20 01:58:08 PST 2001
*-----------------------------------------------------------------------*/
/*
- * xmodem.c: xmodem functionality for uploading of kernels and
+ * xmodem.c: xmodem functionality for uploading of kernels and
* the like
*
* Copyright (C) 2001 Hewlett-Packard Laboratories
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*
* This was originally written for blob and then adapted for busybox.
*
*/
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <termios.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <string.h>
#include "busybox.h"
-
#define SOH 0x01
#define STX 0x02
#define EOT 0x04
#define ACK 0x06
#define NAK 0x15
-#define CAN 0x18
#define BS 0x08
/*
#define TIMEOUT_LONG 10
#define MAXERRORS 10
-static inline void write_byte(int fd, char cc) {
- write(fd, &cc, 1);
-}
-
-static inline void write_flush(int fd) {
- tcdrain(fd);
-}
-
-static inline void read_flush(int fd) {
- tcflush(fd, TCIFLUSH);
-}
-
static int read_byte(int fd, unsigned int timeout) {
char buf[1];
int n;
#define note_error(fmt,args...) \
snprintf(error_buf, error_buf_size, fmt,##args)
- read_flush(ttyfd);
+ /* Flush pending input */
+ tcflush(ttyfd, TCIFLUSH);
/* Ask for CRC; if we get errors, we will go with checksum */
- write_byte(ttyfd, nak);
- write_flush(ttyfd);
+ write(ttyfd, &nak, 1);
for (;;) {
int blockBegin;
break;
case EOT:
- write_byte(ttyfd, ACK);
- write_flush(ttyfd);
+ nak = ACK;
+ write(ttyfd, &nak, 1);
goto done;
default:
wantBlockNo++;
length += blockLength;
- if (bb_full_write(filefd, blockBuf, blockLength) < 0) {
+ if (full_write(filefd, blockBuf, blockLength) < 0) {
note_error("write to file failed: %m");
goto fatal;
}
next:
errors = 0;
- write_byte(ttyfd, ACK);
- write_flush(ttyfd);
+ nak = ACK;
+ write(ttyfd, &nak, 1);
continue;
error:
errors++;
if (errors == MAXERRORS) {
/* Abort */
- int i;
// if using crc, try again w/o crc
if (nak == 'C') {
note_error("too many errors; giving up");
fatal:
- for (i = 0; i < 5; i ++)
- write_byte(ttyfd, CAN);
- for (i = 0; i < 5; i ++)
- write_byte(ttyfd, BS);
- write_flush(ttyfd);
+ /* 5 CAN followed by 5 BS */
+ write(ttyfd, "\030\030\030\030\030\010\010\010\010\010", 10);
return -1;
}
- read_flush(ttyfd);
- write_byte(ttyfd, nak);
- write_flush(ttyfd);
+ /* Flush pending input */
+ tcflush(ttyfd, TCIFLUSH);
+
+ write(ttyfd, &nak, 1);
}
done:
#undef note_error
}
-static void sigalrm_handler(int signum)
+static void sigalrm_handler(int ATTRIBUTE_UNUSED signum)
{
}
bb_show_usage();
fn = argv[1];
- ttyfd = open("/dev/tty", O_RDWR);
- if (ttyfd < 0)
- bb_error_msg_and_die("%s: open on /dev/tty failed: %m\n", argv[0]);
-
- filefd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0666);
- if (filefd < 0)
- bb_error_msg_and_die("%s: open on %s failed: %m\n", argv[0], fn);
+ ttyfd = xopen3(CURRENT_TTY, O_RDWR, 0);
+ filefd = xopen3(fn, O_RDWR|O_CREAT|O_TRUNC, 0666);
if (tcgetattr(ttyfd, &tty) < 0)
bb_error_msg_and_die("%s: tcgetattr failed: %m\n", argv[0]);
-
+
orig_tty = tty;
cfmakeraw(&tty);
tcsetattr(ttyfd, TCSAFLUSH, &tty);
-
+
memset(&act, 0, sizeof(act));
act.sa_handler = sigalrm_handler;
sigaction(SIGALRM, &act, 0);
bb_fflush_stdout_and_exit(EXIT_SUCCESS);
}
-
-/*
-Local Variables:
-c-file-style: "linux"
-c-basic-offset: 4
-tab-width: 4
-End:
-*/