xtb+.c
上传用户:duobangkj
上传日期:2007-01-07
资源大小:70k
文件大小:25k
源码类别:

Telnet客户端

开发平台:

Unix_Linux

  1. /* xtb+.c -- CIS B+ Protocol module for XT
  2. This file uses 4-character tabstops
  3.  */
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <signal.h>
  9. #include <fcntl.h>
  10. #include <ctype.h>
  11. #define NOREDEF 1 /* prevents xt.h from redefining fprint, fputc, fputs */
  12. #include "xt.h"
  13. #define min(x,y) ((int)(x)<(int)(y)?(x):(y))
  14. #define max(x,y) ((int)(x)>(int)(y)?(x):(y))
  15. #define MaskLowRange 0x01
  16. #define MaskHiRange 0x10
  17. #define Send_Ahead_Buffers 5
  18. #define ETX 0x3 /* ^C */
  19. #define DLE 0x10 /* ^P */
  20. #define XON 0x11 /* ^Q */
  21. #define XOFF 0x13 /* ^S */
  22. #define NAK   0x15 /* ^U */
  23. enum {
  24. Check_B,
  25. Check_CRC
  26. } ;
  27. enum {
  28. Quote_Default,
  29. Quote_Not_NULL,
  30. Quote_Extended,
  31. Quote_Full,
  32. Quote_Mask
  33. } ;
  34. enum {
  35. Overwrite,
  36. Resume
  37. } ;
  38. enum {
  39. Resume_Allowed,
  40. Resume_Not_Allowed,
  41. Resume_Failed,
  42. Resume_Denied
  43. } ;
  44. typedef enum {
  45. S_Get_DLE,
  46. S_DLE_Seen,
  47. S_DLE_B_Seen,
  48. S_Get_Data,
  49. S_Get_check,
  50. S_Get_CRC,
  51. S_Verify_CRC,
  52. S_Verify_CKS,
  53. S_Verify_Packet,
  54. S_Send_NAK,
  55. S_Send_ACK,
  56. S_Send_ENQ,
  57. S_Resend_Packets
  58. } Sender_Action;
  59. #define LOC_BUF 2064
  60. extern short cr_add;
  61. extern void cl_line();
  62. static char S_Buffer[LOC_BUF], R_Buffer[LOC_BUF], O_Buffer[2 * LOC_BUF],
  63. tdir[32];
  64. char Name[SM_BUFF];
  65. static unchar Mask[32];
  66. static unsigned Checksum;
  67. static int Ch, /* last char read from remote */
  68. Quoting, /* quoting level requested by the user */
  69. Window_Size, /* Send size of send ahead window */
  70. Packet_Size, /* Maximum block size. */
  71. R_Buffer_Len, O_Buffer_Len, Seq_Num, Pending_Count,
  72. Next_Packet, Packets_Btwn_ACKs, Last_ACK, textmode, Last_Chr,
  73. Send_Errors, Read_Errors;
  74. static short Max_Errors=10, Abort_Flag, Not_Masked, Sent_ENQ, Actual_Check,
  75. Valid_To_Resume_Download, Valid_To_Resume_Upload,
  76. Send_File_Information, Packet_Received, Result;
  77. static long already_have, data, total_read, total_sent,
  78. fsize, carriage_return;
  79. static time_t start;
  80. static FILE *Data_File;
  81. struct {
  82. int Seq;
  83. int Packet_Size;
  84. char *packet;
  85. } Pending[Send_Ahead_Buffers];
  86. /* crc_xmodem_tab calculated by Mark G. Mendel, Network Systems Corporation */
  87. ushort crc_xmodem_tab[256] = {
  88.  0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
  89.  0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
  90.  0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
  91.  0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
  92.  0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
  93.  0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
  94.  0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
  95.  0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
  96.  0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
  97.  0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
  98.  0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
  99.  0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
  100.  0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
  101.  0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
  102.  0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
  103.  0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
  104.  0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
  105.  0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
  106.  0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
  107.  0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
  108.  0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
  109.  0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
  110.  0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
  111.  0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
  112.  0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
  113.  0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
  114.  0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
  115.  0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
  116.  0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
  117.  0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
  118.  0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
  119.  0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
  120. };
  121. static void
  122. init_check()
  123. {
  124. Checksum=Actual_Check ? 0xffff : 0;
  125. }
  126. static void
  127. do_checksum(ch)
  128. unsigned ch;
  129. {
  130. if (Actual_Check==Check_B){
  131. Checksum<<=1;
  132. if (Checksum>255)
  133. Checksum=(Checksum&0xff)+1;
  134. Checksum+=ch&0xFF;
  135. if (Checksum>255)
  136. Checksum=(Checksum&0xff)+1;
  137. } else
  138. Checksum=(crc_xmodem_tab[((Checksum>>8)^ch)&0xff]^(Checksum<<8))&0xffff;
  139. }
  140. /* #define CIS_DEBUG*/ /* for B+ logging */
  141. #ifdef CIS_DEBUG
  142. static FILE *bfp;
  143. static void
  144. xtlog(dir, val)
  145. char dir;
  146. int val;
  147. {
  148. static int cnt, lastdir;
  149. if (!bfp)
  150. bfp=fopen("xtb+log","w"),
  151. cnt=0,
  152. lastdir=dir;
  153. if (++cnt>20||lastdir!=dir)
  154. fputc('n',bfp),
  155. cnt=1;
  156. if (lastdir!=dir)
  157. fputc('n',bfp);
  158. if (val>'~'||val<' ')
  159. fprintf(bfp,"%c%1x%1x ",dir,val/16,val%16);
  160. else
  161. fprintf(bfp,"%c%c  ",dir,val);
  162. lastdir=dir;
  163. }
  164. static void
  165. Why_NAK(reason)
  166. char *reason;
  167. {
  168. sprintf(Msg,"Sending NAK, %s",reason);
  169. S0(Msg);
  170. }
  171. #else
  172. #define xtlog(dir,val)
  173. #define Why_NAK(reason)
  174. #endif
  175. static void
  176. stats(count)
  177. int count;
  178. {
  179. int rate, minutes, sec, data_percent;
  180. long chars, rem;
  181. time_t elapsed, now;
  182. data+=count;
  183. if (!fsize)
  184. data_percent=0;
  185. else
  186. data_percent=100*(data+carriage_return)/fsize;
  187. if (data_percent>100)
  188. data_percent=100;
  189. now=mtime();
  190. elapsed=now-start;
  191. chars=data+carriage_return-already_have-(tdir[0]=='T'?Packet_Size:0);
  192. if (elapsed<1000 || !chars)
  193. ttgoto(LI-6,26),
  194. fputs("estimating",tfp);
  195. else
  196. rate=100*chars/elapsed,
  197. rate*=10,
  198. rem=(fsize-(data+carriage_return-already_have))/rate,
  199. minutes=rem/60,
  200. sec=rem%60,
  201. ttgoto(LI-6,26),
  202. fprintf(tfp,"%8.1d:%2.2d",minutes,sec),
  203. elapsed/=1000,
  204. minutes=elapsed/60,
  205. sec=elapsed%60,
  206. ttgoto(LI-6,61),
  207. fprintf(tfp,"%8.1d:%2.2d",minutes,sec),
  208. ttgoto(LI-4,23),
  209. fprintf(tfp,"Rate: %d characters per second ", rate);
  210. ttgoto(LI-8,0),
  211. fprintf(tfp,"%8.1ld",total_sent),
  212. ttgoto(LI-8,20),
  213. fprintf(tfp,"%8.1ld",total_read),
  214. ttgoto(LI-8,40);
  215. if (!data_percent)
  216. fprintf(tfp,"%8.1ld",data);
  217. else
  218. fprintf(tfp,"%8.1ld %3.1u %%",data,data_percent);
  219. if (carriage_return)
  220. ttgoto(LI-8,60),
  221. fprintf(tfp,"%+7.1ld",carriage_return);
  222. }
  223. static void
  224. showmode()
  225. {
  226. int l;
  227. sprintf(Msg,"%s %s (%ld bytes) as %s",tdir,Name,fsize,
  228. textmode?"ASCII":"BINARY");
  229. ttgoto(LI-12,0);
  230. cl_line();
  231. if ((l=strlen(Msg)) < CO)
  232. ttgoto(LI-12,(CO-l)/2 -1);
  233. fputs(Msg,tfp);
  234. start=mtime();
  235. }
  236. static void
  237. Discard_ACKed_Packets()
  238. {
  239. int i, n;
  240. short Packet_Acked=FALSE;
  241. Last_ACK=Ch;
  242. n=(Next_Packet+Pending_Count)%Send_Ahead_Buffers;
  243. for (i=Pending_Count;i>0;i--){
  244. n--;
  245. if (n<0)
  246. n+=5;
  247. if (Pending[n].Seq==Ch-'0')
  248. Packet_Acked=TRUE,
  249. Next_Packet=(n+1)%Send_Ahead_Buffers;
  250. if (Packet_Acked==TRUE)
  251. free(Pending[n].packet),
  252. Pending[n].packet=NIL(char),
  253. Pending_Count--;
  254. }
  255. }
  256. static void
  257. Send_Byte(ch)
  258. int ch;
  259. {
  260. sendbyte(ch);
  261. total_sent++;
  262. xtlog('>',ch);
  263. }
  264. static void
  265. Add_Masked_Byte(ch)
  266. int ch;
  267. {
  268. if (ch<0x20 &&
  269. (Quoting==Quote_Full||(Mask[ch]&MaskLowRange)))
  270. O_Buffer[O_Buffer_Len++]=(char) DLE,
  271. ch+='@';
  272. else if (ch>=0x80 && ch<0xA0 &&
  273. (Quoting==Quote_Full||(Mask[ch-0x80]&MaskHiRange)))
  274. O_Buffer[O_Buffer_Len++]=(char) DLE,
  275. ch=ch+'`'-0x80;
  276. else if (ch==0xff)
  277. O_Buffer[O_Buffer_Len++]=(char) ch;
  278. O_Buffer[O_Buffer_Len++]=(char) ch;
  279. }
  280. static
  281. Read_Byte()
  282. {
  283. if ((Ch=readbyte(10))== -1)
  284. return FAILURE;
  285. total_read++;
  286. xtlog('<',Ch);
  287. return SUCCESS;
  288. }
  289. static
  290. Read_Masked_Byte()
  291. {
  292. Not_Masked=TRUE;
  293. if (!Read_Byte())
  294. return FAILURE;
  295. if (Ch==DLE){
  296. if (!Read_Byte())
  297. return FAILURE;
  298. Not_Masked=FALSE;
  299. if (Ch>='`')
  300. Ch+=0x80;
  301. Ch&=0x9F;
  302. }
  303. if (Ch==0xff)
  304. if (!Read_Byte())
  305. return FAILURE;
  306. return SUCCESS;
  307. }
  308. static void
  309. Send_ACK()
  310. {
  311. Send_Byte(DLE);
  312. Send_Byte(Seq_Num+'0');
  313. }
  314. static void
  315. Init()
  316. {
  317. int i;
  318. R_Buffer_Len=Window_Size=Pending_Count=Next_Packet=
  319. Seq_Num=Packets_Btwn_ACKs=Last_ACK=0;
  320. Packet_Size=LG_BUFF;
  321. Quoting=Quote_Mask;
  322. for (i=0;i<Send_Ahead_Buffers;i++)
  323. Pending[i].packet=NIL(char);
  324. Actual_Check=Check_B;
  325. Abort_Flag=Sent_ENQ=FALSE;
  326. memset(Mask,0,32);
  327. Mask[ETX]=Mask[ENQ]=Mask[DLE]=Mask[NAK]=Mask[XON]=Mask[XOFF]=MaskLowRange;
  328. total_sent=total_read=data=fsize=Read_Errors=Send_Errors=
  329. already_have=carriage_return=0;
  330. fputs("nnnnnnnnnnnnnnn",tfp);
  331. ttgoto(LI-14,25);
  332. S1("CIS B-Plus Protocol Transfer");
  333. ttgoto(LI-10,0);
  334. fputs("B+ Bytes Sent       B+ Bytes Rcvd",tfp);
  335. ttgoto(LI-10,40);
  336. fputs("Data Bytes          Carriage Returns",tfp);
  337. ttgoto(LI-6,10);
  338. fputs("Time Remaining:",tfp);
  339. ttgoto(LI-6,48);
  340. fputs("Elapsed Time:",tfp);
  341. }
  342. static void
  343. Xmit_Packet(Size, Seq, Packet)
  344. int Size, Seq;
  345. unchar *Packet;
  346. {
  347. register int I;
  348. init_check();
  349. O_Buffer_Len=0;
  350. O_Buffer[O_Buffer_Len++]=(char) DLE;
  351. O_Buffer[O_Buffer_Len++]=(char) 'B';
  352. O_Buffer[O_Buffer_Len++]=(char) Seq+'0';
  353. do_checksum(Seq+'0');
  354. for (I=0;I<Size;I++)
  355. Add_Masked_Byte(Packet[I]),
  356. do_checksum(Packet[I]);
  357. O_Buffer[O_Buffer_Len++]=(char) ETX;
  358. do_checksum(ETX);
  359. if (Actual_Check==Check_B)
  360. Add_Masked_Byte(Checksum);
  361. else
  362. Add_Masked_Byte(Checksum>>8),
  363. Add_Masked_Byte(Checksum&0xff);
  364. send_string(O_Buffer, O_Buffer_Len);
  365. total_sent += O_Buffer_Len;
  366. for (I=0;I<O_Buffer_Len;I++)
  367. xtlog('>',O_Buffer[I]&0xff);
  368. }
  369. static
  370. Wait_For_ACK(Have_DLE_B, Acknowledge, Resend)
  371. short Have_DLE_B, Acknowledge, Resend;
  372. {
  373. Sender_Action Action;
  374. int i=0, n, RCV_Num, Errors=0;
  375. R_Buffer_Len=0;
  376. Packet_Received=FALSE;
  377. if (Have_DLE_B)
  378. Action=S_DLE_B_Seen;
  379. else
  380. Action=S_Get_DLE;
  381. while (Errors<Max_Errors)
  382. switch (Action){
  383. case S_Get_Data:
  384. if (Read_Masked_Byte()==FAILURE){
  385. Action=S_Send_NAK;
  386. Why_NAK("couldn't read next data byte");
  387. } else if (Not_Masked && Ch==ETX)
  388. Action=S_Get_check;
  389. else if (Not_Masked && Ch==ENQ)
  390. Action=S_Send_ACK;
  391. else if (i>Packet_Size){
  392. Action=S_Send_NAK;
  393. Why_NAK("incoming buffer overflow");
  394. } else
  395. R_Buffer[i++]=Ch,
  396. do_checksum(Ch);
  397. break;
  398. case S_Get_DLE:
  399. if (Packets_Btwn_ACKs>Window_Size+2&&Pending_Count){
  400. Packets_Btwn_ACKs=0;
  401. Action=S_Send_ENQ;
  402. continue;
  403. }
  404. if (!Read_Byte())
  405. Action=S_Send_ENQ;
  406. else if (Ch==DLE)
  407. Action=S_DLE_Seen;
  408. else if (Ch==NAK)
  409. Action=S_Send_ENQ;
  410. else if (Ch==ENQ)
  411. Action=S_Send_ACK;
  412. else if (Ch==ETX){
  413. Action=S_Send_NAK;
  414. Why_NAK("awaiting DLE, got ETX");
  415. }
  416. break;
  417. case S_DLE_Seen:
  418. if (!Read_Byte())
  419. Action=S_Send_ENQ;
  420. else if (Ch>='0'&&Ch<='9')
  421. if (Sent_ENQ&&Ch==Last_ACK){
  422. Sent_ENQ=FALSE;
  423. if (!Pending_Count)
  424. return SUCCESS;
  425. else
  426. Action=S_Resend_Packets;
  427. } else {
  428. Discard_ACKed_Packets();
  429. if (Sent_ENQ)
  430. Action=S_Get_DLE;
  431. else
  432. return SUCCESS;
  433. }
  434. else if (Ch==';')
  435. Action=S_Get_DLE;
  436. else if (Ch=='B')
  437. Action=S_DLE_B_Seen;
  438. else if (Ch==ENQ)
  439. Action=S_Send_ACK;
  440. else
  441. Action=S_Get_DLE;
  442. break;
  443. case S_DLE_B_Seen:
  444. if (!Read_Byte()){
  445. Action=S_Send_NAK;
  446. Why_NAK("no data byte after DLE-B");
  447. } else if (Ch==ENQ)
  448. Action=S_Send_ACK;
  449. else {
  450. init_check();
  451. RCV_Num=Ch-'0';
  452. do_checksum(Ch);
  453. i=0;
  454. Action=S_Get_Data;
  455. }
  456. break;
  457. case S_Get_check:
  458. do_checksum(ETX);
  459. if (Read_Masked_Byte()==FAILURE){
  460. Action=S_Send_NAK;
  461. Why_NAK("no incoming checksum");
  462. } else if (Not_Masked&&Ch==ENQ)
  463. Action=S_Send_ACK;
  464. else if (Actual_Check==Check_CRC)
  465. Action=S_Get_CRC;
  466. else
  467. Action=S_Verify_CKS;
  468. break;
  469. case S_Get_CRC:
  470. do_checksum(Ch);
  471. if (Read_Masked_Byte()==FAILURE){
  472. Action=S_Send_NAK;
  473. Why_NAK("no incoming CRC value");
  474. } else if (Not_Masked&&Ch==ENQ)
  475. Action=S_Send_ACK;
  476. else
  477. Action=S_Verify_CRC;
  478. break;
  479. case S_Verify_CRC:
  480. do_checksum(Ch);
  481. if (!Checksum)
  482. Action=S_Verify_Packet;
  483. else {
  484. Action=S_Send_NAK;
  485. Why_NAK("CRC error");
  486. }
  487. break;
  488. case S_Verify_CKS:
  489. if (Checksum==Ch)
  490. Action=S_Verify_Packet;
  491. else {
  492. Action=S_Send_NAK;
  493. Why_NAK("Checksum error");
  494. }
  495. break;
  496. case S_Verify_Packet:
  497. if (RCV_Num==((Seq_Num+1)%10)||R_Buffer[0]=='F'){
  498. Packets_Btwn_ACKs++;
  499. Seq_Num=RCV_Num;
  500. if (Acknowledge)
  501. Send_ACK();
  502. R_Buffer_Len=i;
  503. Packet_Received=TRUE;
  504. return FAILURE;
  505. } else if (RCV_Num==Seq_Num)
  506. Action=S_Send_ACK;
  507. else {
  508. Action=S_Send_NAK;
  509. Why_NAK("packet out of sequence");
  510. }
  511. break;
  512. case S_Send_NAK:
  513. ttgoto(LI-2,20);
  514. sprintf(Msg,"Read Errors: %2.1d",++Read_Errors);
  515. S;
  516. Errors++;
  517. Send_Byte(NAK);
  518. Action=S_Get_DLE;
  519. break;
  520. case S_Send_ACK:
  521. Send_ACK();
  522. Action=S_Get_DLE;
  523. break;
  524. case S_Send_ENQ:
  525. ttgoto(LI-2,40);
  526. sprintf(Msg,"Send Errors: %2.1d",++Send_Errors);
  527. S;
  528. Errors++;
  529. Sent_ENQ=TRUE;
  530. Send_Byte(ENQ);
  531. Send_Byte(ENQ);
  532. Action=S_Get_DLE;
  533. break;
  534. case S_Resend_Packets:
  535. if (Resend)
  536. for (i=0;i<Pending_Count;i++)
  537. n=(Next_Packet+i)%Send_Ahead_Buffers,
  538. Xmit_Packet(
  539. Pending[n].Packet_Size,
  540. Pending[n].Seq,
  541. Pending[n].packet);
  542. else
  543. return FAILURE;
  544. Action=S_Get_DLE;
  545. break;
  546. }
  547. return FAILURE;
  548. }
  549. static void
  550. Send_Failure(Code, Text)
  551. char Code;
  552. char *Text;
  553. {
  554. int Len, Seq;
  555. S_Buffer[0]='F';
  556. S_Buffer[1]=Code;
  557. Len=2;
  558. while (*Text)
  559. S_Buffer[Len++]= *Text++;
  560. Seq=(Seq_Num+1)%10;
  561. while (Pending_Count&&Wait_For_ACK(FALSE,FALSE,FALSE))
  562. ;
  563. Xmit_Packet(Len,Seq,S_Buffer);
  564. do
  565. Wait_For_ACK(FALSE,FALSE,FALSE);
  566. while (Packet_Received);
  567. }
  568. static
  569. Flush_Pending()
  570. {
  571. while (Pending_Count)
  572. if (!Wait_For_ACK(FALSE,TRUE,TRUE))
  573. return FAILURE;
  574. return SUCCESS;
  575. }
  576. static void
  577. Send_Abort()
  578. {
  579. fclose(Data_File);
  580. sprintf(Msg,"Transfer abort requested");
  581. S0(Msg);
  582. Send_Failure('A',Msg);
  583. }
  584. static
  585. Send_Packet(Size)
  586. int Size;
  587. {
  588. int Next, Next_Seq;
  589. char *ptr = S_Buffer;
  590. while ((Pending_Count>Window_Size))
  591. if (!Wait_For_ACK(FALSE,TRUE,TRUE)){
  592. Send_Abort();
  593. return FAILURE;
  594. }
  595. Next=(Next_Packet+Pending_Count)%Send_Ahead_Buffers;
  596. Pending_Count++;
  597. Next_Seq=Seq_Num=(Seq_Num+1)%10;
  598. Pending[Next].Seq=Next_Seq;
  599. Pending[Next].packet=(char *) malloc(Size);
  600. memcpy(Pending[Next].packet,ptr,Size);
  601. Pending[Next].Packet_Size=Size;
  602. Packets_Btwn_ACKs=0;
  603. Xmit_Packet(Size,Next_Seq,S_Buffer);
  604. return SUCCESS;
  605. }
  606. static ulong
  607. cnvAtoL(ptr)
  608. char *ptr;
  609. {
  610. ushort sign=FALSE;
  611. char ch;
  612. ulong result=0;
  613. ch= *ptr++;
  614. if (ch=='-')
  615. sign=TRUE,
  616. ch= *ptr++;
  617. while (ch>='0'&&ch<='9')
  618. result=result*10+(ch-'0'),
  619. ch= *ptr++;
  620. return(sign?-result:result);
  621. }
  622. static
  623. char *cnvLtoA(ptr, n)
  624. char *ptr;
  625. ulong n;
  626. {
  627. char tmp1[11], *tmp2=tmp1;
  628. if (!n){
  629. *ptr++ ='0';
  630. return ptr;
  631. }
  632. *tmp2++ =0;
  633. do 
  634. *tmp2++ =((char)(n%10))+'0',
  635. n/=10;
  636. while (n>0);
  637. tmp2--;
  638. while (*tmp2)
  639. *ptr++ = *tmp2--;
  640. return ptr;
  641. }
  642. static void
  643. Send_Unexpected_Packet()
  644. {
  645. sprintf(Msg,"Unexpected packet type");
  646. S0(Msg);
  647. Send_Failure('N',Msg);
  648. }
  649. FILE *
  650. QueryCreate(Offer_Resume)
  651. short Offer_Resume;
  652. {
  653. int key;
  654. short Condition;
  655. FILE *fileptr;
  656. Condition = isregfile(Name) ? Offer_Resume : Resume_Denied;
  657. if (access(Name,0)&&(fileptr=fopen(Name,"w"))){
  658. Result=Overwrite;
  659. return fileptr;
  660. } else if (access(Name,2))
  661. Condition = Resume_Denied;
  662. switch(Condition){
  663. case Resume_Allowed:
  664. sprintf(Msg,"'%s' exists; Overwrite, Resume, reName, or Abort?",Name);
  665. break;
  666. case Resume_Not_Allowed:
  667. sprintf(Msg,"'%s' exists; Overwrite, reName, or Abort?",Name);
  668. break;
  669. case Resume_Failed:
  670. sprintf(Msg,"'%s' CRC error; Overwrite, reName or Abort?",Name);
  671. break;
  672. case Resume_Denied:
  673. sprintf(Msg,"Permission denied for '%s'; reName, or Abort?",Name);
  674. break;
  675. }
  676. if (cismode)
  677. S0(Msg);
  678. else
  679. S2(Msg);
  680. for (;;){
  681. beep();
  682. key=toupper(fgetc(stdin));
  683. if (isupper(key)){
  684. fputc(key,tfp);
  685. switch(key){
  686. case 'O':
  687. if (Condition!=Resume_Denied){
  688. Result=Overwrite;
  689. return fopen(Name,"w");
  690. }
  691. break;
  692. case 'N':
  693. fputc('r',tfp);
  694. cl_line();
  695. show(-1,"Enter New Name:");
  696. getline();
  697. getword();
  698. strcpy(Name,word);
  699. return QueryCreate(Offer_Resume);
  700. case 'A':
  701. return NIL(FILE);
  702. case 'R':
  703. if (Condition==Resume_Allowed){
  704. Result=Resume;
  705. return fopen(Name,"r+");
  706. }
  707. break;
  708. }
  709. fputc('b',tfp);
  710. }
  711. }
  712. }
  713. static
  714. Read(fp, buf, want)
  715. FILE *fp;
  716. char *buf;
  717. register int want;
  718. {
  719. register int c;
  720. int read=0;
  721. while (want--)
  722. switch(c=getc(fp)){
  723. case EOF:
  724. return read;
  725. case 'n':
  726. if (cr_add&&textmode&&Last_Chr!='r')
  727. ungetc(c,fp),
  728. carriage_return++,
  729. c='r';
  730. default:
  731. Last_Chr= *buf++ =c;
  732. read++;
  733. }
  734. return read;
  735. }
  736. static
  737. Write(fp, buf, want)
  738. FILE *fp;
  739. char *buf;
  740. register int want;
  741. {
  742. int written=0;
  743. for (;want-->0;buf++){
  744. if (textmode){
  745. if (*buf=='r'){
  746. Last_Chr= *buf;
  747. continue;
  748. }
  749. if (Last_Chr=='r')
  750. if (*buf=='n')
  751. carriage_return--;
  752. else
  753. if (fputc('r',fp)== -1)
  754. return -1;
  755. else
  756. written++;
  757. Last_Chr= *buf;
  758. }
  759. if (fputc(*buf,fp)== -1)
  760. return -1;
  761. else
  762. written++;
  763. }
  764. return written;
  765. }
  766. static
  767. Receive_File()
  768. {
  769. char *ptr;
  770. int N, i;
  771. short Request_Resume;
  772. Result=Overwrite;
  773. if (Valid_To_Resume_Download==2)
  774. Request_Resume=Resume_Allowed;
  775. else
  776. Request_Resume=Resume_Not_Allowed;
  777. if (!(Data_File=QueryCreate(Request_Resume))){
  778. Send_Abort();
  779. return FAILURE;
  780. }
  781. if (Result==Resume){
  782. strcpy(tdir,"Attempting receive resume of");
  783. init_check();
  784. do {
  785. S_Buffer[0]='N';
  786. N=Read(Data_File,&S_Buffer[0],Packet_Size);
  787. if (N>0){
  788. for (i=0;i<N;i++)
  789. do_checksum(S_Buffer[i]);
  790. if (Abort_Flag){
  791. Send_Abort();
  792. return FAILURE;
  793. }
  794. already_have+=N;
  795. }
  796. } while (N>0);
  797. ptr= &S_Buffer[0];
  798. *ptr++ ='T';
  799. *ptr++ ='r';
  800. ptr=cnvLtoA(ptr,already_have);
  801. *ptr++ =' ';
  802. ptr=cnvLtoA(ptr,Checksum);
  803. if (!Send_Packet(ptr- &S_Buffer[0])||!Flush_Pending()){
  804. fclose(Data_File);
  805. S0("Can't resume transfer");
  806. return FAILURE;
  807. }
  808. fseek(Data_File,0L,2);
  809. strcpy(tdir,"Resuming receive of");
  810. data=already_have-carriage_return;
  811. carriage_return= -carriage_return;
  812. showmode();
  813. } else
  814. Send_ACK(),
  815. strcpy(tdir,"Receiving"),
  816. already_have=0;
  817. for (;;){
  818. if (Abort_Flag){
  819. Send_Abort();
  820. return FAILURE;
  821. }
  822. Wait_For_ACK(FALSE,TRUE,TRUE);
  823. if (Packet_Received)
  824. switch(R_Buffer[0]){
  825. case 'N':
  826. if ((N=Write(Data_File,&R_Buffer[1],R_Buffer_Len-1))== -1){
  827. sprintf(Msg,"Disk write error");
  828. S0(Msg);
  829. Send_Failure('I',Msg);
  830. fclose(Data_File);
  831. return FAILURE;
  832. }
  833. stats(N);
  834. break;
  835. case 'T':
  836. switch(R_Buffer[1]){
  837. case 'I':
  838. fsize=cnvAtoL(&R_Buffer[4]);
  839. showmode();
  840. break;
  841. case 'C':
  842. fclose(Data_File);
  843. return SUCCESS;
  844. case 'f':
  845. fclose(Data_File);
  846. if (!(Data_File=QueryCreate(Resume_Failed))){
  847. Send_Abort();
  848. return FAILURE;
  849. }
  850. strcpy(tdir,"Receiving");
  851. data=already_have=carriage_return=0;
  852. showmode();
  853. break;
  854. default:
  855. Send_Unexpected_Packet();
  856. fclose(Data_File);
  857. return FAILURE;
  858. }
  859. break;
  860. case 'F':
  861. fclose(Data_File);
  862. R_Buffer[R_Buffer_Len]=0;
  863. if (Result==Resume)
  864. sprintf(Msg,"Can't resume transfer: %s",&R_Buffer[3]);
  865. else
  866. sprintf(Msg,"B protocol Failure: %s",&R_Buffer[3]);
  867. S0(Msg);
  868. return FAILURE;
  869. default:
  870. Send_Unexpected_Packet();
  871. fclose(Data_File);
  872. return FAILURE;
  873. }
  874. else {
  875. fclose(Data_File);
  876. return FAILURE;
  877. }
  878. }
  879. }
  880. static char *
  881. Handle_Send_Failure()
  882. {
  883. if (!R_Buffer_Len)
  884. return("Remote is not responding");
  885. else {
  886. if (R_Buffer[0]=='F'){
  887. if (R_Buffer_Len>=2){
  888. R_Buffer[min(81,R_Buffer_Len)]='';
  889. return(&R_Buffer[1]);
  890. } else
  891. return("No reason given by remote");
  892. } else {
  893. Send_Failure('E',"Unexpected packet type");
  894. return("Unexpected packet type");
  895. }
  896. }
  897. }
  898. static
  899. Send_File()
  900. {
  901. int N;
  902. struct stat statbuf;
  903. if (!(Data_File=fopen(Name,"r"))){
  904. sprintf(Msg,"Can't access '%s'",Name);
  905. S0(Msg);
  906. Send_Failure('M',Msg);
  907. return FAILURE;
  908. }
  909. fstat(fileno(Data_File),&statbuf);
  910. fsize=statbuf.st_size;
  911. strcpy(tdir,"Transmitting");
  912. showmode();
  913. do {
  914. S_Buffer[0]='N';
  915. N=Read(Data_File,&S_Buffer[1],Packet_Size);
  916. if (N>0){
  917. if (!Send_Packet(N+1)){
  918. fclose(Data_File);
  919. S0(Handle_Send_Failure());
  920. return FAILURE;
  921. }
  922. if (Abort_Flag){
  923. Send_Abort();
  924. return FAILURE;
  925. }
  926. stats(N);
  927. }
  928. } while (N>0);
  929. if (!N){
  930. fclose(Data_File);
  931. S_Buffer[0]='T';
  932. S_Buffer[1]='C';
  933. if (!Send_Packet(2)){
  934. S0(Handle_Send_Failure());
  935. return FAILURE;
  936. }
  937. return Flush_Pending();
  938. } else {
  939. sprintf(Msg,"Disk read error");
  940. S0(Msg);
  941. Send_Failure('I',Msg);
  942. return FAILURE;
  943. }
  944. }
  945. #define Plus_Packet_Size 18
  946. #define LowRange 7
  947. #define HiRange 11
  948. #define My_Send_Window_Size 1
  949. #define My_Recv_Window_Size 1
  950. #define My_Buffer_Size 8
  951. #define My_Check_Method Check_CRC
  952. #define My_Download_Resume 2
  953. #define My_Upload_Resume 0
  954. #define My_File_Information 1
  955. static char Quote_Level_Select_Low[]={
  956. 1, 3, 3, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  957. 0, 0, 3, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
  958. };
  959. static char QuotE_Level_select_Hi[]={
  960. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  961. 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
  962. };
  963. static char QUote_Level_Mapping[]={
  964. Quote_Not_NULL,
  965. Quote_Default,
  966. Quote_Extended,
  967. Quote_Full
  968. };
  969. static
  970. Plus_Respond()
  971. {
  972. int Status, temp_window_size, temp_method, temp_size, MaskByte, Bit, i;
  973. char Estimated_Quote_Level=0;
  974. S_Buffer[0]='+';
  975. S_Buffer[1]=My_Send_Window_Size;
  976. S_Buffer[2]=My_Recv_Window_Size;
  977. S_Buffer[3]=Packet_Size/128;
  978. S_Buffer[4]=My_Check_Method;
  979. S_Buffer[5]=Quote_Default;
  980. S_Buffer[6]=FALSE;
  981. S_Buffer[15]=My_Download_Resume;
  982. S_Buffer[16]=My_Upload_Resume;
  983. S_Buffer[17]=My_File_Information;
  984. for (i=0;i<8;i++)
  985. S_Buffer[i+LowRange]=0;
  986. for (MaskByte=0;MaskByte<4;MaskByte++)
  987. for (Bit=0;Bit<8;Bit++){
  988. if (Mask[MaskByte*8+Bit]&MaskLowRange)
  989. S_Buffer[MaskByte+LowRange]|=0x80>>Bit;
  990. if (Mask[MaskByte*8+Bit]&MaskHiRange)
  991. S_Buffer[MaskByte+HiRange]|=0x80>>Bit;
  992. }
  993. for (i=R_Buffer_Len;i<Plus_Packet_Size;i++)
  994. R_Buffer[i]=0;
  995. if (R_Buffer[3]<S_Buffer[3])
  996. temp_size=(R_Buffer[3]*128);
  997. else
  998. temp_size=(S_Buffer[3]*128);
  999. temp_window_size=min(R_Buffer[2],My_Send_Window_Size);
  1000. temp_method=min(R_Buffer[4],My_Check_Method);
  1001. Valid_To_Resume_Download=min(R_Buffer[15],My_Download_Resume);
  1002. Valid_To_Resume_Upload=min(R_Buffer[16],My_Upload_Resume);
  1003. Send_File_Information=min(R_Buffer[17],My_File_Information);
  1004. if (R_Buffer_Len>=Plus_Packet_Size)
  1005. for (MaskByte=0;MaskByte<4;MaskByte++)
  1006. for (Bit=0;Bit<8;Bit++){
  1007. if (R_Buffer[LowRange+MaskByte]&(0x80>>Bit))
  1008. Mask[MaskByte*8+Bit]|=MaskLowRange;
  1009. if (R_Buffer[HiRange+MaskByte]&(0x80>>Bit))
  1010. Mask[MaskByte*8+Bit]|=MaskHiRange;
  1011. }
  1012. else {
  1013. for (i=0;i<32&&Estimated_Quote_Level<3;i++){
  1014. if (Mask[i]&MaskLowRange)
  1015. Estimated_Quote_Level=
  1016. max(Quote_Level_Select_Low[i],Estimated_Quote_Level);
  1017. if (Mask[i]&MaskHiRange)
  1018. Estimated_Quote_Level=
  1019. max(QuotE_Level_select_Hi[i],Estimated_Quote_Level);
  1020. }
  1021. }
  1022. Quoting=Quote_Full;
  1023. S_Buffer[5]=QUote_Level_Mapping[Estimated_Quote_Level];
  1024. if (Status=Send_Packet(Plus_Packet_Size))
  1025. if (Status=Flush_Pending()){
  1026. Actual_Check=temp_method;
  1027. Packet_Size=temp_size;
  1028. Window_Size=temp_window_size;
  1029. }
  1030. Quoting=Quote_Mask;
  1031. return Status;
  1032. }
  1033. static
  1034. Do_Transfer()
  1035. {
  1036. int I, N;
  1037. short Have_DLE_B=TRUE;
  1038. for (;;){
  1039. Wait_For_ACK(Have_DLE_B,FALSE,TRUE);
  1040. if (Packet_Received){
  1041. if (R_Buffer[0]=='T'){
  1042. if (R_Buffer[1]!='D'&&R_Buffer[1]!='U'){
  1043. S0("Invalid transfer direction");
  1044. Send_Failure('N',"Not implemented");
  1045. return FAILURE;
  1046. }
  1047. if (R_Buffer[2]!='A'&&R_Buffer[2]!='B'){
  1048. S0("Invalid transfer type");
  1049. Send_Failure('N',"Not implemented");
  1050. return FAILURE;
  1051. }
  1052. N=min(R_Buffer_Len-3,SM_BUFF-1);
  1053. for (I=0;I<N;I++)
  1054. Name[I]=R_Buffer[I+3];
  1055. Name[I]='';
  1056. textmode=(R_Buffer[2]=='A');
  1057. if (R_Buffer[1]=='U'){
  1058. Send_ACK();
  1059. return Send_File();
  1060. } else
  1061. return Receive_File();
  1062. } else if (R_Buffer[0]=='+'){
  1063. if (Plus_Respond())
  1064. Have_DLE_B=FALSE;
  1065. else {
  1066. S0("Could not negotiate B-Plus parameters");
  1067. return FAILURE;
  1068. }
  1069. } else {
  1070. Send_Unexpected_Packet();
  1071. return FAILURE;
  1072. }
  1073. } else {
  1074. S0("Remote is not responding");
  1075. return FAILURE;
  1076. }
  1077. }
  1078. }
  1079. static
  1080. RETSIGTYPE cisbsigint(junk)
  1081. int junk;
  1082. {
  1083. signal(SIGINT,cisbsigint);
  1084. Abort_Flag=TRUE;
  1085. }
  1086. void
  1087. B_Transfer()
  1088. {
  1089. short Status=FALSE;
  1090. RETSIGTYPE (*oldvec)();
  1091. oldvec = signal(SIGINT,cisbsigint);
  1092. cur_off();
  1093. Init();
  1094. while (readbyte(1) != -1)
  1095. ;
  1096. Send_Byte(DLE);
  1097. Send_Byte('+');
  1098. Send_Byte('+');
  1099. Send_ACK();
  1100. Read_Byte();
  1101. switch(Ch){
  1102. case DLE:
  1103. Read_Byte();
  1104. if (Ch=='B')
  1105. Status=Do_Transfer();
  1106. break;
  1107. default:
  1108. fputc(Ch,tfp);
  1109. break;
  1110. }
  1111. sprintf(Msg,"File Transfer %s",Status?"Succeeded":"Failed");
  1112. S0(Msg);
  1113. beep();
  1114. if (Abort_Flag){
  1115. while (Read_Byte() && Ch==ENQ){
  1116. Seq_Num=0;
  1117. Send_Byte(DLE);
  1118. Send_Byte('+');
  1119. Send_Byte('+');
  1120. Send_ACK();
  1121. }
  1122. }
  1123. cur_on();
  1124. signal(SIGINT,oldvec);
  1125. }