Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1376 lines
33 KiB

  1. /* zmdm.c -- Routines to handle zmodem for HyperACCESS
  2. *
  3. * Copyright 1990 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 13 $
  7. * $Date: 7/12/02 8:36a $
  8. */
  9. /*
  10. * Z M . C
  11. * ZMODEM protocol primitives
  12. * 05-09-88 Chuck Forsberg Omen Technology Inc
  13. *
  14. * Entry point Functions:
  15. * zsbhdr(type, hdr) send binary header
  16. * zshhdr(type, hdr) send hex header
  17. * zgethdr(hdr, eflag) receive header - binary or hex
  18. * zsdata(buf, len, frameend) send data
  19. * zrdata(buf, len) receive data
  20. * stohdr(pos) store position data in Txhdr
  21. * long rclhdr(hdr) recover position offset from header
  22. */
  23. #include <windows.h>
  24. #pragma hdrstop
  25. #include <setjmp.h>
  26. #define BYTE unsigned char
  27. #include <tdll\stdtyp.h>
  28. #include <tdll\com.h>
  29. #include <tdll\assert.h>
  30. #include <tdll\session.h>
  31. #include <tdll\file_io.h>
  32. #include "xfr_srvc.h"
  33. #include "xfr_todo.h"
  34. #include "xfr_dsp.h"
  35. #include "xfer_tsc.h"
  36. #include "foo.h"
  37. #include "zmodem.hh"
  38. #include "zmodem.h"
  39. #if defined(DEBUG_DUMPPACKET)
  40. #include <stdio.h>
  41. extern FILE* fpPacket;
  42. void DbgDumpPacket(ZC* zc, BYTE* buf, int nLength);
  43. #endif // defined(DEBUG_DUMPPACKET)
  44. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  45. * readline - added to get all this stuff to match up
  46. *
  47. */
  48. /*----------------------------------------------------------------------+
  49. | zmdm_rl
  50. +----------------------------------------------------------------------*/
  51. int zmdm_rl (ZC *zc, int timeout)
  52. {
  53. TCHAR c;
  54. int x;
  55. int n;
  56. long elapsed_time;
  57. elapsed_time = (long)startinterval();
  58. // if ((c = rdget(zc)) == (-1))
  59. if ((n = mComRcvChar(zc->hCom, &c)) == 0)
  60. {
  61. xfer_idle(zc->hSession, XFER_IDLE_IO);
  62. while (((long)interval(elapsed_time) <= (long)timeout) && (n == 0))
  63. {
  64. //
  65. // We don't want to keep attempting to receive data
  66. // if we have lost the connection. REV: 08/22/2001.
  67. //
  68. if (xfer_carrier_lost(zc->hSession))
  69. {
  70. return (ZCARRIER_LOST);
  71. }
  72. x = xfer_user_interrupt(zc->hSession);
  73. switch (x)
  74. {
  75. case XFER_ABORT:
  76. zmdmr_update(zc, ZCAN);
  77. longjmp(zc->flagkey_buf, 1);
  78. break;
  79. case XFER_SKIP:
  80. /* This MUST only happen while receiving */
  81. stohdr(zc, zc->filesize);
  82. zshhdr(zc, ZRPOS, zc->Txhdr);
  83. zc->nSkip = TRUE;
  84. zc->file_bytes = zc->filesize;
  85. break;
  86. default:
  87. break;
  88. }
  89. //
  90. // We don't want to keep attempting to receive data
  91. // if we have lost the connection. REV: 08/22/2001.
  92. //
  93. if (xfer_carrier_lost(zc->hSession))
  94. {
  95. return (ZCARRIER_LOST);
  96. }
  97. xfer_idle(zc->hSession, XFER_IDLE_IO);
  98. // c = rdget(zc);
  99. n = mComRcvChar(zc->hCom, &c);
  100. }
  101. if (n == 0)
  102. {
  103. c = TIMEOUT;
  104. }
  105. }
  106. return (c);
  107. }
  108. /*----------------------------------------------------------------------+
  109. | zsbhdr - Send ZMODEM binary header hdr of type type.
  110. +----------------------------------------------------------------------*/
  111. void zsbhdr(ZC *zc, int type, BYTE *hdr)
  112. {
  113. register int n;
  114. register unsigned short crc;
  115. xsendline(zc, &zc->stP, ZPAD);
  116. xsendline(zc, &zc->stP, ZDLE);
  117. if (zc->Crc32t = zc->Txfcs32)
  118. zsbh32(zc, hdr, type);
  119. else
  120. {
  121. xsendline(zc, &zc->stP, ZBIN);
  122. zsendline(zc, type);
  123. crc = updcrc(zc, type, 0);
  124. for (n=4; --n >= 0; ++hdr)
  125. {
  126. zsendline(zc, *hdr);
  127. crc = updcrc(zc, (0377& *hdr), crc);
  128. }
  129. crc = updcrc(zc, 0,crc);
  130. crc = updcrc(zc, 0,crc);
  131. zsendline(zc, (int)crc>>8);
  132. zsendline(zc, (int)crc);
  133. }
  134. if (type != ZDATA)
  135. flushmo(zc, &zc->stP);
  136. // xfer_idle(zc->hSession, XFER_IDLE_IO);
  137. }
  138. /*----------------------------------------------------------------------+
  139. | zsbh32 - Send ZMODEM binary header hdr of type type.
  140. +----------------------------------------------------------------------*/
  141. void zsbh32(ZC *zc, BYTE *hdr, int type)
  142. {
  143. register int n;
  144. register unsigned long crc;
  145. xsendline(zc, &zc->stP, ZBIN32);
  146. zsendline(zc, type);
  147. crc = 0xFFFFFFFFL;
  148. crc = UPDC32(zc, type, crc);
  149. for (n=4; --n >= 0; ++hdr)
  150. {
  151. crc = UPDC32(zc, (0377 & *hdr), crc);
  152. zsendline(zc, *hdr);
  153. }
  154. crc = ~crc;
  155. for (n=4; --n >= 0;)
  156. {
  157. zsendline(zc, (int)crc);
  158. crc >>= 8;
  159. }
  160. flushmo(zc, &zc->stP);
  161. // xfer_idle(zc->hSession, XFER_IDLE_IO);
  162. }
  163. /*----------------------------------------------------------------------+
  164. | zshhdr - Send ZMODEM HEX header hdr of type type.
  165. +----------------------------------------------------------------------*/
  166. void zshhdr(ZC *zc, int type, BYTE *hdr)
  167. {
  168. register int n;
  169. register unsigned short crc;
  170. sendline(zc, &zc->stP, ZPAD);
  171. sendline(zc, &zc->stP, ZPAD);
  172. sendline(zc, &zc->stP, ZDLE);
  173. sendline(zc, &zc->stP, ZHEX);
  174. zputhex(zc, type);
  175. zc->Crc32t = 0;
  176. crc = updcrc(zc, type, 0);
  177. for (n=4; --n >= 0; ++hdr)
  178. {
  179. zputhex(zc, *hdr);
  180. crc = updcrc(zc, (0377 & *hdr), crc);
  181. }
  182. crc = updcrc(zc, 0, crc);
  183. crc = updcrc(zc, 0,crc);
  184. zputhex(zc, crc>>8);
  185. zputhex(zc, crc);
  186. /* Make it printable on remote machine */
  187. sendline(zc, &zc->stP, 015);
  188. sendline(zc, &zc->stP, 0212);
  189. /*
  190. * Uncork the remote in case a fake XOFF has stopped data flow
  191. */
  192. if (type != ZFIN && type != ZACK)
  193. sendline(zc, &zc->stP, 021);
  194. flushmo(zc, &zc->stP);
  195. // xfer_idle(zc->hSession, XFER_IDLE_IO);
  196. }
  197. /*----------------------------------------------------------------------+
  198. | zsdata - Send binary array buf of lengthl length, with ending ZDLE
  199. | sequence frameend.
  200. +----------------------------------------------------------------------*/
  201. void zsdata(ZC *zc, BYTE *buf, int length, int frameend)
  202. {
  203. register unsigned short crc;
  204. // xfer_idle(zc->hSession, XFER_IDLE_IO);
  205. if (zc->Crc32t)
  206. zsda32(zc, buf, length, frameend);
  207. else
  208. {
  209. crc = 0;
  210. for (;--length >= 0; ++buf)
  211. {
  212. zsendline(zc, *buf);
  213. crc = updcrc(zc, (0377 & *buf), crc);
  214. }
  215. xsendline(zc, &zc->stP, ZDLE);
  216. xsendline(zc, &zc->stP, (UCHAR)frameend);
  217. crc = updcrc(zc, frameend, crc);
  218. crc = updcrc(zc, 0, crc);
  219. crc = updcrc(zc, 0, crc);
  220. zsendline(zc, (int)crc>>8);
  221. zsendline(zc, (int)crc);
  222. }
  223. if (frameend == ZCRCW)
  224. {
  225. xsendline(zc, &zc->stP, XON);
  226. flushmo(zc, &zc->stP);
  227. }
  228. // xfer_idle(zc->hSession, XFER_IDLE_IO);
  229. }
  230. /*----------------------------------------------------------------------+
  231. | zsda32
  232. +----------------------------------------------------------------------*/
  233. void zsda32(ZC *zc, BYTE *buf, int length, int frameend)
  234. {
  235. register int c;
  236. register unsigned long crc;
  237. crc = 0xFFFFFFFFL;
  238. for (;--length >= 0; ++buf)
  239. {
  240. c = *buf & 0377;
  241. if (c & 0140)
  242. {
  243. zc->lastsent = c;
  244. xsendline(zc, &zc->stP, ((UCHAR)c));
  245. }
  246. else
  247. zsendline(zc, c);
  248. crc = UPDC32(zc, c, crc);
  249. }
  250. xsendline(zc, &zc->stP, ZDLE);
  251. xsendline(zc, &zc->stP, (UCHAR)frameend);
  252. crc = UPDC32(zc, frameend, crc);
  253. crc = ~crc;
  254. for (length=4; --length >= 0;)
  255. {
  256. zsendline(zc, (int)crc);
  257. crc >>= 8;
  258. }
  259. }
  260. /*----------------------------------------------------------------------+
  261. | zrdata - Receive array buf of max length with ending ZDLE sequence and
  262. | CRC. Returns the ending character or error code. NB: On
  263. | errors may store length+1 bytes!
  264. +----------------------------------------------------------------------*/
  265. int zrdata(ZC *zc, BYTE *buf, int length)
  266. {
  267. register int c;
  268. register unsigned short crc;
  269. register BYTE *end;
  270. register int d;
  271. if (zc->Rxframeind == ZBIN32)
  272. return zrdat32(zc, buf, length);
  273. crc = zc->Rxcount = 0;
  274. end = buf + length;
  275. //
  276. // Don't overrun the buffer. We used to overrun the buffer when
  277. // *buf++ = (char)c; is executed at the botton of the loop when
  278. // buf == end. REV: 4/4/2002
  279. //
  280. while (buf < end)
  281. {
  282. if ((c = zdlread(zc)) & ~0377)
  283. {
  284. crcfoo1:
  285. switch (c)
  286. {
  287. case GOTCRCE:
  288. case GOTCRCG:
  289. case GOTCRCQ:
  290. case GOTCRCW:
  291. crc = updcrc(zc, (d=c)&0377, crc);
  292. if ((c = zdlread(zc)) & ~0377)
  293. goto crcfoo1;
  294. crc = updcrc(zc, c, crc);
  295. if ((c = zdlread(zc)) & ~0377)
  296. goto crcfoo1;
  297. crc = updcrc(zc, c, crc);
  298. if (crc & 0xFFFF)
  299. {
  300. /* zperr(badcrc); */
  301. #if defined(DEBUG_DUMPPACKET)
  302. fprintf(fpPacket, "zrdata: Bad CRC 0x%04X\n", crc);
  303. DbgDumpPacket(zc, end - length, length - (end - buf));
  304. #endif // defined(DEBUG_DUMPPACKET)
  305. zmdmr_update (zc, ERROR);
  306. return ERROR;
  307. }
  308. zc->Rxcount = (int)(length - (end - buf));
  309. return d;
  310. case GOTCAN:
  311. /* zperr("Sender Canceled"); */
  312. zmdmr_update (zc, ZCAN);
  313. return ZCAN;
  314. case TIMEOUT:
  315. /* zperr("TIMEOUT"); */
  316. #if defined(DEBUG_DUMPPACKET)
  317. fputs("zrdata: Timed-out\n", fpPacket);
  318. #endif // defined(DEBUG_DUMPPACKET)
  319. zmdmr_update(zc, TIMEOUT);
  320. return c;
  321. default:
  322. /* zperr("Bad data subpacket"); */
  323. #if defined(DEBUG_DUMPPACKET)
  324. fprintf(fpPacket, "zrdata: Bad data subpacket c=%d\n", c);
  325. #endif // defined(DEBUG_DUMPPACKET)
  326. zmdmr_update(zc, ZBADFMT);
  327. return c;
  328. }
  329. }
  330. *buf++ = (char)c;
  331. crc = updcrc(zc, c, crc);
  332. }
  333. /* zperr("Data subpacket too long"); */
  334. DbgOutStr("ZMODEM error %s %d\r\n", TEXT(__FILE__), __LINE__,0,0,0);
  335. #if defined(DEBUG_DUMPPACKET)
  336. fputs("zrdata: Data subpacket too long\n", fpPacket);
  337. #endif // defined(DEBUG_DUMPPACKET)
  338. zmdmr_update(zc, ZBADFMT);
  339. return ERROR;
  340. }
  341. /*----------------------------------------------------------------------+
  342. | zrdat32
  343. +----------------------------------------------------------------------*/
  344. int zrdat32(ZC *zc, BYTE *buf, int length)
  345. {
  346. register int c;
  347. register unsigned long crc;
  348. register BYTE *end;
  349. register int d;
  350. crc = 0xFFFFFFFFL;
  351. zc->Rxcount = 0;
  352. end = buf + length;
  353. while (buf <= end)
  354. {
  355. if ((c = zdlread(zc)) & ~0377)
  356. {
  357. crcfoo:
  358. switch (c)
  359. {
  360. case GOTCRCE:
  361. case GOTCRCG:
  362. case GOTCRCQ:
  363. case GOTCRCW:
  364. d = c;
  365. c &= 0377;
  366. crc = UPDC32(zc, c, crc);
  367. if ((c = zdlread(zc)) & ~0377)
  368. goto crcfoo;
  369. crc = UPDC32(zc, c, crc);
  370. if ((c = zdlread(zc)) & ~0377)
  371. goto crcfoo;
  372. crc = UPDC32(zc, c, crc);
  373. if ((c = zdlread(zc)) & ~0377)
  374. goto crcfoo;
  375. crc = UPDC32(zc, c, crc);
  376. if ((c = zdlread(zc)) & ~0377)
  377. goto crcfoo;
  378. crc = UPDC32(zc, c, crc);
  379. if (crc != 0xDEBB20E3)
  380. {
  381. /* zperr(badcrc); */
  382. DbgOutStr("ZMODEM error %s %d\r\n", TEXT(__FILE__), __LINE__,0,0,0);
  383. #if defined(DEBUG_DUMPPACKET)
  384. fprintf(fpPacket, "zrdat32: Bad 32-bit CRC 0x%08lX\n", crc);
  385. DbgDumpPacket(zc, end - length, length - (end - buf));
  386. #endif // defined(DEBUG_DUMPPACKET)
  387. zmdmr_update (zc, ERROR);
  388. return ERROR;
  389. }
  390. zc->Rxcount = (int)(length - (end - buf));
  391. return d;
  392. case GOTCAN:
  393. /* zperr("Sender Canceled"); */
  394. DbgOutStr("ZMODEM error %s %d\r\n", TEXT(__FILE__), __LINE__,0,0,0);
  395. zmdmr_update (zc, ZCAN);
  396. return ZCAN;
  397. case TIMEOUT:
  398. /* zperr("TIMEOUT"); */
  399. DbgOutStr("ZMODEM error %s %d\r\n", TEXT(__FILE__), __LINE__,0,0,0);
  400. #if defined(DEBUG_DUMPPACKET)
  401. fputs("zrdata: Timed-out\n", fpPacket);
  402. #endif // defined(DEBUG_DUMPPACKET)
  403. zmdmr_update (zc, TIMEOUT);
  404. return c;
  405. default:
  406. /* zperr("Bad data subpacket"); */
  407. DbgOutStr("ZMODEM error %s %d\r\n", TEXT(__FILE__), __LINE__,0,0,0);
  408. #ifdef DEBUG_DUMPPACKET
  409. fputs("zrdat32: Bad data subpacket\n", fpPacket);
  410. #endif // defined(DEBUG_DUMPPACKET)
  411. zmdmr_update (zc, ZBADFMT);
  412. return c;
  413. }
  414. }
  415. *buf++ = (char)c;
  416. crc = UPDC32(zc, c, crc);
  417. }
  418. /* zperr("Data subpacket too long"); */
  419. DbgOutStr("ZMODEM error %s %d\r\n", TEXT(__FILE__), __LINE__,0,0,0);
  420. #ifdef DEBUG_DUMPPACKET
  421. fputs("zrdat32: Data subpacket too long\n", fpPacket);
  422. #endif // defined(DEBUG_DUMPPACKET)
  423. zmdmr_update (zc, ZBADFMT);
  424. return ERROR;
  425. }
  426. #if defined(DEBUG_DUMPPACKET)
  427. void DbgDumpPacket(ZC *zc, BYTE *buf, int length)
  428. {
  429. int nCount;
  430. int jj;
  431. fputs("Here's the offending packet:\n", fpPacket);
  432. for (nCount = 0; nCount < length; nCount += 16)
  433. {
  434. for (jj = nCount; jj < nCount + 16 && jj < length; jj += 1)
  435. {
  436. fprintf(fpPacket, "%02X ", (unsigned int) buf[jj]);
  437. }
  438. fputs("\n", fpPacket);
  439. }
  440. }
  441. #endif // defined(DEBUG_DUMPPACKET)
  442. /*----------------------------------------------------------------------+
  443. | zgethdr - Read a ZMODEM header to hdr, either binary or HEX.
  444. | On success, set Rxpos and return type of header.
  445. | Otherwise return negative on error.
  446. | Return ERROR instantly if ZCRCW sequence, for fast error recovery.
  447. +----------------------------------------------------------------------*/
  448. int zgethdr(ZC *zc, BYTE *hdr, int eflag)
  449. {
  450. register int c;
  451. register int n;
  452. register int cancount;
  453. /* Max bytes before start of frame */
  454. // n = zc->Zrwindow + (int)cnfg.bit_rate;
  455. n = zc->Zrwindow + cnfgBitRate();
  456. zc->Rxframeind = ZHEX;
  457. zc->Rxtype = 0;
  458. startover:
  459. cancount = 5;
  460. again:
  461. /* Return immediate ERROR if ZCRCW sequence seen */
  462. switch (c = readline(zc, zc->Rxtimeout))
  463. {
  464. case ZCARRIER_LOST:
  465. case RCDO:
  466. case TIMEOUT:
  467. goto fifi;
  468. case CAN:
  469. gotcan:
  470. if (--cancount <= 0)
  471. {
  472. c = ZCAN;
  473. goto fifi;
  474. }
  475. // switch (c = readline(h, 1))
  476. switch (c = readline(zc, zc->Rxtimeout)) // Mobidem
  477. {
  478. case TIMEOUT:
  479. goto again;
  480. case ZCRCW:
  481. #if defined(DEBUG_DUMPPACKET)
  482. fputs("zgethdr: ZCRCW ret from readline\n", fpPacket);
  483. #endif // defined(DEBUG_DUMPPACKET)
  484. c = ERROR;
  485. /* **** FALL THRU TO **** */
  486. case RCDO:
  487. goto fifi;
  488. default:
  489. break;
  490. case CAN:
  491. if (--cancount <= 0)
  492. {
  493. c = ZCAN;
  494. goto fifi;
  495. }
  496. goto again;
  497. }
  498. /* **** FALL THRU TO **** */
  499. default:
  500. agn2:
  501. if ( --n == 0)
  502. {
  503. /* zperr("Garbage count exceeded"); */
  504. DbgOutStr("ZMODEM error %s %d\r\n", TEXT(__FILE__), __LINE__,0,0,0);
  505. #if defined(DEBUG_DUMPPACKET)
  506. fputs("zgethdr: Garbage count exceeded\n", fpPacket);
  507. #endif // defined(DEBUG_DUMPPACKET)
  508. return(ERROR);
  509. }
  510. goto startover;
  511. case ZPAD|0200: /* This is what we want. */
  512. zc->Not8bit = c;
  513. case ZPAD: /* This is what we want. */
  514. break;
  515. }
  516. cancount = 5;
  517. splat:
  518. switch (c = noxrd7(zc))
  519. {
  520. case ZPAD:
  521. goto splat;
  522. case RCDO:
  523. case TIMEOUT:
  524. goto fifi;
  525. default:
  526. goto agn2;
  527. case ZDLE: /* This is what we want. */
  528. break;
  529. }
  530. switch (c = noxrd7(zc))
  531. {
  532. case RCDO:
  533. case TIMEOUT:
  534. goto fifi;
  535. case ZBIN:
  536. zc->Rxframeind = ZBIN;
  537. zc->Crc32 = FALSE;
  538. c = zrbhdr(zc, hdr, eflag);
  539. break;
  540. case ZBIN32:
  541. zc->Crc32 = ZBIN32;
  542. zc->Rxframeind = ZBIN32;
  543. c = zrbhdr32(zc, hdr, eflag);
  544. break;
  545. case ZHEX:
  546. zc->Rxframeind = ZHEX;
  547. zc->Crc32 = FALSE;
  548. c = zrhhdr(zc, hdr, eflag);
  549. break;
  550. case CAN:
  551. goto gotcan;
  552. default:
  553. goto agn2;
  554. }
  555. zc->Rxpos = hdr[ZP3] & 0377;
  556. zc->Rxpos = (zc->Rxpos<<8) + (hdr[ZP2] & 0377);
  557. zc->Rxpos = (zc->Rxpos<<8) + (hdr[ZP1] & 0377);
  558. zc->Rxpos = (zc->Rxpos<<8) + (hdr[ZP0] & 0377);
  559. fifi:
  560. switch (c)
  561. {
  562. case GOTCAN:
  563. c = ZCAN;
  564. break;
  565. case ZNAK:
  566. case ZCAN:
  567. case ERROR:
  568. case TIMEOUT:
  569. case RCDO:
  570. case ZCARRIER_LOST:
  571. break;
  572. default:
  573. break;
  574. }
  575. if (eflag == 'T')
  576. {
  577. zmdms_update(zc, c);
  578. }
  579. else if (eflag == 'R')
  580. {
  581. zmdmr_update(zc, c);
  582. }
  583. return c;
  584. }
  585. /*----------------------------------------------------------------------+
  586. | zrbhdr - Receive a binary style header (type and position).
  587. +----------------------------------------------------------------------*/
  588. int zrbhdr(ZC *zc, BYTE *hdr, int eflag)
  589. {
  590. register int c, n;
  591. register unsigned short crc;
  592. if ((c = zdlread(zc)) & ~0377)
  593. return c;
  594. zc->Rxtype = c;
  595. crc = updcrc(zc, c, 0);
  596. for (n=4; --n >= 0; ++hdr)
  597. {
  598. if ((c = zdlread(zc)) & ~0377)
  599. return c;
  600. crc = updcrc(zc, c, crc);
  601. *hdr = (char)c;
  602. }
  603. if ((c = zdlread(zc)) & ~0377)
  604. return c;
  605. crc = updcrc(zc, c, crc);
  606. if ((c = zdlread(zc)) & ~0377)
  607. return c;
  608. crc = updcrc(zc, c, crc);
  609. if (crc & 0xFFFF)
  610. {
  611. /* zperr(badcrc); */
  612. DbgOutStr("ZMODEM error %s %d\r\n", TEXT(__FILE__), __LINE__,0,0,0);
  613. if (eflag == 'T')
  614. zmdms_update(zc, ERROR);
  615. else if (eflag == 'R')
  616. {
  617. #if defined(DEBUG_DUMPPACKET)
  618. fprintf(fpPacket, "zrbhdr: Bad CRC 0x%04X\n", crc);
  619. #endif // defined(DEBUG_DUMPPACKET)
  620. zmdmr_update(zc, ERROR);
  621. }
  622. return ERROR;
  623. }
  624. return zc->Rxtype;
  625. }
  626. /*----------------------------------------------------------------------+
  627. | zrbhdr32 - Receive a binary style header (type and position) with
  628. | 32 bit FCS.
  629. +----------------------------------------------------------------------*/
  630. int zrbhdr32(ZC *zc, BYTE *hdr, int eflag)
  631. {
  632. register int c, n;
  633. register unsigned long crc;
  634. if ((c = zdlread(zc)) & ~0377)
  635. return c;
  636. zc->Rxtype = c;
  637. crc = 0xFFFFFFFFL;
  638. crc = UPDC32(zc, c, crc);
  639. for (n=4; --n >= 0; ++hdr)
  640. {
  641. if ((c = zdlread(zc)) & ~0377)
  642. return c;
  643. crc = UPDC32(zc, c, crc);
  644. *hdr = (char)c;
  645. }
  646. for (n=4; --n >= 0;)
  647. {
  648. if ((c = zdlread(zc)) & ~0377)
  649. return c;
  650. crc = UPDC32(zc, c, crc);
  651. }
  652. if (crc != 0xDEBB20E3)
  653. {
  654. /* zperr(badcrc); */
  655. DbgOutStr("ZMODEM error %s %d\r\n", TEXT(__FILE__), __LINE__,0,0,0);
  656. if (eflag == 'T')
  657. zmdms_update(zc, ERROR);
  658. else if (eflag == 'R')
  659. {
  660. #if defined(DEBUG_DUMPPACKET)
  661. fprintf(fpPacket, "zrbhdr32: Bad CRC 0x%08lX\n", crc);
  662. #endif // defined(DEBUG_DUMPPACKET)
  663. zmdmr_update(zc, ERROR);
  664. }
  665. return ERROR;
  666. }
  667. return zc->Rxtype;
  668. }
  669. /*----------------------------------------------------------------------+
  670. | zrhhdr - Receive a hex style header (type and postion).
  671. +----------------------------------------------------------------------*/
  672. int zrhhdr(ZC *zc, BYTE *hdr, int eflag)
  673. {
  674. register int c;
  675. register unsigned short crc;
  676. register int n;
  677. if ((c = zgethex(zc)) < 0)
  678. return c;
  679. zc->Rxtype = c;
  680. crc = updcrc(zc, c, 0);
  681. for (n=4; --n >= 0; ++hdr)
  682. {
  683. if ((c = zgethex(zc)) < 0)
  684. return c;
  685. crc = updcrc(zc, c, crc);
  686. *hdr = (char)c;
  687. }
  688. if ((c = zgethex(zc)) < 0)
  689. return c;
  690. crc = updcrc(zc, c, crc);
  691. if ((c = zgethex(zc)) < 0)
  692. return c;
  693. crc = updcrc(zc, c, crc);
  694. if (crc & 0xFFFF)
  695. {
  696. /* zperr(badcrc); */
  697. DbgOutStr("ZMODEM error %s %d\r\n", TEXT(__FILE__), __LINE__,0,0,0);
  698. if (eflag == 'T')
  699. zmdms_update(zc, ERROR);
  700. else if (eflag == 'R')
  701. {
  702. #if defined(DEBUG_DUMPPACKET)
  703. fprintf(fpPacket, "zrhhdr: Bad CRC 0x%04X\n", crc);
  704. #endif // defined(DEBUG_DUMPPACKET)
  705. zmdmr_update(zc, ERROR);
  706. }
  707. return ERROR;
  708. }
  709. // switch ( c = readline(h, 1))
  710. switch ( c = readline(zc, zc->Rxtimeout)) // Mobidem
  711. {
  712. case 0215:
  713. zc->Not8bit = c;
  714. /* **** FALL THRU TO **** */
  715. case 015:
  716. /* Throw away possible cr/lf */
  717. // switch (c = readline(h, 1))
  718. switch (c = readline(zc, zc->Rxtimeout)) // Mobidem
  719. {
  720. case 012:
  721. zc->Not8bit |= c;
  722. }
  723. }
  724. return zc->Rxtype;
  725. }
  726. /*----------------------------------------------------------------------+
  727. | zputhex - Send a byte as two hex digits.
  728. +----------------------------------------------------------------------*/
  729. void zputhex(ZC *zc, int c)
  730. {
  731. static BYTE digits[] = "0123456789abcdef";
  732. sendline(zc, &zc->stP, digits[(c&0xF0)>>4]);
  733. sendline(zc, &zc->stP, digits[(c)&0xF]);
  734. }
  735. /*----------------------------------------------------------------------+
  736. | zsendline - Send character c with ZMODEM escape sequence encoding.
  737. | Escape XON, XOFF. Escape CR following @ (Telnet net escape).
  738. +----------------------------------------------------------------------*/
  739. void zsendline(ZC *zc, int c)
  740. {
  741. /* Quick check for non control characters */
  742. if (c & 0140)
  743. {
  744. zc->lastsent = c;
  745. xsendline(zc, &zc->stP, ((UCHAR)c));
  746. }
  747. else
  748. {
  749. switch (c &= 0377)
  750. {
  751. case ZDLE:
  752. xsendline(zc, &zc->stP, ZDLE);
  753. xsendline(zc, &zc->stP, (UCHAR)(zc->lastsent = (c ^= 0100)));
  754. break;
  755. case 015:
  756. case 0215:
  757. if (!zc->Zctlesc && (zc->lastsent & 0177) != '@')
  758. goto sendit;
  759. /* **** FALL THRU TO **** */
  760. case 020:
  761. case 021:
  762. case 023:
  763. case 0220:
  764. case 0221:
  765. case 0223:
  766. xsendline(zc, &zc->stP, ZDLE);
  767. c ^= 0100;
  768. sendit:
  769. xsendline(zc, &zc->stP, (UCHAR)(zc->lastsent = c));
  770. break;
  771. default:
  772. if (zc->Zctlesc && ! (c & 0140))
  773. {
  774. xsendline(zc, &zc->stP, ZDLE);
  775. c ^= 0100;
  776. }
  777. xsendline(zc, &zc->stP, (UCHAR)(zc->lastsent = c));
  778. }
  779. }
  780. }
  781. /*----------------------------------------------------------------------+
  782. | zgethex - Decode two lower case hex digits into an 8 bit byte value.
  783. +----------------------------------------------------------------------*/
  784. int zgethex(ZC *zc)
  785. {
  786. register int c;
  787. c = zgeth1(zc);
  788. return c;
  789. }
  790. /*----------------------------------------------------------------------+
  791. | zgeth1
  792. +----------------------------------------------------------------------*/
  793. int zgeth1(ZC *zc)
  794. {
  795. register int c, n;
  796. if ((c = noxrd7(zc)) < 0)
  797. return c;
  798. n = c - '0';
  799. if (n > 9)
  800. n -= ('a' - ':');
  801. if (n & ~0xF)
  802. {
  803. #if defined(DEBUG_DUMPPACKET)
  804. fprintf(fpPacket, "zgeth1: n = 0x%02X\n", n);
  805. #endif // defined(DEBUG_DUMPPACKET)
  806. return ERROR;
  807. }
  808. if ((c = noxrd7(zc)) < 0)
  809. return c;
  810. c -= '0';
  811. if (c > 9)
  812. c -= ('a' - ':');
  813. if (c & ~0xF)
  814. {
  815. #if defined(DEBUG_DUMPPACKET)
  816. fprintf(fpPacket, "zgeth1: c = 0x%02X\n", c);
  817. #endif // defined(DEBUG_DUMPPACKET)
  818. return ERROR;
  819. }
  820. c += (n<<4);
  821. return c;
  822. }
  823. /*----------------------------------------------------------------------+
  824. | zdlread - Read a byte, checking for ZMODEM escape encoding including
  825. | CAN*5 which represents a quick abort.
  826. +----------------------------------------------------------------------*/
  827. int zdlread(ZC *zc)
  828. {
  829. register int c;
  830. again:
  831. /* Quick check for non control characters */
  832. if ((c = readline(zc, zc->Rxtimeout)) & 0140)
  833. return c;
  834. switch (c)
  835. {
  836. case ZDLE:
  837. break;
  838. case 023:
  839. case 0223:
  840. case 021:
  841. case 0221:
  842. goto again;
  843. default:
  844. if (zc->Zctlesc && !(c & 0140))
  845. {
  846. goto again;
  847. }
  848. return c;
  849. }
  850. again2:
  851. if ((c = readline(zc, zc->Rxtimeout)) < 0)
  852. return c;
  853. if (c == CAN && (c = readline(zc, zc->Rxtimeout)) < 0)
  854. return c;
  855. if (c == CAN && (c = readline(zc, zc->Rxtimeout)) < 0)
  856. return c;
  857. if (c == CAN && (c = readline(zc, zc->Rxtimeout)) < 0)
  858. return c;
  859. switch (c)
  860. {
  861. case CAN:
  862. return GOTCAN;
  863. case ZCRCE:
  864. case ZCRCG:
  865. case ZCRCQ:
  866. case ZCRCW:
  867. return (c | GOTOR);
  868. case ZRUB0:
  869. return 0177;
  870. case ZRUB1:
  871. return 0377;
  872. case 023:
  873. case 0223:
  874. case 021:
  875. case 0221:
  876. goto again2;
  877. default:
  878. if (zc->Zctlesc && ! (c & 0140))
  879. {
  880. goto again2;
  881. }
  882. if ((c & 0140) == 0100)
  883. return (c ^ 0100);
  884. break;
  885. }
  886. return ERROR;
  887. }
  888. /*----------------------------------------------------------------------+
  889. | noxrd7 - Read a character from the modem line with timeout.
  890. | Eat parity, XON and XOFF characters.
  891. +----------------------------------------------------------------------*/
  892. int noxrd7(ZC *zc)
  893. {
  894. register int c;
  895. for (;;)
  896. {
  897. if ((c = readline(zc, zc->Rxtimeout)) < 0)
  898. return c;
  899. switch (c &= 0177)
  900. {
  901. case XON:
  902. case XOFF:
  903. continue;
  904. default:
  905. if (zc->Zctlesc && !(c & 0140))
  906. continue;
  907. case '\r':
  908. case '\n':
  909. case ZDLE:
  910. return c;
  911. }
  912. }
  913. }
  914. /*----------------------------------------------------------------------+
  915. | stohdr - Store long integer pos in Txhdr.
  916. +----------------------------------------------------------------------*/
  917. void stohdr(ZC *zc, long pos)
  918. {
  919. zc->Txhdr[ZP0] = (char)(pos & 0377);
  920. zc->Txhdr[ZP1] = (char)((pos>>8) & 0377);
  921. zc->Txhdr[ZP2] = (char)((pos>>16) & 0377);
  922. zc->Txhdr[ZP3] = (char)((pos>>24) & 0377);
  923. }
  924. /*----------------------------------------------------------------------+
  925. | rclhdr - Recover a long integer from a header.
  926. +----------------------------------------------------------------------*/
  927. long rclhdr(BYTE *hdr)
  928. {
  929. register long l;
  930. l = (hdr[ZP3] & 0377);
  931. l = (l << 8) | (hdr[ZP2] & 0377);
  932. l = (l << 8) | (hdr[ZP1] & 0377);
  933. l = (l << 8) | (hdr[ZP0] & 0377);
  934. return l;
  935. }
  936. static unsigned int z_errors [] = {
  937. TSC_DISK_FULL, /* ZFULLDISK (-5) */
  938. TSC_LOST_CARRIER, /* ZCARRIER_LOST (-4) */
  939. TSC_GEN_FAILURE, /* RCDO (-3) */
  940. TSC_NO_RESPONSE, /* TIMEOUT (-2) */
  941. TSC_BAD_FORMAT, /* ERROR (-1) */
  942. // mode to zmdm.h // REV: 4/24/2002
  943. //#define ERROFFSET 5
  944. TSC_CANT_START, /* ZRQINIT (0) */
  945. TSC_CANT_START, /* ZRINIT (1) */
  946. TSC_CANT_START, /* ZSINIT (2) */
  947. TSC_OK, /* ZACK (3) */
  948. TSC_GEN_FAILURE, /* ZFILE (4) */
  949. TSC_OK, /* ZSKIP (5) */
  950. TSC_GEN_FAILURE, /* ZNAK (6) */
  951. TSC_RMT_CANNED, /* ZABORT (7) */
  952. TSC_COMPLETE, /* ZFIN (8) */
  953. TSC_GEN_FAILURE, /* ZRPOS (9) */
  954. TSC_GEN_FAILURE, /* ZDATA (10) */
  955. TSC_OK, /* ZEOF (11) */
  956. TSC_DISK_ERROR, /* ZFERR (12) */
  957. TSC_GEN_FAILURE, /* ZCRC (13) */
  958. TSC_OK, /* ZCHALLENGE (14) */
  959. TSC_COMPLETE, /* ZCOMPL (15) */
  960. TSC_USER_CANNED, /* ZCAN (16) */
  961. TSC_OK, /* ZFREECNT (17) */
  962. TSC_CANT_START, /* ZCOMMAND (18) */
  963. TSC_CANT_START, /* ZSTDERR (19) */
  964. TSC_BAD_FORMAT, /* added for HA/5 */
  965. TSC_OK, /* sent ack (21) */
  966. TSC_VIRUS_DETECT, /* ZMDM_VIRUS (22) */
  967. TSC_REFUSE, /* ZMDM_REFUSE (23)*/
  968. TSC_OLDER_FILE, /* ZMDM_OLDER (24) */
  969. TSC_FILEINUSE, /* ZMDM_INUSE (25) */
  970. };
  971. #define ERRSIZE 30
  972. /*----------------------------------------------------------------------+
  973. | zmdm_error
  974. +----------------------------------------------------------------------*/
  975. unsigned int zmdm_error(ZC *zc, int error)
  976. {
  977. error += ERROFFSET;
  978. if ((error > ERRSIZE) || (error < 0))
  979. return TSC_GEN_FAILURE;
  980. else
  981. return z_errors[error];
  982. }
  983. /*----------------------------------------------------------------------+
  984. | zmdm_retval
  985. +----------------------------------------------------------------------*/
  986. int zmdm_retval(ZC *zc, int flag, int error)
  987. {
  988. if (flag == TRUE)
  989. {
  990. zc->s_error = error;
  991. }
  992. return(zc->s_error);
  993. }
  994. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  995. * zmdms_progress
  996. *
  997. * DESCRIPTION:
  998. * Updates display fields on screen to indicate the progress of the transfer.
  999. *
  1000. * ARGUMENTS:
  1001. * none
  1002. *
  1003. * RETURNS:
  1004. * nothing
  1005. */
  1006. void zmdms_progress(ZC *zc, int status)
  1007. {
  1008. long ttime, stime;
  1009. long bytes_sent;
  1010. long cps;
  1011. // int k_sent;
  1012. long new_stime = -1L;
  1013. long new_ttime = -1L;
  1014. long new_cps = -1L;
  1015. long file_so_far = -1L;
  1016. long total_so_far = -1L;
  1017. if (zc->xfertimer == -1L)
  1018. return;
  1019. ttime = bittest(status, TRANSFER_DONE) ?
  1020. zc->xfertime : (long)interval(zc->xfertimer);
  1021. if ((stime = ttime / 10L) != zc->displayed_time ||
  1022. bittest(status, FILE_DONE | TRANSFER_DONE))
  1023. {
  1024. new_stime = stime;
  1025. /* Display amount transferred */
  1026. bytes_sent = zc->file_bytes + zc->total_bytes;
  1027. file_so_far = zc->file_bytes;
  1028. total_so_far = bytes_sent;
  1029. /* Display throughput and time remaining */
  1030. if ((stime > 2 ||
  1031. ttime > 0 && bittest(status, FILE_DONE | TRANSFER_DONE)) &&
  1032. (cps = ((zc->real_bytes + zc->actual_bytes) * 10L) / ttime) > 0)
  1033. {
  1034. new_cps = cps;
  1035. if (bittest(status, TRANSFER_DONE))
  1036. ttime = 0;
  1037. else
  1038. ttime = ((zc->nbytes - bytes_sent) / cps) +
  1039. zc->nfiles - zc->filen;
  1040. new_ttime = ttime;
  1041. }
  1042. zc->displayed_time = stime;
  1043. }
  1044. xferMsgProgress(zc->hSession,
  1045. new_stime,
  1046. new_ttime,
  1047. new_cps,
  1048. file_so_far,
  1049. total_so_far);
  1050. }
  1051. /*----------------------------------------------------------------------+
  1052. | zmdms_newfile
  1053. +----------------------------------------------------------------------*/
  1054. void zmdms_newfile(ZC *zc, int filen, TCHAR *fname, long flength)
  1055. {
  1056. xferMsgNewfile(zc->hSession,
  1057. filen,
  1058. NULL,
  1059. fname);
  1060. xferMsgFilesize(zc->hSession, flength);
  1061. }
  1062. /*----------------------------------------------------------------------+
  1063. | zmsma_update
  1064. +----------------------------------------------------------------------*/
  1065. void zmdms_update(ZC *zc, int state)
  1066. {
  1067. int nErrorID;
  1068. if (state == ZACK || state == ZMDM_ACKED )
  1069. {
  1070. return;
  1071. }
  1072. if (zc->pstatus > RCDO)
  1073. {
  1074. nErrorID = zc->pstatus + ERROFFSET - 1;
  1075. }
  1076. else if (zc->pstatus < RCDO )
  1077. {
  1078. nErrorID = zc->pstatus + ERROFFSET;
  1079. }
  1080. else
  1081. {
  1082. nErrorID = ERROR + ERROFFSET - 1;
  1083. }
  1084. zc->last_event = zc->pstatus;
  1085. zc->pstatus = state;
  1086. xferMsgStatus(zc->hSession, nErrorID);
  1087. xferMsgEvent(zc->hSession, nErrorID);
  1088. if (state == ERROR)
  1089. {
  1090. zc->errors += 1;
  1091. xferMsgErrorcnt(zc->hSession, zc->errors);
  1092. }
  1093. }
  1094. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1095. * zmdmr_progress
  1096. *
  1097. * DESCRIPTION:
  1098. * Displays the progress of a filetransfer on screen by showing the number of
  1099. * bytes transferred and updating the vu meters if they have been initialized.
  1100. *
  1101. * ARGUMENTS:
  1102. *
  1103. * RETURNS:
  1104. *
  1105. */
  1106. void zmdmr_progress(ZC *zc, int status)
  1107. {
  1108. long ttime, stime;
  1109. long bytes_rcvd;
  1110. long bytes_diff;
  1111. // long k_rcvd;
  1112. long cps;
  1113. long new_stime = -1;
  1114. long new_ttime = -1;
  1115. long new_cps = -1;
  1116. long file_so_far = -1;
  1117. long total_so_far = -1;
  1118. if (zc == NULL || zc->xfertimer == -1L)
  1119. return;
  1120. ttime = bittest(status, TRANSFER_DONE) ?
  1121. zc->xfertime : (long)interval(zc->xfertimer);
  1122. if ((stime = ttime / 10L) != zc->displayed_time ||
  1123. bittest(status, FILE_DONE | TRANSFER_DONE))
  1124. {
  1125. /* Display elapsed time */
  1126. new_stime = stime;
  1127. bytes_rcvd = zc->total_bytes + zc->file_bytes;
  1128. if (bittest(status, FILE_DONE))
  1129. if (zc->filesize != 0)
  1130. if (zc->file_bytes != zc->filesize)
  1131. {
  1132. zmdmr_filesize(zc, zc->file_bytes);
  1133. bytes_diff = zc->filesize- zc->file_bytes;
  1134. zc->filesize -= bytes_diff;
  1135. zc->nbytes -= bytes_diff;
  1136. zmdmr_totalsize(zc, zc->nbytes);
  1137. }
  1138. /* Display amount received */
  1139. file_so_far = zc->file_bytes;
  1140. total_so_far = bytes_rcvd;
  1141. /* Display throughput and time remaining */
  1142. if (stime > 0 &&
  1143. (cps = ((zc->actual_bytes + zc->real_bytes)*10L) / ttime) > 0)
  1144. {
  1145. new_cps = cps;
  1146. /* calculate time to completion */
  1147. if (zc->nbytes > 0L)
  1148. {
  1149. ttime = (zc->nbytes - bytes_rcvd) / cps;
  1150. if (zc->nfiles > 1)
  1151. ttime += (zc->nfiles - zc->filen);
  1152. new_ttime = ttime;
  1153. }
  1154. else if (zc->filesize > 0L)
  1155. {
  1156. ttime = (zc->filesize - zc->file_bytes) / cps;
  1157. new_ttime = ttime;
  1158. }
  1159. }
  1160. xferMsgProgress(zc->hSession,
  1161. new_stime,
  1162. new_ttime,
  1163. new_cps,
  1164. file_so_far,
  1165. total_so_far);
  1166. }
  1167. }
  1168. /*----------------------------------------------------------------------+
  1169. | zmdmr_update
  1170. +----------------------------------------------------------------------*/
  1171. void zmdmr_update(ZC *zc, int status)
  1172. {
  1173. int nErrorID;
  1174. if (status == ZACK || status == ZMDM_ACKED )
  1175. return;
  1176. if (status == ZRPOS && zc->do_init)
  1177. {
  1178. nErrorID = 0;
  1179. }
  1180. else if (zc->pstatus > RCDO)
  1181. {
  1182. nErrorID = zc->pstatus + ERROFFSET - 1;
  1183. }
  1184. else if (zc->pstatus < RCDO )
  1185. {
  1186. nErrorID = zc->pstatus + ERROFFSET;
  1187. }
  1188. else
  1189. {
  1190. nErrorID = ERROR + ERROFFSET - 1;
  1191. }
  1192. zc->last_event = zc->pstatus;
  1193. zc->pstatus = status;
  1194. xferMsgStatus(zc->hSession, nErrorID);
  1195. xferMsgEvent(zc->hSession, nErrorID);
  1196. if (status == ERROR)
  1197. {
  1198. zc->errors += 1;
  1199. xferMsgErrorcnt(zc->hSession, zc->errors);
  1200. }
  1201. }
  1202. /*----------------------------------------------------------------------+
  1203. | zmdmr_filecnt
  1204. +----------------------------------------------------------------------*/
  1205. void zmdmr_filecnt(ZC *zc, int cnt)
  1206. {
  1207. xferMsgFilecnt(zc->hSession, cnt);
  1208. }
  1209. /*----------------------------------------------------------------------+
  1210. | zmdmr_totalsize
  1211. +----------------------------------------------------------------------*/
  1212. void zmdmr_totalsize(ZC *zc, long bytes)
  1213. {
  1214. if (zc->nfiles >= 1)
  1215. {
  1216. xferMsgTotalsize(zc->hSession, bytes);
  1217. }
  1218. }
  1219. /*----------------------------------------------------------------------+
  1220. | zmdmr_newfile
  1221. +----------------------------------------------------------------------*/
  1222. void zmdmr_newfile(ZC *zc, int filen, BYTE *theirname, TCHAR *ourname)
  1223. {
  1224. xferMsgNewfile(zc->hSession,
  1225. filen,
  1226. theirname,
  1227. ourname);
  1228. }
  1229. /*----------------------------------------------------------------------+
  1230. | zmdmr_filesize
  1231. +----------------------------------------------------------------------*/
  1232. void zmdmr_filesize(ZC *zc, long fsize)
  1233. {
  1234. if (fsize <= 0L)
  1235. return;
  1236. xferMsgFilesize(zc->hSession, fsize);
  1237. }
  1238. /* End of zmodem.c */