Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/miscutils/rx.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 1  Line 1 
1  /* vi: set sw=4 ts=4: */  /* vi: set sw=4 ts=4: */
2  /*-------------------------------------------------------------------------  /*
  * Filename:      xmodem.c  
3   * Copyright:     Copyright (C) 2001, Hewlett-Packard Company   * Copyright:     Copyright (C) 2001, Hewlett-Packard Company
4   * Author:        Christopher Hoover <ch@hpl.hp.com>   * Author:        Christopher Hoover <ch@hpl.hp.com>
5   * Description:   xmodem functionality for uploading of kernels   * Description:   xmodem functionality for uploading of kernels
6   *                and the like   *                and the like
7   * Created at:    Thu Dec 20 01:58:08 PST 2001   * Created at:    Thu Dec 20 01:58:08 PST 2001
8   *-----------------------------------------------------------------------*/   *
9  /*   * xmodem functionality for uploading of kernels and the like
  * xmodem.c: xmodem functionality for uploading of kernels and  
  *            the like  
10   *   *
11   * Copyright (C) 2001 Hewlett-Packard Laboratories   * Copyright (C) 2001 Hewlett-Packard Laboratories
12   *   *
# Line 26  Line 23 
23  #define ACK 0x06  #define ACK 0x06
24  #define NAK 0x15  #define NAK 0x15
25  #define BS  0x08  #define BS  0x08
26    #define PAD 0x1A
27    
28  /*  /*
29  Cf:  Cf:
# Line 44  Cf: Line 42  Cf:
42    
43  static int read_byte(unsigned timeout)  static int read_byte(unsigned timeout)
44  {  {
45   char buf[1];   unsigned char buf;
46   int n;   int n;
47    
48   alarm(timeout);   alarm(timeout);
49   /* NOT safe_read! We want ALRM to interrupt us */   /* NOT safe_read! We want ALRM to interrupt us */
50   n = read(read_fd, buf, 1);   n = read(read_fd, &buf, 1);
51   alarm(0);   alarm(0);
52   if (n == 1)   if (n == 1)
53   return (unsigned char)buf[0];   return buf;
54   return -1;   return -1;
55  }  }
56    
57  static int receive(/*int read_fd, */int file_fd)  static int receive(/*int read_fd, */int file_fd)
58  {  {
59   unsigned char blockBuf[1024];   unsigned char blockBuf[1024];
60     unsigned blockLength = 0;
61   unsigned errors = 0;   unsigned errors = 0;
62   unsigned wantBlockNo = 1;   unsigned wantBlockNo = 1;
63   unsigned length = 0;   unsigned length = 0;
64   int do_crc = 1;   int do_crc = 1;
65   char nak = 'C';   char reply_char;
66   unsigned timeout = TIMEOUT_LONG;   unsigned timeout = TIMEOUT_LONG;
67    
68   /* Flush pending input */   /* Flush pending input */
69   tcflush(read_fd, TCIFLUSH);   tcflush(read_fd, TCIFLUSH);
70    
71   /* Ask for CRC; if we get errors, we will go with checksum */   /* Ask for CRC; if we get errors, we will go with checksum */
72   full_write(write_fd, &nak, 1);   reply_char = 'C';
73     full_write(write_fd, &reply_char, 1);
74    
75   for (;;) {   for (;;) {
76   int blockBegin;   int blockBegin;
77   int blockNo, blockNoOnesCompl;   int blockNo, blockNoOnesCompl;
78   int blockLength;   int cksum_or_crc;
  int cksum_crc; /* cksum OR crc */  
79   int expected;   int expected;
80   int i,j;   int i, j;
81    
82   blockBegin = read_byte(timeout);   blockBegin = read_byte(timeout);
83   if (blockBegin < 0)   if (blockBegin < 0)
84   goto timeout;   goto timeout;
85    
86     /* If last block, remove padding */
87     if (blockBegin == EOT) {
88     /* Data blocks can be padded with ^Z characters */
89     /* This code tries to detect and remove them */
90     if (blockLength >= 3
91     && blockBuf[blockLength - 1] == PAD
92     && blockBuf[blockLength - 2] == PAD
93     && blockBuf[blockLength - 3] == PAD
94     ) {
95     while (blockLength
96               && blockBuf[blockLength - 1] == PAD
97     ) {
98     blockLength--;
99     }
100     }
101     }
102     /* Write previously received block */
103     if (blockLength) {
104     errno = 0;
105     if (full_write(file_fd, blockBuf, blockLength) != blockLength) {
106     bb_perror_msg("can't write to file");
107     goto fatal;
108     }
109     }
110    
111   timeout = TIMEOUT;   timeout = TIMEOUT;
112   nak = NAK;   reply_char = NAK;
113    
114   switch (blockBegin) {   switch (blockBegin) {
115   case SOH:   case SOH:
116   case STX:   case STX:
117   break;   break;
   
118   case EOT:   case EOT:
119   nak = ACK;   reply_char = ACK;
120   full_write(write_fd, &nak, 1);   full_write(write_fd, &reply_char, 1);
121   return length;   return length;
   
122   default:   default:
123   goto error;   goto error;
124   }   }
125    
126   /* block no */   /* Block no */
127   blockNo = read_byte(TIMEOUT);   blockNo = read_byte(TIMEOUT);
128   if (blockNo < 0)   if (blockNo < 0)
129   goto timeout;   goto timeout;
130    
131   /* block no one's compliment */   /* Block no, in one's complement form */
132   blockNoOnesCompl = read_byte(TIMEOUT);   blockNoOnesCompl = read_byte(TIMEOUT);
133   if (blockNoOnesCompl < 0)   if (blockNoOnesCompl < 0)
134   goto timeout;   goto timeout;
# Line 126  static int receive(/*int read_fd, */int Line 148  static int receive(/*int read_fd, */int
148   }   }
149    
150   if (do_crc) {   if (do_crc) {
151   cksum_crc = read_byte(TIMEOUT);   cksum_or_crc = read_byte(TIMEOUT);
152   if (cksum_crc < 0)   if (cksum_or_crc < 0)
153   goto timeout;   goto timeout;
154   cksum_crc = (cksum_crc << 8) | read_byte(TIMEOUT);   cksum_or_crc = (cksum_or_crc << 8) | read_byte(TIMEOUT);
155   if (cksum_crc < 0)   if (cksum_or_crc < 0)
156   goto timeout;   goto timeout;
157   } else {   } else {
158   cksum_crc = read_byte(TIMEOUT);   cksum_or_crc = read_byte(TIMEOUT);
159   if (cksum_crc < 0)   if (cksum_or_crc < 0)
160   goto timeout;   goto timeout;
161   }   }
162    
# Line 155  static int receive(/*int read_fd, */int Line 177  static int receive(/*int read_fd, */int
177   expected = expected ^ blockBuf[i] << 8;   expected = expected ^ blockBuf[i] << 8;
178   for (j = 0; j < 8; j++) {   for (j = 0; j < 8; j++) {
179   if (expected & 0x8000)   if (expected & 0x8000)
180   expected = expected << 1 ^ 0x1021;   expected = (expected << 1) ^ 0x1021;
181   else   else
182   expected = expected << 1;   expected = (expected << 1);
183   }   }
184   }   }
185   expected &= 0xffff;   expected &= 0xffff;
# Line 166  static int receive(/*int read_fd, */int Line 188  static int receive(/*int read_fd, */int
188   expected += blockBuf[i];   expected += blockBuf[i];
189   expected &= 0xff;   expected &= 0xff;
190   }   }
191   if (cksum_crc != expected) {   if (cksum_or_crc != expected) {
192   bb_error_msg(do_crc ? "crc error, expected 0x%04x, got 0x%04x"   bb_error_msg(do_crc ? "crc error, expected 0x%04x, got 0x%04x"
193                     : "checksum error, expected 0x%02x, got 0x%02x",                     : "checksum error, expected 0x%02x, got 0x%02x",
194      expected, cksum_crc);   expected, cksum_or_crc);
195   goto error;   goto error;
196   }   }
197    
198   wantBlockNo++;   wantBlockNo++;
199   length += blockLength;   length += blockLength;
   
  errno = 0;  
  if (full_write(file_fd, blockBuf, blockLength) != blockLength) {  
  bb_perror_msg("can't write to file");  
  goto fatal;  
  }  
