00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef CANFDX
00017 #include "zmodem.h"
00018 #endif
00019 int Rxtimeout = 100;
00020
00021 #ifndef UNSL
00022 #define UNSL
00023 #endif
00024
00025
00026
00027 int Rxframeind;
00028 int Rxtype;
00029 int Rxcount;
00030 char Rxhdr[4];
00031 char Txhdr[4];
00032 long Rxpos;
00033 long Txpos;
00034 int Txfcs32;
00035 int Crc32t;
00036 int Crc32;
00037 int Znulls;
00038 char Attn[ZATTNLEN+1];
00039
00040 static lastsent;
00041 static Not8bit;
00042
00043 static char *frametypes[] = {
00044 "Carrier Lost",
00045 "TIMEOUT",
00046 "ERROR",
00047 #define FTOFFSET 3
00048 "ZRQINIT",
00049 "ZRINIT",
00050 "ZSINIT",
00051 "ZACK",
00052 "ZFILE",
00053 "ZSKIP",
00054 "ZNAK",
00055 "ZABORT",
00056 "ZFIN",
00057 "ZRPOS",
00058 "ZDATA",
00059 "ZEOF",
00060 "ZFERR",
00061 "ZCRC",
00062 "ZCHALLENGE",
00063 "ZCOMPL",
00064 "ZCAN",
00065 "ZFREECNT",
00066 "ZCOMMAND",
00067 "ZSTDERR",
00068 "xxxxx"
00069 #define FRTYPES 22
00070
00071 };
00072
00073 static char badcrc[] = "Bad CRC";
00074
00075
00076 void zsbhdr(type, hdr)
00077 int type;
00078 register char *hdr;
00079 {
00080 register int n;
00081 register unsigned short crc;
00082
00083 vfile("zsbhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr));
00084 if (type == ZDATA)
00085 for (n = Znulls; --n >=0; )
00086 xsendline(0);
00087
00088 xsendline(ZPAD); xsendline(ZDLE);
00089
00090 if (Crc32t=Txfcs32)
00091 zsbh32(hdr, type);
00092 else {
00093 xsendline(ZBIN); zsendline(type); crc = updcrc(type, 0);
00094
00095 for (n=4; --n >= 0; ++hdr) {
00096 zsendline(*hdr);
00097 crc = updcrc((0377& *hdr), crc);
00098 }
00099 crc = updcrc(0,updcrc(0,crc));
00100 zsendline(crc>>8);
00101 zsendline(crc);
00102 }
00103 if (type != ZDATA)
00104 flushmo();
00105 }
00106
00107
00108
00109 void zsbh32(hdr, type)
00110 register char *hdr;
00111 int type;
00112 {
00113 register int n;
00114 register UNSL long crc;
00115
00116 xsendline(ZBIN32); zsendline(type);
00117 crc = 0xFFFFFFFFL; crc = UPDC32(type, crc);
00118
00119 for (n=4; --n >= 0; ++hdr) {
00120 crc = UPDC32((0377 & *hdr), crc);
00121 zsendline(*hdr);
00122 }
00123 crc = ~crc;
00124 for (n=4; --n >= 0;) {
00125 zsendline((int)crc);
00126 crc >>= 8;
00127 }
00128 }
00129
00130
00131 void zshhdr(type, hdr)
00132 int type;
00133 register char *hdr;
00134 {
00135 register int n;
00136 register unsigned short crc;
00137
00138 vfile("zshhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr));
00139 sendline(ZPAD); sendline(ZPAD); sendline(ZDLE); sendline(ZHEX);
00140 zputhex(type);
00141 Crc32t = 0;
00142
00143 crc = updcrc(type, 0);
00144 for (n=4; --n >= 0; ++hdr) {
00145 zputhex(*hdr); crc = updcrc((0377 & *hdr), crc);
00146 }
00147 crc = updcrc(0,updcrc(0,crc));
00148 zputhex(crc>>8); zputhex(crc);
00149
00150
00151 sendline(015); sendline(0212);
00152
00153
00154
00155 if (type != ZFIN && type != ZACK)
00156 sendline(021);
00157 flushmo();
00158 }
00159
00160
00161
00162
00163 static char *Zendnames[] = { "ZCRCE", "ZCRCG", "ZCRCQ", "ZCRCW"};
00164
00165 void zsdata(buf, length, frameend)
00166 register char *buf;
00167 int length;
00168 int frameend;
00169 {
00170 register unsigned short crc;
00171
00172 vfile("zsdata: %d %s", length, Zendnames[(frameend-ZCRCE)&3]);
00173 if (Crc32t)
00174 zsda32(buf, length, frameend);
00175 else {
00176 crc = 0;
00177 for (;--length >= 0; ++buf) {
00178 zsendline(*buf); crc = updcrc((0377 & *buf), crc);
00179 }
00180 xsendline(ZDLE); xsendline(frameend);
00181 crc = updcrc(frameend, crc);
00182
00183 crc = updcrc(0,updcrc(0,crc));
00184 zsendline(crc>>8); zsendline(crc);
00185 }
00186 if (frameend == ZCRCW) {
00187 xsendline(XON); flushmo();
00188 }
00189 }
00190
00191 void zsda32(buf, length, frameend)
00192 register char *buf;
00193 int length;
00194 int frameend;
00195 {
00196 register int c;
00197 register UNSL long crc;
00198
00199 crc = 0xFFFFFFFFL;
00200 for (;--length >= 0; ++buf) {
00201 c = *buf & 0377;
00202 if (c & 0140)
00203 xsendline(lastsent = c);
00204 else
00205 zsendline(c);
00206 crc = UPDC32(c, crc);
00207 }
00208 xsendline(ZDLE); xsendline(frameend);
00209 crc = UPDC32(frameend, crc);
00210
00211 crc = ~crc;
00212 for (length=4; --length >= 0;) {
00213 zsendline((int)crc); crc >>= 8;
00214 }
00215 }
00216
00217
00218
00219
00220
00221
00222 int zrdata(buf, length)
00223 register char *buf;
00224 int length;
00225 {
00226 register int c;
00227 register unsigned short crc;
00228 register char *end;
00229 register int d;
00230
00231 if (Rxframeind == ZBIN32)
00232 return zrdat32(buf, length);
00233
00234 crc = Rxcount = 0; end = buf + length;
00235 while (buf <= end) {
00236 if ((c = zdlread()) & ~0377) {
00237 crcfoo:
00238 switch (c) {
00239 case GOTCRCE:
00240 case GOTCRCG:
00241 case GOTCRCQ:
00242 case GOTCRCW:
00243 crc = updcrc((d=c)&0377, crc);
00244 if ((c = zdlread()) & ~0377)
00245 goto crcfoo;
00246 crc = updcrc(c, crc);
00247 if ((c = zdlread()) & ~0377)
00248 goto crcfoo;
00249 crc = updcrc(c, crc);
00250 if (crc & 0xFFFF) {
00251 zperr(badcrc);
00252 return ERROR;
00253 }
00254 Rxcount = length - (end - buf);
00255 vfile("zrdata: %d %s", Rxcount,
00256 Zendnames[(d-GOTCRCE)&3]);
00257 return d;
00258 case GOTCAN:
00259 zperr("Sender Canceled");
00260 return ZCAN;
00261 case TIMEOUT:
00262 zperr("TIMEOUT");
00263 return c;
00264 default:
00265 zperr("Bad data subpacket");
00266 return c;
00267 }
00268 }
00269 *buf++ = c;
00270 crc = updcrc(c, crc);
00271 }
00272 zperr("Data subpacket too long");
00273 return ERROR;
00274 }
00275
00276 int zrdat32(buf, length)
00277 register char *buf;
00278 int length;
00279 {
00280 register int c;
00281 register UNSL long crc;
00282 register char *end;
00283 register int d;
00284
00285 crc = 0xFFFFFFFFL; Rxcount = 0; end = buf + length;
00286 while (buf <= end) {
00287 if ((c = zdlread()) & ~0377) {
00288 crcfoo:
00289 switch (c) {
00290 case GOTCRCE:
00291 case GOTCRCG:
00292 case GOTCRCQ:
00293 case GOTCRCW:
00294 d = c; c &= 0377;
00295 crc = UPDC32(c, crc);
00296 if ((c = zdlread()) & ~0377)
00297 goto crcfoo;
00298 crc = UPDC32(c, crc);
00299 if ((c = zdlread()) & ~0377)
00300 goto crcfoo;
00301 crc = UPDC32(c, crc);
00302 if ((c = zdlread()) & ~0377)
00303 goto crcfoo;
00304 crc = UPDC32(c, crc);
00305 if ((c = zdlread()) & ~0377)
00306 goto crcfoo;
00307 crc = UPDC32(c, crc);
00308 if (crc != 0xDEBB20E3) {
00309 zperr(badcrc);
00310 return ERROR;
00311 }
00312 Rxcount = length - (end - buf);
00313 vfile("zrdat32: %d %s", Rxcount,
00314 Zendnames[(d-GOTCRCE)&3]);
00315 return d;
00316 case GOTCAN:
00317 zperr("Sender Canceled");
00318 return ZCAN;
00319 case TIMEOUT:
00320 zperr("TIMEOUT");
00321 return c;
00322 default:
00323 zperr("Bad data subpacket");
00324 return c;
00325 }
00326 }
00327 *buf++ = c;
00328 crc = UPDC32(c, crc);
00329 }
00330 zperr("Data subpacket too long");
00331 return ERROR;
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 int zgethdr(hdr, eflag)
00346 char *hdr;
00347 int eflag;
00348 {
00349 register int c, n, cancount;
00350
00351 n = Zrwindow + Baudrate;
00352 Rxframeind = Rxtype = 0;
00353
00354 startover:
00355 cancount = 5;
00356 again:
00357
00358 switch (c = readline(Rxtimeout)) {
00359 case RCDO:
00360 case TIMEOUT:
00361 goto fifi;
00362 case CAN:
00363 gotcan:
00364 if (--cancount <= 0) {
00365 c = ZCAN; goto fifi;
00366 }
00367 switch (c = readline(1)) {
00368 case TIMEOUT:
00369 goto again;
00370 case ZCRCW:
00371 c = ERROR;
00372
00373 case RCDO:
00374 goto fifi;
00375 default:
00376 break;
00377 case CAN:
00378 if (--cancount <= 0) {
00379 c = ZCAN; goto fifi;
00380 }
00381 goto again;
00382 }
00383
00384 default:
00385 agn2:
00386 if ( --n == 0) {
00387 zperr("Garbage count exceeded");
00388 return(ERROR);
00389 }
00390 if (eflag && ((c &= 0177) & 0140))
00391 bttyout(c);
00392 else if (eflag > 1)
00393 bttyout(c);
00394 #ifdef UNIX
00395 fflush(stderr);
00396 #endif
00397 goto startover;
00398 case ZPAD|0200:
00399 Not8bit = c;
00400 case ZPAD:
00401 break;
00402 }
00403 cancount = 5;
00404 splat:
00405 switch (c = noxrd7()) {
00406 case ZPAD:
00407 goto splat;
00408 case RCDO:
00409 case TIMEOUT:
00410 goto fifi;
00411 default:
00412 goto agn2;
00413 case ZDLE:
00414 break;
00415 }
00416
00417 switch (c = noxrd7()) {
00418 case RCDO:
00419 case TIMEOUT:
00420 goto fifi;
00421 case ZBIN:
00422 Rxframeind = ZBIN; Crc32 = FALSE;
00423 c = zrbhdr(hdr);
00424 break;
00425 case ZBIN32:
00426 Crc32 = Rxframeind = ZBIN32;
00427 c = zrbhdr32(hdr);
00428 break;
00429 case ZHEX:
00430 Rxframeind = ZHEX; Crc32 = FALSE;
00431 c = zrhhdr(hdr);
00432 break;
00433 case CAN:
00434 goto gotcan;
00435 default:
00436 goto agn2;
00437 }
00438 Rxpos = hdr[ZP3] & 0377;
00439 Rxpos = (Rxpos<<8) + (hdr[ZP2] & 0377);
00440 Rxpos = (Rxpos<<8) + (hdr[ZP1] & 0377);
00441 Rxpos = (Rxpos<<8) + (hdr[ZP0] & 0377);
00442 fifi:
00443 switch (c) {
00444 case GOTCAN:
00445 c = ZCAN;
00446
00447 case ZNAK:
00448 case ZCAN:
00449 case ERROR:
00450 case TIMEOUT:
00451 case RCDO:
00452 zperr("Got %s", frametypes[c+FTOFFSET]);
00453
00454 default:
00455 if (c >= -3 && c <= FRTYPES)
00456 vfile("zgethdr: %s %lx", frametypes[c+FTOFFSET], Rxpos);
00457 else
00458 vfile("zgethdr: %d %lx", c, Rxpos);
00459 }
00460 return c;
00461 }
00462
00463
00464 int zrbhdr(hdr)
00465 register char *hdr;
00466 {
00467 register int c, n;
00468 register unsigned short crc;
00469
00470 if ((c = zdlread()) & ~0377)
00471 return c;
00472 Rxtype = c;
00473 crc = updcrc(c, 0);
00474
00475 for (n=4; --n >= 0; ++hdr) {
00476 if ((c = zdlread()) & ~0377)
00477 return c;
00478 crc = updcrc(c, crc);
00479 *hdr = c;
00480 }
00481 if ((c = zdlread()) & ~0377)
00482 return c;
00483 crc = updcrc(c, crc);
00484 if ((c = zdlread()) & ~0377)
00485 return c;
00486 crc = updcrc(c, crc);
00487 if (crc & 0xFFFF) {
00488 zperr(badcrc);
00489 return ERROR;
00490 }
00491 #ifdef ZMODEM
00492 Protocol = ZMODEM;
00493 #endif
00494 Zmodem = 1;
00495 return Rxtype;
00496 }
00497
00498
00499 int zrbhdr32(hdr)
00500 register char *hdr;
00501 {
00502 register int c, n;
00503 register UNSL long crc;
00504
00505 if ((c = zdlread()) & ~0377)
00506 return c;
00507 Rxtype = c;
00508 crc = 0xFFFFFFFFL; crc = UPDC32(c, crc);
00509 #ifdef DEBUGZ
00510 vfile("zrbhdr32 c=%X crc=%lX", c, crc);
00511 #endif
00512
00513 for (n=4; --n >= 0; ++hdr) {
00514 if ((c = zdlread()) & ~0377)
00515 return c;
00516 crc = UPDC32(c, crc);
00517 *hdr = c;
00518 #ifdef DEBUGZ
00519 vfile("zrbhdr32 c=%X crc=%lX", c, crc);
00520 #endif
00521 }
00522 for (n=4; --n >= 0;) {
00523 if ((c = zdlread()) & ~0377)
00524 return c;
00525 crc = UPDC32(c, crc);
00526 #ifdef DEBUGZ
00527 vfile("zrbhdr32 c=%X crc=%lX", c, crc);
00528 #endif
00529 }
00530 if (crc != 0xDEBB20E3) {
00531 zperr(badcrc);
00532 return ERROR;
00533 }
00534 #ifdef ZMODEM
00535 Protocol = ZMODEM;
00536 #endif
00537 Zmodem = 1;
00538 return Rxtype;
00539 }
00540
00541
00542
00543 int zrhhdr(hdr)
00544 char *hdr;
00545 {
00546 register int c;
00547 register unsigned short crc;
00548 register int n;
00549
00550 if ((c = zgethex()) < 0)
00551 return c;
00552 Rxtype = c;
00553 crc = updcrc(c, 0);
00554
00555 for (n=4; --n >= 0; ++hdr) {
00556 if ((c = zgethex()) < 0)
00557 return c;
00558 crc = updcrc(c, crc);
00559 *hdr = c;
00560 }
00561 if ((c = zgethex()) < 0)
00562 return c;
00563 crc = updcrc(c, crc);
00564 if ((c = zgethex()) < 0)
00565 return c;
00566 crc = updcrc(c, crc);
00567 if (crc & 0xFFFF) {
00568 zperr(badcrc); return ERROR;
00569 }
00570 switch ( c = readline(1)) {
00571 case 0215:
00572 Not8bit = c;
00573
00574 case 015:
00575
00576 switch (c = readline(1)) {
00577 case 012:
00578 Not8bit |= c;
00579 }
00580 }
00581 #ifdef ZMODEM
00582 Protocol = ZMODEM;
00583 #endif
00584 Zmodem = 1; return Rxtype;
00585 }
00586
00587
00588 void zputhex(c)
00589 register int c;
00590 {
00591 static char digits[] = "0123456789abcdef";
00592
00593 if (Verbose>8)
00594 vfile("zputhex: %02X", c);
00595 sendline(digits[(c&0xF0)>>4]);
00596 sendline(digits[(c)&0xF]);
00597 }
00598
00599
00600
00601
00602
00603 void zsendline(c)
00604 int c;
00605 {
00606
00607
00608 if (c & 0140)
00609 xsendline(lastsent = c);
00610 else {
00611 switch (c &= 0377) {
00612 case ZDLE:
00613 xsendline(ZDLE);
00614 xsendline (lastsent = (c ^= 0100));
00615 break;
00616 case 015:
00617 case 0215:
00618 if (!Zctlesc && (lastsent & 0177) != '@')
00619 goto sendit;
00620
00621 case 020:
00622 case 021:
00623 case 023:
00624 case 0220:
00625 case 0221:
00626 case 0223:
00627 xsendline(ZDLE);
00628 c ^= 0100;
00629 sendit:
00630 xsendline(lastsent = c);
00631 break;
00632 default:
00633 if (Zctlesc && ! (c & 0140)) {
00634 xsendline(ZDLE);
00635 c ^= 0100;
00636 }
00637 xsendline(lastsent = c);
00638 }
00639 }
00640 }
00641
00642
00643 int zgethex()
00644 {
00645 register int c;
00646
00647 c = zgeth1();
00648 if (Verbose>8)
00649 vfile("zgethex: %02X", c);
00650 return c;
00651 }
00652 int zgeth1()
00653 {
00654 register int c, n;
00655
00656 if ((c = noxrd7()) < 0)
00657 return c;
00658 n = c - '0';
00659 if (n > 9)
00660 n -= ('a' - ':');
00661 if (n & ~0xF)
00662 return ERROR;
00663 if ((c = noxrd7()) < 0)
00664 return c;
00665 c -= '0';
00666 if (c > 9)
00667 c -= ('a' - ':');
00668 if (c & ~0xF)
00669 return ERROR;
00670 c += (n<<4);
00671 return c;
00672 }
00673
00674
00675
00676
00677
00678 int zdlread()
00679 {
00680 register int c;
00681
00682 again:
00683
00684 if ((c = readline(Rxtimeout)) & 0140)
00685 return c;
00686 switch (c) {
00687 case ZDLE:
00688 break;
00689 case 023:
00690 case 0223:
00691 case 021:
00692 case 0221:
00693 goto again;
00694 default:
00695 if (Zctlesc && !(c & 0140)) {
00696 goto again;
00697 }
00698 return c;
00699 }
00700 again2:
00701 if ((c = readline(Rxtimeout)) < 0)
00702 return c;
00703 if (c == CAN && (c = readline(Rxtimeout)) < 0)
00704 return c;
00705 if (c == CAN && (c = readline(Rxtimeout)) < 0)
00706 return c;
00707 if (c == CAN && (c = readline(Rxtimeout)) < 0)
00708 return c;
00709 switch (c) {
00710 case CAN:
00711 return GOTCAN;
00712 case ZCRCE:
00713 case ZCRCG:
00714 case ZCRCQ:
00715 case ZCRCW:
00716 return (c | GOTOR);
00717 case ZRUB0:
00718 return 0177;
00719 case ZRUB1:
00720 return 0377;
00721 case 023:
00722 case 0223:
00723 case 021:
00724 case 0221:
00725 goto again2;
00726 default:
00727 if (Zctlesc && ! (c & 0140)) {
00728 goto again2;
00729 }
00730 if ((c & 0140) == 0100)
00731 return (c ^ 0100);
00732 break;
00733 }
00734 if (Verbose>1)
00735 zperr("Bad escape sequence %x", c);
00736 return ERROR;
00737 }
00738
00739
00740
00741
00742
00743 int noxrd7()
00744 {
00745 register int c;
00746
00747 for (;;) {
00748 if ((c = readline(Rxtimeout)) < 0)
00749 return c;
00750 switch (c &= 0177) {
00751 case XON:
00752 case XOFF:
00753 continue;
00754 default:
00755 if (Zctlesc && !(c & 0140))
00756 continue;
00757 case '\r':
00758 case '\n':
00759 case ZDLE:
00760 return c;
00761 }
00762 }
00763 }
00764
00765
00766 void stohdr(pos)
00767 long pos;
00768 {
00769 Txhdr[ZP0] = pos;
00770 Txhdr[ZP1] = pos>>8;
00771 Txhdr[ZP2] = pos>>16;
00772 Txhdr[ZP3] = pos>>24;
00773 }
00774
00775
00776 long
00777 rclhdr(hdr)
00778 register char *hdr;
00779 {
00780 register long l;
00781
00782 l = (hdr[ZP3] & 0377);
00783 l = (l << 8) | (hdr[ZP2] & 0377);
00784 l = (l << 8) | (hdr[ZP1] & 0377);
00785 l = (l << 8) | (hdr[ZP0] & 0377);
00786 return l;
00787 }
00788
00789