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.

945 lines
20 KiB

  1. /* File: C:\WACKER\xfer\mdmx_rcv.c (Created: 18-Jan-1994)
  2. * created from HAWIN source file
  3. *
  4. * mdmx_rcv.c -- XMODEM compatible file receiving routines for HA5G
  5. *
  6. * Copyright 1987,88,89,90,1994 by Hilgraeve Inc. -- Monroe, MI
  7. * All rights reserved
  8. *
  9. * $Revision: 9 $
  10. * $Date: 7/11/02 3:58p $
  11. */
  12. #include <windows.h>
  13. #pragma hdrstop
  14. #include <stdlib.h>
  15. // #include <setjmp.h>
  16. #define BYTE unsigned char
  17. #include <tdll\mc.h>
  18. #include <tdll\stdtyp.h>
  19. #include <tdll\com.h>
  20. #include <tdll\assert.h>
  21. #include <tdll\session.h>
  22. #include <tdll\load_res.h>
  23. #include <tdll\xfer_msc.h>
  24. #include <tdll\file_io.h>
  25. #include <tdll\htchar.h>
  26. #include "xfr_srvc.h"
  27. #include "xfr_todo.h"
  28. #include "xfr_dsp.h"
  29. #include "xfer_tsc.h"
  30. #include "foo.h"
  31. #include "cmprs.h"
  32. #include "xfer.h"
  33. #include "xfer.hh"
  34. #include "mdmx.h"
  35. #include "mdmx.hh"
  36. #if !defined(STATIC_FUNC)
  37. #define STATIC_FUNC
  38. #endif
  39. /* * * * * * * * * * * * *
  40. * Function Prototypes *
  41. * * * * * * * * * * * * */
  42. STATIC_FUNC void start_receive(ST_MDMX *xc, unsigned expect);
  43. STATIC_FUNC int wait_receive(ST_MDMX *xc);
  44. STATIC_FUNC int receivepckt(ST_MDMX *xc,
  45. HSESSION hSession,
  46. unsigned expect,
  47. struct s_mdmx_pckt *pckt);
  48. STATIC_FUNC void respond(HSESSION hSession, ST_MDMX *xc, char code);
  49. STATIC_FUNC void xm_clear_input(HSESSION hSession);
  50. STATIC_FUNC void xm_rcheck(ST_MDMX *xc, HSESSION hSession, int before);
  51. STATIC_FUNC void xm_check_input(HSESSION hSession, int suspend);
  52. extern int xr_collect(ST_MDMX *, int, long, unsigned char **,
  53. unsigned char *, unsigned *);
  54. /*lint -e502*/ /* lint seems to want the ~ operator applied
  55. * only to unsigned, wer'e using uchar
  56. */
  57. #define ESC_MSG_COL 1
  58. /* * * * * * * * * * * *
  59. * Shared Variables *
  60. * * * * * * * * * * * */
  61. // int (NEAR *p_putc)(metachar c) = xm_putc;
  62. // static struct s_mdmx_pckt *next_pckt;
  63. // static unsigned this_pckt;
  64. // static tiny check_type;
  65. // static int batch;
  66. // static int streaming;
  67. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  68. * mdmx_rcv
  69. *
  70. * DESCRIPTION:
  71. *
  72. * ARGUMENTS:
  73. *
  74. * RETURNS:
  75. *
  76. */
  77. int mdmx_rcv(HSESSION hSession, int attended, int method, int single_file)
  78. {
  79. ST_MDMX *xc;
  80. struct s_mdmx_pckt *last_pckt = NULL;
  81. struct s_mdmx_pckt *swap_pckt = NULL;
  82. struct st_rcv_open stRcv;
  83. TCHAR fname[FNAME_LEN];
  84. TCHAR our_fname[FNAME_LEN];
  85. long basesize;
  86. int still_trying = TRUE;
  87. int xpckt_size;
  88. int xstatus = TSC_OK;
  89. int override = FALSE;
  90. unsigned int uiOldOptions;
  91. unsigned tries, retries;
  92. unsigned char *cp;
  93. int blk_result = UNDEFINED, result = 0;
  94. char start_char;
  95. char nak_char;
  96. TCHAR_Fill(fname, TEXT('\0'), FNAME_LEN);
  97. /* allocate space for large packets since we don't necessarily know what
  98. * we'll be getting.
  99. */
  100. xc = NULL;
  101. last_pckt = NULL;
  102. xc = malloc(sizeof(ST_MDMX));
  103. if (xc == NULL)
  104. goto done;
  105. memset(xc, 0, sizeof(ST_MDMX));
  106. DbgOutStr("xc = 0x%x\r\n", xc, 0,0,0,0);
  107. last_pckt = malloc(sizeof(ST_MDMX) + LARGE_PACKET + 2);
  108. if (last_pckt == NULL)
  109. goto done;
  110. memset(last_pckt, 0, sizeof(ST_MDMX));
  111. xc->next_pckt = malloc(sizeof(ST_MDMX) + LARGE_PACKET + 2);
  112. if (xc->next_pckt == NULL)
  113. goto done;
  114. memset(xc->next_pckt, 0, sizeof(ST_MDMX));
  115. xc->hSession = hSession;
  116. xc->hCom = sessQueryComHdl(hSession);
  117. DbgOutStr("hs = 0x%x\r\n", hSession, 0,0,0,0);
  118. mdmxXferInit(xc, method);
  119. if (xfer_set_comport(hSession, FALSE, &uiOldOptions) != TRUE)
  120. goto done;
  121. else
  122. override = TRUE;
  123. xc->file_bytes = 0L;
  124. xc->total_bytes = 0L;
  125. #if FALSE
  126. xc->flagkey = kbd_register_flagkey(ESC_KEY, NULL);
  127. #endif
  128. xc->fh = NULL;
  129. xc->xfertimer = -1L;
  130. xc->xfertime = 0L;
  131. xc->nfiles = 0;
  132. xc->filen = 0;
  133. xc->filesize = -1L;
  134. xc->nbytes = -1L;
  135. still_trying = TRUE;
  136. blk_result = UNDEFINED;
  137. xc->batch = TRUE;
  138. xc->streaming = FALSE;
  139. start_char = 'C';
  140. xc->check_type = CRC;
  141. mdmxdspChecktype(xc, (xc->check_type == CRC) ? 0 : 1);
  142. if (method == XF_YMODEM_G)
  143. {
  144. xc->streaming = TRUE;
  145. start_char = 'G';
  146. }
  147. else if ((method == XF_XMODEM || method == XF_XMODEM_1K) &&
  148. xc->mdmx_chkt == CHECKSUM)
  149. {
  150. start_char = NAK;
  151. xc->check_type = CHECKSUM;
  152. }
  153. nak_char = start_char;
  154. xc->this_pckt = 0;
  155. tries = 0;
  156. mdmxdspPacketErrorcnt(xc, tries);
  157. retries = 0;
  158. mdmxdspErrorcnt(xc, retries);
  159. xc->mdmx_byte_cnt = 0L;
  160. mdmxdspChecktype(xc, (xc->check_type == CRC) ? 0 : 1);
  161. start_receive(xc, xc->this_pckt); /* setup to receive first pckt */
  162. if (attended)
  163. respond(hSession, xc, start_char);
  164. while (still_trying)
  165. {
  166. blk_result = wait_receive(xc);
  167. switch(blk_result)
  168. {
  169. case NOBATCH_PCKT:
  170. /* Received pckt 1 while waiting for pckt 0.
  171. * This must be an XMODEM as opposed to a YMODEM transfer
  172. */
  173. if (!single_file)
  174. {
  175. xstatus = TSC_BAD_FORMAT;
  176. still_trying = FALSE;
  177. break;
  178. }
  179. xc->this_pckt = 1;
  180. xc->batch = FALSE;
  181. xc->filesize = -1L;
  182. nak_char = NAK;
  183. stRcv.pszSuggestedName = "";
  184. stRcv.pszActualName = our_fname;
  185. stRcv.lFileTime = 0;
  186. result = xfer_open_rcv_file(hSession, &stRcv, 0L);
  187. if (result != 0)
  188. {
  189. switch (result)
  190. {
  191. case -6:
  192. xstatus = TSC_REFUSE;
  193. break;
  194. case -5:
  195. xstatus = TSC_CANT_OPEN;
  196. break;
  197. case -4:
  198. xstatus = TSC_NO_FILETIME;
  199. break;
  200. case -3:
  201. xstatus = TSC_CANT_OPEN;
  202. break;
  203. case -2:
  204. xstatus = TSC_OLDER_FILE;
  205. break;
  206. case -1:
  207. default:
  208. xstatus = TSC_CANT_OPEN;
  209. break;
  210. }
  211. still_trying = FALSE;
  212. break;
  213. }
  214. xc->fh = stRcv.bfHdl;
  215. xc->basesize = stRcv.lInitialSize;
  216. basesize = stRcv.lInitialSize;
  217. mdmxdspNewfile(xc,
  218. 0,
  219. our_fname,
  220. our_fname);
  221. /* fall through */
  222. case ALT_PCKT:
  223. case GOOD_PCKT:
  224. /* swap pckt pointers so we can work on this one while receiving
  225. * the next
  226. */
  227. swap_pckt = last_pckt;
  228. last_pckt = xc->next_pckt;
  229. xc->next_pckt = swap_pckt;
  230. if (xc->this_pckt != 0)
  231. start_receive(xc, xc->this_pckt + 1);
  232. if (!xc->streaming)
  233. respond(hSession, xc, ACK); /* send ACK as soon as possible */
  234. /* then send burst for Xmodem pckt 1 */
  235. if (xc->this_pckt == 0)
  236. {
  237. if (!*(last_pckt->bdata)) /* no more files? */
  238. {
  239. xc->xfertime = (long)interval(xc->xfertimer);
  240. still_trying = FALSE;
  241. break;
  242. }
  243. else if (xc->filen > 0 && single_file) /* getting too many files? */
  244. {
  245. xstatus = TSC_TOO_MANY;
  246. still_trying = FALSE;
  247. break;
  248. }
  249. start_receive(xc, 1);
  250. respond(hSession, xc, start_char);
  251. /* get info out of packet 0 and open file */
  252. StrCharCopyN(fname, last_pckt->bdata, FNAME_LEN);
  253. for (cp = fname; *cp != '\0'; cp++)
  254. if (*cp == '/')
  255. *cp = '\\';
  256. stRcv.pszSuggestedName = fname;
  257. stRcv.pszActualName = our_fname;
  258. stRcv.lFileTime = 0;
  259. xfer_build_rcv_name(hSession, &stRcv);
  260. result = xfer_open_rcv_file(hSession, &stRcv, 0L);
  261. if (result != 0)
  262. {
  263. switch (result)
  264. {
  265. case -6:
  266. xstatus = TSC_REFUSE;
  267. break;
  268. case -5:
  269. xstatus = TSC_CANT_OPEN;
  270. break;
  271. case -4:
  272. xstatus = TSC_NO_FILETIME;
  273. break;
  274. case -3:
  275. xstatus = TSC_CANT_OPEN;
  276. break;
  277. case -2:
  278. xstatus = TSC_OLDER_FILE;
  279. break;
  280. case -1:
  281. default:
  282. xstatus = TSC_CANT_OPEN;
  283. break;
  284. }
  285. still_trying = FALSE;
  286. break;
  287. }
  288. xc->fh = stRcv.bfHdl;
  289. xc->basesize = stRcv.lInitialSize;
  290. basesize = stRcv.lInitialSize;
  291. mdmxdspNewfile(xc,
  292. ++xc->filen,
  293. fname,
  294. our_fname);
  295. /* accumlate last transfer total and start new counter */
  296. xc->total_bytes += xc->file_bytes;
  297. xc->mdmx_byte_cnt = xc->file_bytes = 0L;
  298. xc->filesize = -1L;
  299. cp = last_pckt->bdata +
  300. StrCharGetByteCount(last_pckt->bdata) + 1;
  301. if (*cp)
  302. {
  303. xc->filesize = atol(cp);
  304. mdmxdspFilesize(xc, xc->filesize);
  305. }
  306. nak_char = NAK;
  307. }
  308. else
  309. {
  310. /* unload packet data */
  311. cp = last_pckt->bdata;
  312. xpckt_size = (last_pckt->start_char == STX ?
  313. LARGE_PACKET : SMALL_PACKET);
  314. if (xs_unload(xc, cp, xpckt_size) == (-1) /* ERROR */ )
  315. {
  316. xm_clear_input(hSession);
  317. respond(hSession, xc, CAN);
  318. xstatus = TSC_DISK_ERROR;
  319. still_trying = FALSE;
  320. break;
  321. }
  322. // if (xc->filesize != -1L) jmh 03-08-96 to match HAWin
  323. if (xc->filesize > 0)
  324. xc->file_bytes = min(xc->filesize, xc->mdmx_byte_cnt);
  325. else
  326. xc->file_bytes = xc->mdmx_byte_cnt;
  327. }
  328. mdmxdspPacketnumber(xc, (long)++xc->this_pckt);
  329. if (tries)
  330. mdmxdspPacketErrorcnt(xc, tries = 0);
  331. mdmx_progress(xc, 0);
  332. break;
  333. case END_PCKT:
  334. /* the special EOT handling was removed from version 3.20
  335. * due to problems with RBBS-PC. It should be modified and
  336. * reenabled after experimentation.
  337. */
  338. respond(hSession, xc, ACK); /* ACK the EOT */
  339. mdmx_progress(xc, FILE_DONE);
  340. /* It's possible to get an unwanted EOT (if the ACK from the
  341. * first EOT is lost) so we should treat it like a repeated
  342. * packet.
  343. */
  344. if (xc->fh) /* if file was open */
  345. {
  346. if (!xfer_close_rcv_file(hSession,
  347. xc->fh,
  348. xstatus,
  349. fname,
  350. our_fname,
  351. xfer_save_partial(hSession),
  352. xc->basesize + xc->file_bytes /*xc->filesize jmh 03-08-96*/,
  353. 0))
  354. {
  355. xstatus = TSC_DISK_ERROR;
  356. still_trying = FALSE;
  357. break;
  358. }
  359. xc->fh = NULL;
  360. }
  361. if (!xc->batch)
  362. {
  363. xc->xfertime = (long)interval(xc->xfertimer);
  364. still_trying = FALSE;
  365. }
  366. else
  367. {
  368. start_receive(xc, xc->this_pckt = 0);
  369. respond(hSession, xc, nak_char = start_char);
  370. }
  371. if (tries)
  372. // VidWrtStrF(xc->toprow + XR_DR_RETRIES, xc->dc_retries,
  373. // "^H%-2d", tries = 0);
  374. mdmxdspPacketErrorcnt(xc, tries = 0);
  375. break;
  376. case REPEAT_PCKT:
  377. start_receive(xc, xc->this_pckt);
  378. respond(hSession, xc, ACK);
  379. ++tries;
  380. break;
  381. case WRONG_PCKT:
  382. xm_clear_input(hSession);
  383. respond(hSession, xc, CAN);
  384. ++tries; /* to get packet error on screen */
  385. still_trying = FALSE;
  386. xstatus = TSC_OUT_OF_SEQ;
  387. break;
  388. case SHORT_PCKT:
  389. case BAD_FORMAT:
  390. case BAD_CHECK:
  391. case NO_PCKT:
  392. ++tries;
  393. if (xc->mdmx_chkt == UNDETERMINED && xc->this_pckt == 0 && tries == 3
  394. && method == XF_XMODEM)
  395. {
  396. xc->check_type = CHECKSUM;
  397. start_char = nak_char = NAK;
  398. // VidWrtStr(xc->toprow + XR_DR_ERR_CHK, xc->dc_err_chk,
  399. // strld(TM_CHECKSUM));
  400. mdmxdspChecktype(xc, 1);
  401. }
  402. xm_clear_input(hSession);
  403. respond(hSession, xc, nak_char);
  404. start_receive(xc, xc->this_pckt);
  405. break;
  406. case BLK_ABORTED:
  407. xm_clear_input(hSession);
  408. respond(hSession, xc, CAN);
  409. xstatus = TSC_USER_CANNED;
  410. still_trying = FALSE;
  411. break;
  412. case CARRIER_LOST:
  413. xm_clear_input(hSession);
  414. xstatus = TSC_LOST_CARRIER;
  415. still_trying = FALSE;
  416. break;
  417. case CANNED:
  418. xm_clear_input(hSession);
  419. xstatus = TSC_RMT_CANNED;
  420. still_trying = FALSE;
  421. break;
  422. default:
  423. // assert(FALSE);
  424. break;
  425. }
  426. if (tries)
  427. {
  428. mdmxdspPacketErrorcnt(xc, tries);
  429. mdmxdspErrorcnt(xc, ++retries);
  430. mdmxdspLastError(xc, blk_result);
  431. if ((tries >= (unsigned)xc->mdmx_tries) || (xc->streaming && xc->this_pckt > 0))
  432. {
  433. xm_clear_input(hSession);
  434. respond(hSession, xc, CAN);
  435. xstatus = TSC_ERROR_LIMIT;
  436. still_trying = FALSE;
  437. }
  438. }
  439. } /* while (still_trying) */
  440. done:
  441. if (xc)
  442. {
  443. if (xc->xfertime == 0L)
  444. {
  445. xc->xfertime = (long)interval(xc->xfertimer);
  446. }
  447. mdmx_progress(xc, TRANSFER_DONE);
  448. }
  449. if (override)
  450. {
  451. #if FALSE
  452. cnfg.send_xprot = hld_send_xprot;
  453. cnfg.save_xprot = hld_save_xprot;
  454. cnfg.bits_per_char = hld_bits_per_char;
  455. cnfg.parity_type = hld_parity_type;
  456. (void)(*ComResetPort)();
  457. #endif
  458. xfer_restore_comport(hSession, uiOldOptions);
  459. }
  460. if (xc)
  461. {
  462. if (xstatus != TSC_OK)
  463. {
  464. if (xc->fh)
  465. {
  466. xfer_close_rcv_file(hSession,
  467. xc->fh,
  468. xstatus,
  469. fname,
  470. our_fname,
  471. xfer_save_partial(hSession),
  472. xc->basesize + xc->file_bytes /*xc->filesize jmh 03-08-96*/,
  473. 0);
  474. }
  475. }
  476. #if FALSE
  477. kbd_deregister_flagkey(xc->flagkey);
  478. #endif
  479. mdmxdspCloseDisplay(xc);
  480. #if defined(DEADWOOD)
  481. if (xc->p_crc_tbl != NULL)
  482. {
  483. resFreeDataBlock(xc->hSession, xc->p_crc_tbl);
  484. xc->p_crc_tbl = NULL;
  485. }
  486. #else // defined(DEADWOOD
  487. //
  488. // We don't need to free xc->p_crc_tbl since it is pointing
  489. // to a static constant array. REV: 4/10/2002
  490. //
  491. xc->p_crc_tbl = NULL;
  492. #endif // defined(DEADWOOD)
  493. if (xc->next_pckt)
  494. {
  495. free(xc->next_pckt);
  496. xc->next_pckt = NULL;
  497. }
  498. free(xc);
  499. xc = NULL;
  500. }
  501. if (last_pckt)
  502. {
  503. free(last_pckt);
  504. last_pckt = NULL;
  505. }
  506. return((int)xstatus);
  507. }
  508. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  509. * start_receive
  510. *
  511. * DESCRIPTION:
  512. *
  513. * ARGUMENTS:
  514. *
  515. * RETURNS:
  516. *
  517. */
  518. STATIC_FUNC void start_receive(ST_MDMX *xc, unsigned expect)
  519. {
  520. xc->next_pckt->result = UNDEFINED;
  521. xc->next_pckt->expected = expect;
  522. }
  523. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  524. * wait_receive
  525. *
  526. * DESCRIPTION:
  527. *
  528. * ARGUMENTS:
  529. *
  530. * RETURNS:
  531. *
  532. */
  533. STATIC_FUNC int wait_receive(ST_MDMX *xc)
  534. {
  535. if (xc->next_pckt->result == UNDEFINED)
  536. {
  537. xc->next_pckt->result = receivepckt(xc,
  538. xc->hSession,
  539. xc->next_pckt->expected,
  540. xc->next_pckt);
  541. }
  542. return xc->next_pckt->result;
  543. }
  544. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  545. * receivepckt
  546. *
  547. * DESCRIPTION:
  548. *
  549. * ARGUMENTS:
  550. *
  551. * RETURNS:
  552. *
  553. */
  554. STATIC_FUNC int receivepckt(ST_MDMX *xc,
  555. HSESSION hSession,
  556. unsigned expect,
  557. struct s_mdmx_pckt *pckt)
  558. {
  559. long timer, timeout;
  560. int gothdr = FALSE;
  561. int started = FALSE;
  562. TCHAR cc;
  563. unsigned char *cp;
  564. int gotCAN = FALSE;
  565. unsigned char checksum;
  566. unsigned crc;
  567. int count;
  568. // DbgOutStr("pckt = 0x%x\r\n", pckt, 0,0,0,0);
  569. timer = (long)startinterval();
  570. /* wait for valid pckt-start character */
  571. timeout = (long)(xc->mdmx_pckttime * 10);
  572. while (!started)
  573. {
  574. #if FALSE
  575. if (kbd_check_flagkey(xc->flagkey, TRUE))
  576. {
  577. kbd_flush();
  578. return(BLK_ABORTED);
  579. }
  580. #endif
  581. if (xfer_carrier_lost(hSession))
  582. return CARRIER_LOST;
  583. if (xfer_user_interrupt(hSession))
  584. {
  585. mdmxdspLastError(xc, BLK_ABORTED);
  586. return(BLK_ABORTED);
  587. }
  588. mdmx_progress(xc, 0);
  589. if ((long)interval(timer) > timeout)
  590. return(NO_PCKT);
  591. // if ((cc = RemoteGet(hSession)) != -1)
  592. if (mComRcvChar(xc->hCom, &cc) != 0)
  593. {
  594. DbgOutStr("pckt = 0x%x\r\n", pckt, 0,0,0,0);
  595. switch(pckt->start_char = (unsigned char)cc)
  596. {
  597. case EOT:
  598. if (xc->xfertimer == -1L)
  599. xc->xfertimer = (long)startinterval();
  600. return(END_PCKT);
  601. /*lint -unreachable*/
  602. break;
  603. case SOH:
  604. case STX:
  605. started = TRUE;
  606. if (xc->xfertimer == -1L)
  607. xc->xfertimer = (long)startinterval();
  608. break;
  609. case CAN:
  610. /* if two consecutive CANs are received, drop out */
  611. if (gotCAN)
  612. return(CANNED);
  613. gotCAN = TRUE;
  614. break;
  615. default:
  616. /* ignore */
  617. gotCAN = FALSE; /* two CANs must be consecutive */
  618. break;
  619. }
  620. }
  621. else
  622. {
  623. xfer_idle(hSession, XFER_IDLE_IO);
  624. }
  625. }
  626. /* got valid start character, get packet numbers, data, & error codes */
  627. timeout = xc->mdmx_chartime * 10;
  628. cp = &pckt->pcktnum;
  629. count = 2;
  630. for (;;)
  631. {
  632. if (!xr_collect(xc, count, timeout, &cp, &checksum, &crc))
  633. return(SHORT_PCKT);
  634. if (!gothdr)
  635. {
  636. /* got pckt numbers, now get data and check code(s) */
  637. gothdr = TRUE;
  638. count = (pckt->start_char == STX ? LARGE_PACKET : SMALL_PACKET);
  639. count += (xc->check_type == CRC ? 2 : 1);
  640. checksum = 0;
  641. crc = 0;
  642. cp = pckt->bdata;
  643. }
  644. else
  645. break;
  646. }
  647. /* all bytes have been collected, check for valid packet */
  648. if (xc->check_type == CHECKSUM)
  649. {
  650. /* at this point we've included the checksum itself in the checksum
  651. * calculation. We need to back up, subtract the last char. from
  652. * the computation and use it for comparison instead.
  653. */
  654. --cp; /* point to received checksum */
  655. checksum = (unsigned char)(checksum - *cp); /* we added one too many */
  656. if (checksum != *cp)
  657. return(BAD_CHECK);
  658. }
  659. else if (crc != 0)
  660. return(BAD_CHECK);
  661. if (pckt->pcktnum != (unsigned char)((~pckt->npcktnum) & 0xFF))
  662. {
  663. return(BAD_FORMAT);
  664. }
  665. if (pckt->pcktnum != (unsigned char)(expect % 256))
  666. {
  667. /* we always start out expecting ymodem batch, on an xmodem
  668. * transfer, this code will detect the situation.
  669. */
  670. if (!xc->filen && expect == 0 && pckt->pcktnum == 1)
  671. return NOBATCH_PCKT;
  672. else if (pckt->pcktnum == (unsigned char)((expect % 256) - 1))
  673. return REPEAT_PCKT; /* repeated packets are harmless */
  674. else
  675. return WRONG_PCKT;
  676. }
  677. /* if we got this far, the pckt is good */
  678. return(GOOD_PCKT);
  679. }
  680. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  681. * respond
  682. *
  683. * DESCRIPTION:
  684. *
  685. * ARGUMENTS:
  686. *
  687. * RETURNS:
  688. *
  689. */
  690. STATIC_FUNC void respond(HSESSION hSession, ST_MDMX *xc, char code)
  691. /* wait for line to clear, then send code */
  692. {
  693. int i;
  694. ComSendChar(xc->hCom, &xc->stP, code);
  695. if (code == CAN)
  696. {
  697. for (i = 4 + 1; --i > 0; )
  698. ComSendChar(xc->hCom, &xc->stP, CAN);
  699. }
  700. ComSendWait(xc->hCom, &xc->stP);
  701. }
  702. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  703. * xm_clear_input
  704. *
  705. * DESCRIPTION:
  706. *
  707. *
  708. * ARGUMENTS:
  709. *
  710. *
  711. * RETURNS:
  712. *
  713. */
  714. STATIC_FUNC void xm_clear_input(HSESSION hSession)
  715. {
  716. // RemoteClear(hSession); /* make sure no junk is left sitting in it */
  717. ComRcvBufrClear(sessQueryComHdl(hSession));
  718. }
  719. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  720. * xm_rcheck
  721. *
  722. * DESCRIPTION:
  723. *
  724. *
  725. * ARGUMENTS:
  726. *
  727. *
  728. * RETURNS:
  729. *
  730. */
  731. STATIC_FUNC void xm_rcheck(ST_MDMX *xc, HSESSION hSession, int before)
  732. {
  733. if (xc->streaming)
  734. {
  735. /* Do it different for YMODEM-G, since the sender won't wait for ACK */
  736. #if FALSE
  737. if (before)
  738. suspendinput(FLG_DISK_ACTIVE, 5);
  739. else
  740. allowinput(FLG_DISK_ACTIVE);
  741. #endif
  742. }
  743. else
  744. {
  745. if (before)
  746. {
  747. /* wait till next packet is in before writing to disk */
  748. if (xc->next_pckt->result == UNDEFINED)
  749. xc->next_pckt->result = wait_receive(xc);
  750. }
  751. }
  752. }
  753. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  754. * xm_check_input
  755. *
  756. * DESCRIPTION:
  757. *
  758. * ARGUEMENTS:
  759. *
  760. * RETURNS:
  761. *
  762. */
  763. STATIC_FUNC void xm_check_input(HSESSION hSession, int suspend)
  764. {
  765. }
  766. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  767. * xr_collect
  768. *
  769. * DESCRIPTION:
  770. *
  771. *
  772. * ARGUMENTS:
  773. *
  774. *
  775. * RETURNS:
  776. *
  777. */
  778. int xr_collect(ST_MDMX *xc, int count, long timeout,
  779. unsigned char **ptr,
  780. unsigned char *checksum, unsigned *crc)
  781. {
  782. unsigned char lchecksum;
  783. unsigned char *cp, *head;
  784. TCHAR rchar;
  785. int cnt;
  786. long timer;
  787. head = cp = *ptr;
  788. lchecksum = *checksum;
  789. cnt = count;
  790. while (cnt--)
  791. {
  792. // if ((rchar = RemoteGet(xc->hSession)) == -1)
  793. if (mComRcvChar(xc->hCom, &rchar) == 0)
  794. {
  795. xfer_idle(xc->hSession, XFER_IDLE_IO);
  796. /* driver hasn't put any new chars in rmt_bufr */
  797. timer = (long)startinterval();
  798. // while ((rchar = RemoteGet(xc->hSession)) == -1)
  799. while (mComRcvChar(xc->hCom, &rchar) == 0)
  800. {
  801. /* check for char timeout */
  802. xfer_idle(xc->hSession, XFER_IDLE_IO);
  803. if ((long)interval(timer) > timeout)
  804. return(FALSE);
  805. }
  806. }
  807. *cp = (unsigned char)rchar;
  808. lchecksum += *cp;
  809. ++cp;
  810. }
  811. *ptr = cp;
  812. *checksum = lchecksum;
  813. if (count > 100)
  814. *crc = calc_crc(xc, (unsigned)0, head, count);
  815. return(TRUE);
  816. }
  817. /***************************** end of mdmx_rcv.c **************************/