200   next:   next:
201   errors = 0;   errors = 0;
202   nak = ACK;   reply_char = ACK;
203   full_write(write_fd, &nak, 1);   full_write(write_fd, &reply_char, 1);
204   continue;   continue;
205   error:   error:
206   timeout:   timeout:
# Line 192  static int receive(/*int read_fd, */int Line 208  static int receive(/*int read_fd, */int
208   if (errors == MAXERRORS) {   if (errors == MAXERRORS) {
209   /* Abort */   /* Abort */
210    
211   /* if were asking for crc, try again w/o crc */   /* If were asking for crc, try again w/o crc */
212   if (nak == 'C') {   if (reply_char == 'C') {
213   nak = NAK;   reply_char = NAK;
214   errors = 0;   errors = 0;
215   do_crc = 0;   do_crc = 0;
216   goto timeout;   goto timeout;
# Line 209  static int receive(/*int read_fd, */int Line 225  static int receive(/*int read_fd, */int
225   /* Flush pending input */   /* Flush pending input */
226   tcflush(read_fd, TCIFLUSH);   tcflush(read_fd, TCIFLUSH);
227    
228   full_write(write_fd, &nak, 1);   full_write(write_fd, &reply_char, 1);
229   } /* for (;;) */   } /* for (;;) */
230  }  }
231    
# Line 218  static void sigalrm_handler(int UNUSED_P Line 234  static void sigalrm_handler(int UNUSED_P
234  }  }
235    
236  int rx_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;  int rx_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
237  int rx_main(int argc, char **argv)  int rx_main(int argc UNUSED_PARAM, char **argv)
238  {  {
239   struct termios tty, orig_tty;   struct termios tty, orig_tty;
240   int termios_err;   int termios_err;
241   int file_fd;   int file_fd;
242   int n;   int n;
243    
  if (argc != 2)  
  bb_show_usage();  
   
244   /* Disabled by vda:   /* Disabled by vda:
245   * why we can't receive from stdin? Why we *require*   * why we can't receive from stdin? Why we *require*
246   * controlling tty?? */   * controlling tty?? */
247   /*read_fd = xopen(CURRENT_TTY, O_RDWR);*/   /*read_fd = xopen(CURRENT_TTY, O_RDWR);*/
248   file_fd = xopen(argv[1], O_RDWR|O_CREAT|O_TRUNC);   file_fd = xopen(single_argv(argv), O_RDWR|O_CREAT|O_TRUNC);
249    
250   termios_err = tcgetattr(read_fd, &tty);   termios_err = tcgetattr(read_fd, &tty);
251   if (termios_err == 0) {   if (termios_err == 0) {

Legend:
Removed from v.983  
changed lines
  Added in v.984