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.

573 lines
14 KiB

  1. /* File: C:\WACKER\xfer\krm.c (Created: 28-Jan-1994)
  2. * created from HAWIN source file
  3. * krm.c -- Functions common to both kermit send and kermit receive
  4. * routines.
  5. *
  6. * Copyright 1989,1990,1991,1994 by Hilgraeve Inc. -- Monroe, MI
  7. * All rights reserved
  8. *
  9. * $Revision: 6 $
  10. * $Date: 4/10/02 3:05p $
  11. */
  12. #include <windows.h>
  13. #pragma hdrstop
  14. #include <time.h>
  15. #include <stdlib.h>
  16. #include <sys\types.h>
  17. #include <sys\utime.h>
  18. #include <term\res.h>
  19. #include <tdll\stdtyp.h>
  20. #include <tdll\mc.h>
  21. #include <tdll\com.h>
  22. #include <tdll\assert.h>
  23. #include <tdll\session.h>
  24. #include <tdll\load_res.h>
  25. #include <tdll\xfer_msc.h>
  26. #include <tdll\globals.h>
  27. #include <tdll\file_io.h>
  28. #if !defined(BYTE)
  29. #define BYTE unsigned char
  30. #endif
  31. #include "cmprs.h"
  32. #include "xfr_dsp.h"
  33. #include "xfr_todo.h"
  34. #include "xfr_srvc.h"
  35. #include "xfer.h"
  36. #include "xfer.hh"
  37. #include "xfer_tsc.h"
  38. #include "krm.h"
  39. #include "krm.hh"
  40. // int krm_dbg; /* used for real-time debugging using dbg.c */
  41. // int k_useattr; /* send 'normalized' file names ? */
  42. // int k_maxl; /* maximum packet length we'll take */
  43. // int k_timeout; /* time they should wait for us */
  44. // uchar k_chkt; /* check type we want to use */
  45. // int k_retries; /* no. of retries */
  46. // uchar k_markchar; /* first char of each packet */
  47. // uchar k_eol; /* end of line character for packets */
  48. // int k_npad; /* no. of pad chars. to send us */
  49. // uchar k_padc; /* pad char. we want */
  50. // struct s_krm_control FAR *kc;
  51. // void (NEARF *KrmProgress)(HSESSION, bits);
  52. // unsigned ke_msg[] =
  53. // {
  54. // TM_NULL,
  55. // TM_NO_RESP,
  56. // TM_GOT_RETRY,
  57. // TM_ERR_DATA,
  58. // TM_RMT_ERR,
  59. // TM_BAD_FMT,
  60. // TM_PCKT_REPT,
  61. // TM_BAD_SEQ,
  62. // TM_FAILED,
  63. // };
  64. /* for mapping Kermit result codes to Transfer Status Codes */
  65. int kresult_code[] =
  66. {
  67. TSC_OK, /* KA_OK 0 */
  68. TSC_USER_CANNED, /* KA_LABORT1 1 */
  69. TSC_RMT_CANNED, /* KA_RABORT1 2 */
  70. TSC_USER_CANNED, /* KA_LABORTALL 3 */
  71. TSC_RMT_CANNED, /* KA_RABORTALL 4 */
  72. TSC_USER_CANNED, /* KA_IMMEDIATE 5 */
  73. TSC_RMT_CANNED, /* KA_RMTERR 6 */
  74. TSC_LOST_CARRIER, /* KA_LOST_CARRIER 7 */
  75. TSC_ERROR_LIMIT, /* KA_ERRLIMIT 8 */
  76. TSC_OUT_OF_SEQ, /* KA_OUT_OF_SEQ 9 */
  77. TSC_BAD_FORMAT, /* KA_BAD_FORMAT 10 */
  78. TSC_TOO_MANY, /* KA_TOO_MANY 11 */
  79. TSC_CANT_OPEN, /* KA_CANT_OPEN 12 */
  80. TSC_DISK_FULL, /* KA_DISK_FULL 13 */
  81. TSC_DISK_ERROR, /* KA_DISK_ERROR 14 */
  82. TSC_OLDER_FILE, /* KA_OLDER_FILE 15 */
  83. TSC_NO_FILETIME, /* KA_NO_FILETIME 16 */
  84. TSC_WONT_CANCEL, /* KA_WONT_CANCEL 17 */
  85. TSC_VIRUS_DETECT, /* KA_VIRUS_DETECT 18 */
  86. TSC_REFUSE /* KA_USER_REFUSED 19 */
  87. };
  88. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  89. * FUNCTION:
  90. * krmGetParameters
  91. *
  92. * DESCRIPTION:
  93. * This function is called to initialize all of the user settable values
  94. * that get passed in from the parameters dialog box.
  95. *
  96. * ARGUMENTS:
  97. * kc -- pointer to the Kermit data block
  98. *
  99. * RETURNS:
  100. * Nothing.
  101. *
  102. */
  103. void krmGetParameters(ST_KRM *kc)
  104. {
  105. XFR_PARAMS *pX;
  106. XFR_KR_PARAMS *pK;
  107. pX = (XFR_PARAMS *)0;
  108. xfrQueryParameters(sessQueryXferHdl(kc->hSession), (VOID **)&pX);
  109. assert(pX);
  110. if (pX != (XFR_PARAMS *)0)
  111. kc->k_useattr = pX->fUseDateTime;
  112. pK = (XFR_KR_PARAMS *)xfer_get_params(kc->hSession, XF_KERMIT);
  113. assert(pK);
  114. if (pK)
  115. {
  116. kc->k_maxl = pK->nBytesPerPacket;
  117. kc->k_timeout = pK->nSecondsWaitPacket;
  118. kc->k_chkt = (BYTE)pK->nErrorCheckSize;
  119. kc->k_retries = pK->nRetryCount;
  120. kc->k_markchar = (BYTE)pK->nPacketStartChar;
  121. kc->k_eol = (BYTE)pK->nPacketEndChar;
  122. kc->k_npad = pK->nNumberPadChars;
  123. kc->k_padc = (BYTE)pK->nPadChar;
  124. }
  125. else
  126. {
  127. //
  128. // Set to the defaults set in xfrInitializeKermit().
  129. //
  130. kc->k_maxl = 94;
  131. kc->k_timeout = 5;
  132. kc->k_chkt = 1;
  133. kc->k_retries = 5;
  134. kc->k_markchar = 1;
  135. kc->k_eol = 13;
  136. kc->k_npad = 0;
  137. kc->k_padc = 0;
  138. }
  139. }
  140. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  141. * ksend_packet
  142. *
  143. * DESCRIPTION:
  144. *
  145. * ARGUMENTS:
  146. *
  147. * RETURNS:
  148. *
  149. */
  150. void ksend_packet(ST_KRM *kc,
  151. unsigned char type,
  152. unsigned dlength,
  153. int seq,
  154. KPCKT FAR *pckt)
  155. {
  156. unsigned csum;
  157. unsigned crc;
  158. int i;
  159. char *cp;
  160. int iSendStatus = COM_OK;
  161. if (type == 'N' || type == 'E') /* wait for input to clear */
  162. ComRcvBufrClear(kc->hCom);
  163. /* send any padding necessary */
  164. for (i = kc->its_npad + 1; --i > 0; )
  165. ComSendCharNow(kc->hCom, kc->its_padc);
  166. /* when received, only packet data is valid, we fill in remainder */
  167. pckt->pmark = kc->k_markchar;
  168. pckt->plen = (int)tochar(dlength + 3);
  169. if (kc->its_chkt == K_CHK2)
  170. pckt->plen += 1;
  171. else if (kc->its_chkt == K_CHK3)
  172. pckt->plen += 2;
  173. pckt->pseq = (int)tochar(seq);
  174. pckt->ptype = type;
  175. /* now figure check bytes */
  176. if (kc->its_chkt == K_CHK3)
  177. {
  178. crc = kcalc_crc((unsigned)0,
  179. (unsigned char *)&pckt->plen,
  180. (int)dlength + 3);
  181. cp = pckt->pdata + dlength;
  182. *cp++ = (char)tochar((crc >> 12) & 0x0F);
  183. *cp++ = (char)tochar((crc >> 6) & 0x3F);
  184. *cp++ = (char)tochar(crc & 0x3F);
  185. }
  186. else
  187. {
  188. csum = 0;
  189. cp = (char *)&pckt->plen;
  190. for (i = dlength + 4; --i > 0; )
  191. csum += *cp++;
  192. /* cp is left pointing to first byte past data */
  193. if (kc->its_chkt == K_CHK2)
  194. {
  195. *cp++ = (char)tochar((csum >> 6) & 0x3F);
  196. *cp++ = (char)tochar(csum & 0x3F);
  197. }
  198. else
  199. *cp++ = (char)tochar((((csum & 0xC0) >> 6) + csum) & 0x3F);
  200. }
  201. *cp = kc->its_eol;
  202. /* send off all chars in buffer */
  203. // (VOID)mComSndBufr(comhdl, (char *)pckt,
  204. // (uchar)(unchar(pckt->plen) + 3), /* include mark, len & eol */
  205. // 100, kc->flagkey_hdl);
  206. iSendStatus = ComSndBufrSend(kc->hCom,
  207. (void *)pckt,
  208. (int)(unchar(pckt->plen) + 3),
  209. 100);
  210. assert(iSendStatus == COM_OK);
  211. }
  212. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  213. * krec_packet
  214. *
  215. * DESCRIPTION:
  216. * Receive a kermit packet, check it for validity and return either the
  217. * type of the received packet or an error code.
  218. *
  219. * ARGUMENTS:
  220. * len
  221. * seq
  222. * data
  223. *
  224. * RETURNS:
  225. *
  226. */
  227. int krec_packet(ST_KRM *kc,
  228. int *len,
  229. int *seq,
  230. unsigned char *data)
  231. {
  232. TCHAR c = 0;
  233. char *bp;
  234. char hdr[3];
  235. int done, got_hdr;
  236. int cnt, i;
  237. long j;
  238. unsigned chksum;
  239. unsigned rchk;
  240. long stime;
  241. long timelimit = kc->its_timeout * 10L;
  242. /* wait until any packet is transmitted */
  243. // (VOID)mComSndBufrWait(comhdl, 100, kc->flagkey_hdl);
  244. if (ComSndBufrWait(kc->hCom, 100) == COM_PORT_NOT_OPEN)
  245. {
  246. return(BAD_PACKET);
  247. }
  248. stime = (long)startinterval();
  249. while (c != (int)kc->k_markchar)
  250. {
  251. if (j = xfer_user_interrupt(kc->hSession))
  252. {
  253. /* Yes, this is needed */
  254. // XferAbort(kc->hSession, (LPVOID)((LPSTR)j));
  255. xfer_user_abort(kc->hSession, j);
  256. return(BAD_PACKET);
  257. }
  258. if (xfer_carrier_lost(kc->hSession))
  259. {
  260. return(BAD_PACKET);
  261. }
  262. (*kc->KrmProgress)(kc, 0);
  263. // if ((c = mComRcvChar(comhdl)) == -1)
  264. if (mComRcvChar(kc->hCom, &c) == 0)
  265. {
  266. if ((long)interval(stime) > timelimit)
  267. {
  268. return('T');
  269. }
  270. xfer_idle(kc->hSession, XFER_IDLE_IO);
  271. }
  272. else if (c != (int)kc->k_markchar)
  273. {
  274. }
  275. else
  276. ; /* for lint */
  277. }
  278. getpacket:
  279. chksum = 0;
  280. done = got_hdr = FALSE;
  281. bp = &hdr[0];
  282. cnt = 3;
  283. while (!done)
  284. {
  285. for (i = cnt + 1; --i > 0; )
  286. {
  287. // while ((c = mComRcvChar(comhdl)) == -1)
  288. while (mComRcvChar(kc->hCom, &c) == 0)
  289. {
  290. if (j = xfer_user_interrupt(kc->hSession))
  291. {
  292. // XferAbort(kc->hSession, (LPVOID)((LPSTR)j));
  293. xfer_user_abort(kc->hSession, j);
  294. return(BAD_PACKET);
  295. }
  296. if (xfer_carrier_lost(kc->hSession))
  297. {
  298. return(BAD_PACKET);
  299. }
  300. (*kc->KrmProgress)(kc, 0);
  301. if ((long)interval(stime) > timelimit)
  302. {
  303. return('T');
  304. }
  305. xfer_idle(kc->hSession, XFER_IDLE_IO);
  306. }
  307. *bp = (char)c;
  308. if ((unsigned char)*bp == kc->k_markchar)
  309. {
  310. goto getpacket;
  311. }
  312. chksum += *bp++;
  313. }
  314. if (!got_hdr)
  315. {
  316. got_hdr = TRUE;
  317. *seq = unchar(hdr[1]);
  318. cnt = unchar(hdr[0]) - 2; /* we've already got seq & len chars */
  319. if (cnt < 0 || cnt > 92)
  320. {
  321. return(BAD_PACKET);
  322. }
  323. bp = data;
  324. }
  325. else
  326. done = TRUE;
  327. }
  328. bp -= kc->its_chkt; /* move pointer back to beginning of check field */
  329. switch(kc->its_chkt)
  330. {
  331. case 1:
  332. *len = cnt - 1;
  333. chksum -= bp[0];
  334. chksum = (((chksum & 0xC0) >> 6) + chksum) & 0x3F;
  335. rchk = (unsigned char)unchar(bp[0]);
  336. break;
  337. case 2:
  338. *len = cnt - 2;
  339. chksum = (chksum - (bp[0] + bp[1])) & 0x0FFF;
  340. rchk = ((unsigned char)unchar(bp[0]) << 6) + unchar(bp[1]);
  341. break;
  342. case 3:
  343. *len = cnt - 3;
  344. rchk = ((unsigned char)unchar(bp[0]) << 12) +
  345. ((unsigned char)unchar(bp[1]) << 6) +
  346. unchar(bp[2]);
  347. chksum = kcalc_crc((unsigned)0, hdr, 3);
  348. if (*len > 0)
  349. chksum = kcalc_crc(chksum, data, *len);
  350. break;
  351. default:
  352. break;
  353. }
  354. *bp = '\0';
  355. if (*len < 0 || chksum != rchk)
  356. {
  357. return(BAD_PACKET);
  358. }
  359. else
  360. {
  361. return(hdr[2]);
  362. }
  363. }
  364. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  365. * buildparams
  366. *
  367. * DESCRIPTION:
  368. * Build a packet containing our initializing parameters. Return length of
  369. * data in packet.
  370. *
  371. * ARGUMENTS:
  372. * initiating -- TRUE if we're initiating the transfer, FALSE if we're ACKing
  373. * its initializing packet
  374. * bufr -- a place to put the results
  375. * RETURNS:
  376. *
  377. */
  378. int buildparams(ST_KRM *kc, int initiating, unsigned char *bufr)
  379. {
  380. unsigned char *bp = bufr;
  381. if (initiating) /* just tell them what we want to do */
  382. {
  383. *bp++ = (unsigned char)tochar(kc->k_maxl); /* MAXL */
  384. *bp++ = (unsigned char)tochar(kc->k_timeout); /* TIME */
  385. *bp++ = (unsigned char)tochar(kc->k_npad); /* NPAD */
  386. *bp++ = (unsigned char)ctl(kc->k_padc); /* PADC */
  387. *bp++ = (unsigned char)tochar(kc->k_eol); /* EOL */
  388. *bp++ = K_QCTL; /* QCTL */
  389. *bp++ = 'Y'; /* QBIN */
  390. *bp++ = (unsigned char)(kc->k_chkt + '0'); /* CHKT */
  391. *bp++ = K_REPT; /* REPT */
  392. *bp++ = (unsigned char)tochar(CAPMASK_ATTR);/* CAPAS */
  393. }
  394. else /* we're responding to them */
  395. {
  396. /* MAXL */
  397. *bp++ = (char)tochar(kc->k_maxl);
  398. /* TIME */
  399. *bp++ = (char)tochar((abs(kc->k_timeout - kc->its_timeout) <= 2) ?
  400. kc->k_timeout + 2 : kc->k_timeout);
  401. /* NPAD */
  402. *bp++ = (unsigned char)tochar(kc->k_npad);
  403. /* PADC */
  404. *bp++ = (unsigned char)ctl(kc->k_padc);
  405. /* EOL */
  406. *bp++ = (unsigned char)tochar(kc->k_eol);
  407. /* QCTL */
  408. *bp++ = K_QCTL;
  409. /* QBIN */
  410. if (kc->its_qbin == 'Y')
  411. kc->its_qbin = (char)(cnfgBitsPerChar(kc->hSession) == 8 ? 'N' : K_QBIN);
  412. if (IN_RANGE(kc->its_qbin, 33, 62) || IN_RANGE(kc->its_qbin, 96, 126))
  413. *bp++ = kc->its_qbin;
  414. else
  415. *bp++ = 'N', kc->its_qbin = '\0';
  416. /* CHKT */
  417. if (!IN_RANGE(kc->its_chkt, 1, 3))
  418. kc->its_chkt = 1;
  419. *bp++ = (unsigned char)(kc->its_chkt + '0');
  420. /* REPT */
  421. if (IN_RANGE(kc->its_rept, 33, 62) || IN_RANGE(kc->its_rept, 96, 126))
  422. *bp++ = kc->its_rept;
  423. else
  424. *bp++ = ' ', kc->its_rept = '\0';
  425. if (kc->its_capat) /* if sender can handle A packets, we can too */
  426. *bp++ = tochar(CAPMASK_ATTR);
  427. }
  428. return (int)(bp - bufr);
  429. }
  430. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  431. * getparams
  432. *
  433. * DESCRIPTION:
  434. *
  435. * ARGUMENTS:
  436. *
  437. * RETURNS:
  438. * nothing
  439. */
  440. void getparams(ST_KRM *kc, int initiating, unsigned char *bufr)
  441. {
  442. if (!*bufr)
  443. return;
  444. kc->its_maxl = (*bufr == ' ' ? 80 : unchar(*bufr));
  445. /* if user has shortened packet length, he must know something about
  446. intervening transmission system that other end may not know about */
  447. if (kc->its_maxl > kc->k_maxl)
  448. kc->its_maxl = kc->k_maxl;
  449. if (!*++bufr)
  450. return;
  451. kc->its_timeout = (*bufr == ' ' ? 10 : unchar(*bufr));
  452. if (!initiating && abs(kc->k_timeout - kc->its_timeout) <= 2)
  453. kc->its_timeout = kc->k_timeout + 2;
  454. if (!*++bufr)
  455. return;
  456. kc->its_npad = unchar(*bufr);
  457. if (!*++bufr)
  458. return;
  459. kc->its_padc = (char)(*bufr == ' ' ? '\0' : ctl(*bufr));
  460. if (!*++bufr)
  461. return;
  462. kc->its_eol = (char)(*bufr == ' ' ? '\r' : unchar(*bufr));
  463. if (!*++bufr)
  464. return;
  465. kc->its_qctl = (char)(*bufr == ' ' ? K_QCTL : *bufr);
  466. if (!*++bufr)
  467. return;
  468. kc->its_qbin = *bufr;
  469. if (initiating &&
  470. !(IN_RANGE(kc->its_qbin, 33, 62) || IN_RANGE(kc->its_qbin, 96, 126)))
  471. kc->its_qbin = '\0';
  472. if (!*++bufr)
  473. return;
  474. kc->its_chkt = (unsigned char)(*bufr - '0');
  475. if (initiating && kc->its_chkt != kc->k_chkt)
  476. kc->its_chkt = 1;
  477. if (!*++bufr)
  478. return;
  479. kc->its_rept = *bufr;
  480. if (!(IN_RANGE(kc->its_rept, 33, 62) || IN_RANGE(kc->its_rept, 96, 126)))
  481. kc->its_rept = '\0';
  482. if (initiating && kc->its_rept != K_REPT)
  483. kc->its_rept = '\0';
  484. if (!*++bufr)
  485. return;
  486. if (unchar(*bufr) & CAPMASK_ATTR)
  487. kc->its_capat = TRUE;
  488. return;
  489. }
  490. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  491. * kcalc_crc
  492. *
  493. * DESCRIPTION:
  494. *
  495. * ARGUMENTS:
  496. *
  497. * RETURNS:
  498. *
  499. */
  500. // #if FALSE /* implemented in machine code for speed */
  501. unsigned kcalc_crc(unsigned crc, unsigned char *data, int cnt)
  502. {
  503. unsigned int c;
  504. unsigned q;
  505. while (cnt--)
  506. {
  507. c = *data++;
  508. q = (crc ^ c) & 017;
  509. crc = (crc >> 4) ^ (q * 010201);
  510. q = (crc ^ (c >> 4)) & 017;
  511. crc = (crc >> 4) ^ (q * 010201);
  512. }
  513. return(crc);
  514. }
  515. // #endif
  516. /* end of krm.c */