home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / sources / misc / 3953 < prev    next >
Encoding:
Text File  |  1992-09-14  |  57.1 KB  |  2,421 lines

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
  4. Subject:  v32i061:  ecu - ECU Asynchronous Communications v3.20, Part26/40
  5. Message-ID: <1992Sep14.144808.22156@sparky.imd.sterling.com>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: 4abfd625d7ffa3328f17ca8f380a5912
  8. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  9. Organization: Sterling Software
  10. References: <csm-v32i036=ecu.141245@sparky.IMD.Sterling.COM>
  11. Date: Mon, 14 Sep 1992 14:48:08 GMT
  12. Approved: kent@sparky.imd.sterling.com
  13. Lines: 2406
  14.  
  15. Submitted-by: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
  16. Posting-number: Volume 32, Issue 61
  17. Archive-name: ecu/part26
  18. Environment: SCO,XENIX,ISC,SUNOS,SYSVR4,HDB,Curses
  19. Supersedes: ecu: Volume 21, Issue 53-89
  20.  
  21. ---- Cut Here and feed the following to sh ----
  22. #!/bin/sh
  23. # this is ecu320.26 (part 26 of ecu320)
  24. # do not concatenate these parts, unpack them in order with /bin/sh
  25. # file z/zcurses.c continued
  26. #
  27. if test ! -r _shar_seq_.tmp; then
  28.     echo 'Please unpack part 1 first!'
  29.     exit 1
  30. fi
  31. (read Scheck
  32.  if test "$Scheck" != 26; then
  33.     echo Please unpack part "$Scheck" next!
  34.     exit 1
  35.  else
  36.     exit 0
  37.  fi
  38. ) < _shar_seq_.tmp || exit 1
  39. if test ! -f _shar_wnt_.tmp; then
  40.     echo 'x - still skipping z/zcurses.c'
  41. else
  42. echo 'x - continuing file z/zcurses.c'
  43. sed 's/^X//' << 'SHAR_EOF' >> 'z/zcurses.c' &&
  44. X    report_file_close(skipped)
  45. X--------------------------------------------------------------------------*/
  46. Xvoid report_file_close(skipped)
  47. Xint skipped;
  48. X{
  49. X    if(dumbtty)
  50. X    {
  51. X        dumbtty_newline();
  52. X        dumbtty_pos +=
  53. X            printf("Transfer time was %s",get_elapsed_time(elapsed_seconds));
  54. X        dumbtty_newline();
  55. X        if(s128[0])
  56. X        {
  57. X            dumbtty_pos += strlen(s128 + 9);
  58. X            fputs(s128 + 9,stdout);
  59. X            dumbtty_newline();
  60. X        }
  61. X        if(this_file_errors)
  62. X        {
  63. X            dumbtty_pos +=
  64. X                printf("Errors for this file were %d",this_file_errors);
  65. X            dumbtty_newline();
  66. X        }
  67. X        return;
  68. X    }
  69. X
  70. X    if(show_window)
  71. X    {
  72. X        clear_area(win,9,50,8);
  73. X        waddstr(win,"+0");
  74. X        Txpos = 0;
  75. X        Rxpos = 0;
  76. X    }
  77. X
  78. X    report_str("End of file",0);
  79. X    if(!skipped)
  80. X    {
  81. X        report_file_xfer_rate("last file",
  82. X            this_file_xfer_count - initial_filepos,1);
  83. X    }
  84. X    wrefresh(win);
  85. X    this_file_start_seconds = 0;
  86. X
  87. X}    /* end of report_file_close */
  88. X
  89. X/*+-------------------------------------------------------------------------
  90. X    report_comm_baud_rate(baud_rate)
  91. X
  92. X baud rate: row 7 col 14 length 5
  93. X--------------------------------------------------------------------------*/
  94. Xreport_comm_baud_rate(baud_rate)
  95. Xunsigned int baud_rate;
  96. X{
  97. X    char tstr8[8];
  98. X
  99. X    zcurses_baud_rate = baud_rate;
  100. X
  101. X    if(dumbtty)
  102. X    {
  103. X        return;
  104. X    }
  105. X
  106. X    clear_area(win,7,14,5);
  107. X    if(baud_rate == 0)
  108. X        waddstr(win,"?");
  109. X    else
  110. X
  111. X    {
  112. X        sprintf(tstr8,"%-5u",baud_rate);
  113. X        waddstr(win,tstr8);
  114. X    }
  115. X    wrefresh(win);
  116. X
  117. X}    /* end of report_comm_baud_rate */
  118. X
  119. X/*+-------------------------------------------------------------------------
  120. X    report_file_byte_io(count)
  121. X--------------------------------------------------------------------------*/
  122. Xreport_file_byte_io(count)
  123. Xlong count;
  124. X{
  125. X
  126. X    this_file_xfer_count = count;
  127. X    total_data_bytes_xfered += count;
  128. X
  129. X    if(dumbtty)
  130. X    {
  131. X        if(count)
  132. X        {
  133. X            dumbtty_newline();
  134. X            printf("Transferred %ld bytes for this file\n",count);
  135. X            dumbtty_newline();
  136. X        }
  137. X        return;
  138. X    }
  139. X
  140. X    if(total_data_bytes_xfered)
  141. X    {
  142. X        sprintf(s128,"Total file bytes transferred: %ld",
  143. X            total_data_bytes_xfered);
  144. X        report_str(s128,-1);
  145. X    }
  146. X
  147. X}    /* end of report_file_byte_io */
  148. X
  149. X/* end of zcurses.c */
  150. X/* vi: set tabstop=4 shiftwidth=4: */
  151. SHAR_EOF
  152. echo 'File z/zcurses.c is complete' &&
  153. chmod 0644 z/zcurses.c ||
  154. echo 'restore of z/zcurses.c failed'
  155. Wc_c="`wc -c < 'z/zcurses.c'`"
  156. test 42813 -eq "$Wc_c" ||
  157.     echo 'z/zcurses.c: original size 42813, current size' "$Wc_c"
  158. rm -f _shar_wnt_.tmp
  159. fi
  160. # ============= z/zdebug.c ==============
  161. if test -f 'z/zdebug.c' -a X"$1" != X"-c"; then
  162.     echo 'x - skipping z/zdebug.c (File already exists)'
  163.     rm -f _shar_wnt_.tmp
  164. else
  165. > _shar_wnt_.tmp
  166. echo 'x - extracting z/zdebug.c (Text)'
  167. sed 's/^X//' << 'SHAR_EOF' > 'z/zdebug.c' &&
  168. X/* see zcurses.c report_lasthdr() */
  169. X/*+:EDITS:*/
  170. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  171. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  172. X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
  173. X/*:08-14-1990-20:41-wht@n4hgf-ecu3.00-flush old edit history */
  174. Xint header_debug = 0;
  175. X/* vi: set tabstop=4 shiftwidth=4: */
  176. SHAR_EOF
  177. chmod 0644 z/zdebug.c ||
  178. echo 'restore of z/zdebug.c failed'
  179. Wc_c="`wc -c < 'z/zdebug.c'`"
  180. test 329 -eq "$Wc_c" ||
  181.     echo 'z/zdebug.c: original size 329, current size' "$Wc_c"
  182. rm -f _shar_wnt_.tmp
  183. fi
  184. # ============= z/zmodem.c ==============
  185. if test -f 'z/zmodem.c' -a X"$1" != X"-c"; then
  186.     echo 'x - skipping z/zmodem.c (File already exists)'
  187.     rm -f _shar_wnt_.tmp
  188. else
  189. > _shar_wnt_.tmp
  190. echo 'x - extracting z/zmodem.c (Text)'
  191. sed 's/^X//' << 'SHAR_EOF' > 'z/zmodem.c' &&
  192. X#if defined(WHT) && !defined(SHOW_ZHDR_TYPE)
  193. X#define SHOW_ZHDR_TYPE
  194. X#endif
  195. X/*+-------------------------------------------------------------------------
  196. X    zmodem.c - ZMODEM protocol primitives
  197. X    based on code by Chuck Forsberg
  198. X
  199. X  Defined functions:
  200. X    noxrd7()
  201. X    rclhdr(hdr)
  202. X    stohdr(pos)
  203. X    zdlread()
  204. X    zgeth1()
  205. X    zgethdr(hdr,eflag)
  206. X    zgethex()
  207. X    zputhex(c)
  208. X    zrbhdr(hdr)
  209. X    zrbhdr32(hdr)
  210. X    zrdat32(buf,length)
  211. X    zrdata(buf,length)
  212. X    zrhhdr(hdr)
  213. X    zsbh32(type,hdr)
  214. X    zsbhdr(type,hdr)
  215. X    zsda32(buf,length,frameend)
  216. X    zsdata(buf,length,frameend)
  217. X    zsendline(c)
  218. X    zshhdr(type,hdr)
  219. X
  220. X--------------------------------------------------------------------------*/
  221. X/*+:EDITS:*/
  222. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  223. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  224. X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
  225. X/*:08-14-1990-20:41-wht@n4hgf-ecu3.00-flush old edit history */
  226. X
  227. X#include "zmodem.h"            /* wht */
  228. X
  229. Xextern char s128[];                /* wht */
  230. Xextern int Zctlesc;                /* wht */
  231. Xextern int Zmodem;                /* wht */
  232. Xextern long cr3tab[];            /* wht */
  233. Xextern unsigned Baudrate;        /* wht */
  234. Xextern unsigned short crctab[];    /* wht */
  235. X
  236. Xint Rxtimeout = 100;        /* Tenths of seconds to wait for something */
  237. X
  238. X#if !defined(UNSL)
  239. X#define UNSL
  240. X#endif
  241. X
  242. Xstatic lastsent;    /* Last char we sent */
  243. Xstatic evenp;        /* Even parity seen on header */
  244. X
  245. X/* Globals used by ZMODEM functions */
  246. Xchar Attn[ZATTNLEN+1];    /* Attention string rx sends to tx on err */
  247. Xchar Rxhdr[4];        /* Received header */
  248. Xchar Txhdr[4];        /* Transmitted header */
  249. Xint Crc32;        /* Display flag indicating 32 bit CRC being received */
  250. Xint Crc32t;        /* Display flag indicating 32 bit CRC being sent */
  251. Xint Rxcount;        /* Count of data bytes received */
  252. Xint Rxframeind;        /* ZBIN ZBIN32,or ZHEX type of frame received */
  253. Xint Rxtype;        /* Type of header received */
  254. Xint Txfcs32;        /* TURE means send binary frames with 32 bit FCS */
  255. Xint Zrwindow;    /* RX window size (controls garbage count) */
  256. Xlong Rxpos;    /* Received file position */
  257. Xlong Txpos;    /* Transmitted file position */
  258. X
  259. Xchar *frametypes[] = {
  260. X    "Carrier Lost",        /* -3 */
  261. X    "TIMEOUT",            /* -2 */
  262. X    "ERROR",            /* -1 */
  263. X/* #define FTOFFSET 3 moved to zmodem.h */
  264. X    "ZRQINIT",
  265. X    "ZRINIT",
  266. X    "ZSINIT",
  267. X    "ZACK ",
  268. X    "ZFILE",
  269. X    "ZSKIP",
  270. X    "ZNAK ",
  271. X    "ZABORT",
  272. X    "ZFIN ",
  273. X    "ZRPOS",
  274. X    "ZDATA",
  275. X    "ZEOF ",
  276. X    "ZFERR",
  277. X    "ZCRC ",
  278. X    "ZCHALLENGE",
  279. X    "ZCOMPL",
  280. X    "ZCAN ",
  281. X    "ZFREECNT",
  282. X    "ZCOMMAND",
  283. X    "ZSTDERR",
  284. X    "xxxxx"
  285. X#define FRTYPES 22    /* Total number of frame types in this array */
  286. X    /*  not including psuedo negative entries */
  287. X};
  288. X
  289. X/*
  290. X * Send character c with ZMODEM escape sequence encoding.
  291. X *  Escape XON,XOFF. Escape CR following @ (Telenet net escape)
  292. X */
  293. Xvoid
  294. Xzsendline(c)
  295. Xint c;
  296. X{
  297. X
  298. X    /* Quick check for non control characters */
  299. X    if(c & 0140)
  300. X        xsendline(lastsent = c);
  301. X    else 
  302. X    {
  303. X        switch(c &= 0377)
  304. X        {
  305. X        case ZDLE:
  306. X            xsendline(ZDLE);
  307. X            xsendline(lastsent = (c ^= 0100));
  308. X            break;
  309. X        case 015:
  310. X        case 0215:
  311. X            if(!Zctlesc && (lastsent & 0177) != '@')
  312. X                goto sendit;
  313. X            /* **** FALL THRU TO **** */
  314. X        case 020:
  315. X        case 021:
  316. X        case 023:
  317. X        case 0220:
  318. X        case 0221:
  319. X        case 0223:
  320. X            xsendline(ZDLE);
  321. X            c ^= 0100;
  322. Xsendit:
  323. X            xsendline(lastsent = c);
  324. X            break;
  325. X        default:
  326. X            if(Zctlesc && ! (c & 0140))
  327. X            {
  328. X                xsendline(ZDLE);
  329. X                c ^= 0100;
  330. X            }
  331. X            xsendline(lastsent = c);
  332. X        }
  333. X    }
  334. X}
  335. X
  336. Xstatic char masked[] = "8 bit transparent path required";
  337. Xstatic char badcrc[] = "Bad CRC";
  338. X
  339. X/* Send ZMODEM CRC-32 binary header hdr of type type */
  340. Xvoid
  341. Xzsbh32(type,hdr)
  342. Xint type;
  343. Xregister char *hdr;
  344. X{
  345. X    register int n;
  346. X    register UNSL long crc;
  347. X
  348. X    sprintf(s128,
  349. X#ifdef SHOW_ZHDR_TYPE
  350. X        "B32 %s %ld",
  351. X#else
  352. X        "hdr %s %ld",
  353. X#endif
  354. X        frametypes[type+FTOFFSET],rclhdr(hdr));
  355. X    report_last_txhdr(s128,0);
  356. X    report_tx_ind(1);
  357. X    xsendline(ZBIN32);  
  358. X    zsendline(type);
  359. X    crc = 0xFFFFFFFFL; 
  360. X    crc = UPDC32(type,crc);
  361. X
  362. X    for(n=4; --n >= 0; ++hdr)
  363. X    {
  364. X        crc = UPDC32((0377 & *hdr),crc);
  365. X        zsendline(*hdr);
  366. X    }
  367. X    crc = ~crc;
  368. X    for(n=4; --n >= 0;)
  369. X    {
  370. X        zsendline((int)crc);
  371. X        crc >>= 8;
  372. X    }
  373. X    report_tx_ind(0);
  374. X}
  375. X
  376. X/* Send ZMODEM binary header hdr of type type */
  377. Xvoid
  378. Xzsbhdr(type,hdr)
  379. Xint type;
  380. Xregister unsigned char *hdr;
  381. X{
  382. X    register int n;
  383. X    register unsigned crc;
  384. X
  385. X    xsendline(ZPAD); 
  386. X    xsendline(ZDLE);
  387. X
  388. X    if(Crc32t=Txfcs32)
  389. X        zsbh32(type,hdr);
  390. X    else 
  391. X    {
  392. X        sprintf(s128,
  393. X#ifdef SHOW_ZHDR_TYPE
  394. X            "B16 %s %ld",
  395. X#else
  396. X            "hdr %s %ld",
  397. X#endif
  398. X            frametypes[type+FTOFFSET],rclhdr(hdr));
  399. X        report_last_txhdr(s128,0);
  400. X        report_tx_ind(1);
  401. X
  402. X        xsendline(ZBIN); 
  403. X        zsendline(type); 
  404. X        crc = updcrc(type,0);
  405. X
  406. X        for(n=4; --n >= 0; ++hdr)
  407. X        {
  408. X            zsendline(*hdr);
  409. X            crc = updcrc(*hdr,crc);
  410. X        }
  411. X        crc = updcrc(0,updcrc(0,crc));
  412. X        zsendline(crc>>8);
  413. X        zsendline(crc);
  414. X        report_tx_ind(0);
  415. X    }
  416. X    if(type != ZDATA)
  417. X        flushline();
  418. X}
  419. X
  420. X/*
  421. X * Send binary array buf of length length,with ending ZDLE sequence frameend
  422. X */
  423. Xstatic char *Zendnames[] = { "ZCRCE","ZCRCG","ZCRCQ","ZCRCW"};
  424. X
  425. Xvoid
  426. Xzsda32(buf,length,frameend)
  427. Xregister char *buf;
  428. Xint length;
  429. Xint frameend;
  430. X{
  431. X    register int c;
  432. X    register UNSL long crc;
  433. X
  434. X    sprintf(s128,
  435. X#ifdef SHOW_ZHDR_TYPE
  436. X        "D32 %s %d",
  437. X#else
  438. X        "data %s %d",
  439. X#endif
  440. X        Zendnames[frameend-ZCRCE&3],length);
  441. X    report_last_txhdr(s128,0);
  442. X    report_tx_ind(1);
  443. X
  444. X    crc = 0xFFFFFFFFL;
  445. X    for(;--length >= 0; ++buf)
  446. X    {
  447. X        c = *buf & 0377;
  448. X        if(c & 0140)
  449. X            xsendline(lastsent = c);
  450. X        else
  451. X            zsendline(c);
  452. X        crc = UPDC32(c,crc);
  453. X    }
  454. X    xsendline(ZDLE); 
  455. X    xsendline(frameend);
  456. X    crc = UPDC32(frameend,crc);
  457. X
  458. X    crc = ~crc;
  459. X    for(length=4; --length >= 0;)
  460. X    {
  461. X        zsendline((int)crc);  
  462. X        crc >>= 8;
  463. X    }
  464. X    report_tx_ind(0);
  465. X}
  466. X
  467. Xvoid
  468. Xzsdata(buf,length,frameend)
  469. Xregister unsigned char *buf;
  470. Xint length;
  471. Xint frameend;
  472. X{
  473. X    register unsigned short crc;
  474. X
  475. X    if(Crc32t)
  476. X        zsda32(buf,length,frameend);
  477. X    else 
  478. X    {
  479. X        sprintf(s128,
  480. X#ifdef SHOW_ZHDR_TYPE
  481. X            "D16 %s %d",
  482. X#else
  483. X            "data %s %d",
  484. X#endif
  485. X            Zendnames[frameend-ZCRCE&3],length);
  486. X        report_last_txhdr(s128,0);
  487. X        report_tx_ind(1);
  488. X        crc = 0;
  489. X        for(;--length >= 0; ++buf)
  490. X        {
  491. X            zsendline(*buf); 
  492. X            crc = updcrc(*buf,crc);
  493. X        }
  494. X        xsendline(ZDLE); 
  495. X        xsendline(frameend);
  496. X        crc = updcrc(frameend,crc);
  497. X
  498. X        crc = updcrc(0,updcrc(0,crc));
  499. X        zsendline(crc>>8); 
  500. X        zsendline(crc);
  501. X        report_tx_ind(0);
  502. X    }
  503. X    if(frameend == ZCRCW)
  504. X    {
  505. X        xsendline(XON);  
  506. X        flushline();
  507. X    }
  508. X
  509. X}
  510. X
  511. X/* Send a byte as two hex digits */
  512. Xvoid
  513. Xzputhex(c)
  514. Xregister int c;
  515. X{
  516. X    static char digits[]    = "0123456789abcdef";
  517. X
  518. X    sendline(digits[(c&0xF0)>>4]);
  519. X    sendline(digits[(c)&0xF]);
  520. X}
  521. X
  522. Xvoid
  523. Xzshhdr(type,hdr)
  524. Xint type;
  525. Xregister unsigned char *hdr;
  526. X{
  527. X    register int n;
  528. X    register unsigned short crc;
  529. X
  530. X
  531. X    sprintf(s128,
  532. X#ifdef SHOW_ZHDR_TYPE
  533. X        "HEX %s %ld",
  534. X#else
  535. X        "hdr %s %ld",
  536. X#endif
  537. X        frametypes[type+FTOFFSET],rclhdr(hdr));
  538. X    report_last_txhdr(s128,0);
  539. X    report_tx_ind(1);
  540. X    sendline(ZPAD); 
  541. X    sendline(ZPAD); 
  542. X    sendline(ZDLE); 
  543. X    sendline(ZHEX);
  544. X    zputhex(type);
  545. X    Crc32t = 0;
  546. X
  547. X    crc = updcrc(type,0);
  548. X    for(n=4; --n >= 0; ++hdr)
  549. X    {
  550. X        zputhex(*hdr); 
  551. X        crc = updcrc(*hdr,crc);
  552. X/*        crc = updcrc((0377 & *hdr),crc);  original - wht */
  553. X    }
  554. X    crc = updcrc(0,updcrc(0,crc));
  555. X    zputhex(crc>>8); 
  556. X    zputhex(crc);
  557. X
  558. X    /* Make it printable on remote machine */
  559. X    sendline(015); 
  560. X    sendline(012);
  561. X    /*
  562. X     * Uncork the remote in case a fake XOFF has stopped data flow
  563. X     */
  564. X    if(type != ZFIN && type != ZACK)
  565. X        sendline(021);
  566. X    flushline();
  567. X    report_tx_ind(0);
  568. X}
  569. X
  570. X/*
  571. X * Receive array buf of max length with ending ZDLE sequence
  572. X *  and CRC.  Returns the ending character or error code.
  573. X *  NB: On errors may store length+1 bytes!
  574. X */
  575. Xint
  576. Xzrdat32(buf,length)
  577. Xregister char *buf;
  578. Xint length;
  579. X{
  580. X    register int c;
  581. X    register UNSL long crc;
  582. X    register char *end;
  583. X    register int d;
  584. X
  585. X    report_rx_ind(1);
  586. X    crc = 0xFFFFFFFFL;  
  587. X    Rxcount = 0;  
  588. X    end = buf + length;
  589. X    while(buf <= end)
  590. X    {
  591. X        if((c = zdlread()) & ~0377)
  592. X        {
  593. Xcrcfoo:
  594. X            switch(c)
  595. X            {
  596. X            case GOTCRCE:
  597. X            case GOTCRCG:
  598. X            case GOTCRCQ:
  599. X            case GOTCRCW:
  600. X                d = c;  
  601. X                c &= 0377;
  602. X                crc = UPDC32(c,crc);
  603. X                if((c = zdlread()) & ~0377)
  604. X                    goto crcfoo;
  605. X                crc = UPDC32(c,crc);
  606. X                if((c = zdlread()) & ~0377)
  607. X                    goto crcfoo;
  608. X                crc = UPDC32(c,crc);
  609. X                if((c = zdlread()) & ~0377)
  610. X                    goto crcfoo;
  611. X                crc = UPDC32(c,crc);
  612. X                if((c = zdlread()) & ~0377)
  613. X                    goto crcfoo;
  614. X                crc = UPDC32(c,crc);
  615. X                if(crc != 0xDEBB20E3)
  616. X                {
  617. X                    report_str(badcrc,0);
  618. X                    report_rx_ind(0);
  619. X                    return(ERROR);
  620. X                }
  621. X                Rxcount = length - (end - buf);
  622. X                report_rxblklen(Rxcount);
  623. X                sprintf(s128,
  624. X#ifdef SHOW_ZHDR_TYPE
  625. X                    "D32 %s %d",
  626. X#else
  627. X                    "data %s %d",
  628. X#endif
  629. X                    Zendnames[d-GOTCRCE&3],Rxcount);
  630. X                report_last_rxhdr(s128,0);
  631. X                report_rx_ind(0);
  632. X                return(d);
  633. X            case GOTCAN:
  634. X                report_str("Sender Canceled",1);
  635. X                report_rx_ind(0);
  636. X                return(ZCAN);
  637. X            case TIMEOUT:
  638. X                report_str("TIMEOUT",0);
  639. X                report_rx_ind(0);
  640. X                return(c);
  641. X            default:
  642. X                report_str("Bad data subpacket",0);
  643. X                report_rx_ind(0);
  644. X                return(c);
  645. X            }
  646. X        }
  647. X        *buf++ = c;
  648. X        crc = UPDC32(c,crc);
  649. X    }
  650. X    report_str("Data subpacket too long",0);
  651. X    report_rx_ind(0);
  652. X    return(ERROR);
  653. X}
  654. X
  655. Xint
  656. Xzrdata(buf,length)
  657. Xregister char *buf;
  658. Xint length;
  659. X{
  660. X    register int c;
  661. X    register unsigned short crc;
  662. X    register char *end;
  663. X    register int d;
  664. X
  665. X
  666. X    if(Rxframeind == ZBIN32)
  667. X        return(zrdat32(buf,length));
  668. X
  669. X    report_rx_ind(1);
  670. X    crc = Rxcount = 0;  
  671. X    end = buf + length;
  672. X    while(buf <= end)
  673. X    {
  674. X        if((c = zdlread()) & ~0377)
  675. X        {
  676. Xcrcfoo:
  677. X            switch(c)
  678. X            {
  679. X            case GOTCRCE:
  680. X            case GOTCRCG:
  681. X            case GOTCRCQ:
  682. X            case GOTCRCW:
  683. X                crc = updcrc(((d=c)&0377),crc);
  684. X                if((c = zdlread()) & ~0377)
  685. X                    goto crcfoo;
  686. X                crc = updcrc(c,crc);
  687. X                if((c = zdlread()) & ~0377)
  688. X                    goto crcfoo;
  689. X                crc = updcrc(c,crc);
  690. X                if(crc & 0xFFFF)
  691. X                {
  692. X                    report_str(badcrc,0);
  693. X                    report_rx_ind(0);
  694. X                    return(ERROR);
  695. X                }
  696. X                Rxcount = length - (end - buf);
  697. X                report_rxblklen(Rxcount);
  698. X                sprintf(s128,
  699. X#ifdef SHOW_ZHDR_TYPE
  700. X                    "D16 %s %d",
  701. X#else
  702. X                    "data %s %d",
  703. X#endif
  704. X                    Zendnames[d-GOTCRCE&3],Rxcount);
  705. X                report_last_rxhdr(s128,0);
  706. X                report_rx_ind(0);
  707. X                return(d);
  708. X            case GOTCAN:
  709. X                report_str("Sender Cancelled",1);
  710. X                report_rx_ind(0);
  711. X                return(ZCAN);
  712. X            case TIMEOUT:
  713. X                report_str("TIMEOUT",0);
  714. X                report_rx_ind(0);
  715. X                return(c);
  716. X            default:
  717. X                report_str("Bad data subpacket",0);
  718. X                report_rx_ind(0);
  719. X                return(c);
  720. X            }
  721. X        }
  722. X        *buf++ = c;
  723. X        crc = updcrc(c,crc);
  724. X    }
  725. X    report_str("Data subpacket too long",0);
  726. X    report_rx_ind(0);
  727. X    return(ERROR);
  728. X}
  729. X
  730. X
  731. X/*
  732. X * Read a ZMODEM header to hdr,either binary or hex.
  733. X *  eflag controls local display of non zmodem characters:
  734. X *    0:  no display
  735. X *    1:  display printing characters only
  736. X *    2:  display all non ZMODEM characters
  737. X *  On success,set Zmodem to 1,set Rxpos and return type of header.
  738. X *   Otherwise return negative on error.
  739. X *   Return ERROR instantly if ZCRCW sequence,for fast error recovery.
  740. X */
  741. Xint
  742. Xzgethdr(hdr,eflag)
  743. Xchar *hdr;
  744. Xint eflag;
  745. X{
  746. Xregister int c,n,cancount;
  747. X#ifdef SHOW_ZHDR_TYPE
  748. Xchar *hdrtyp = "?";
  749. X#endif
  750. X
  751. X    report_rx_ind(1);
  752. X    n = Zrwindow + Baudrate;    /* Max bytes before start of frame */
  753. X    Rxframeind = Rxtype = 0;
  754. X
  755. Xstartover:
  756. X    cancount = 5;
  757. Xagain:
  758. X    /* Return immediate ERROR if ZCRCW sequence seen */
  759. X    switch(c = readline(Rxtimeout))
  760. X    {
  761. X    case RCDO:
  762. X    case TIMEOUT:
  763. X        goto fifi;
  764. X    case CAN:
  765. Xgotcan:
  766. X        if(--cancount <= 0)
  767. X        {
  768. X            c = ZCAN; 
  769. X            goto fifi;
  770. X        }
  771. X        switch(c = readline(1))
  772. X        {
  773. X        case TIMEOUT:
  774. X            goto again;
  775. X        case ZCRCW:
  776. X            c = ERROR;
  777. X            /* **** FALL THRU TO **** */
  778. X        case RCDO:
  779. X            goto fifi;
  780. X        default:
  781. X            break;
  782. X        case CAN:
  783. X            if(--cancount <= 0)
  784. X            {
  785. X                c = ZCAN; 
  786. X                goto fifi;
  787. X            }
  788. X            goto again;
  789. X        }
  790. X        /* **** FALL THRU TO **** */
  791. X    default:
  792. Xagn2:
  793. X        if( --n == 0)
  794. X        {
  795. X            report_str("Garbage count exceeded",1);
  796. X            report_last_rxhdr("Noise",0);
  797. X            report_rx_ind(0);
  798. X            return(ERROR);
  799. X        }
  800. X        goto startover;
  801. X    case ZPAD|0200:        /* This is what we want. */
  802. X    case ZPAD:        /* This is what we want. */
  803. X        evenp = c & 0200;
  804. X        break;
  805. X    }
  806. X    cancount = 5;
  807. Xsplat:
  808. X    switch(c = noxrd7())
  809. X    {
  810. X    case ZPAD:
  811. X        goto splat;
  812. X    case RCDO:
  813. X    case TIMEOUT:
  814. X        goto fifi;
  815. X    default:
  816. X        goto agn2;
  817. X    case ZDLE:        /* This is what we want. */
  818. X        break;
  819. X    }
  820. X
  821. X    switch(c = noxrd7())
  822. X    {
  823. X    case RCDO:
  824. X    case TIMEOUT:
  825. X        goto fifi;
  826. X    case ZBIN:
  827. X        Rxframeind = ZBIN;  
  828. X        Crc32 = FALSE;
  829. X        c =  zrbhdr(hdr);
  830. X        break;
  831. X    case ZBIN32:
  832. X        Crc32 = Rxframeind = ZBIN32;
  833. X        c =  zrbhdr32(hdr);
  834. X        break;
  835. X    case ZHEX:
  836. X        Rxframeind = ZHEX;  
  837. X        Crc32 = FALSE;
  838. X        c =  zrhhdr(hdr);
  839. X        break;
  840. X    case CAN:
  841. X        goto gotcan;
  842. X    default:
  843. X        goto agn2;
  844. X    }
  845. X    Rxpos = hdr[ZP3] & 0377;
  846. X    Rxpos = (Rxpos<<8) + (hdr[ZP2] & 0377);
  847. X    Rxpos = (Rxpos<<8) + (hdr[ZP1] & 0377);
  848. X    Rxpos = (Rxpos<<8) + (hdr[ZP0] & 0377);
  849. Xfifi:
  850. X    switch(c)
  851. X    {
  852. X    case GOTCAN:
  853. X        c = ZCAN;
  854. X        /* **** FALL THRU TO **** */
  855. X    case ZNAK:
  856. X    case ZCAN:
  857. X    case ERROR:
  858. X    case TIMEOUT:
  859. X    case RCDO:
  860. X        sprintf(s128,"Got %s",frametypes[c+FTOFFSET]);
  861. X        report_str(s128,0);
  862. X        /* **** FALL THRU TO **** */
  863. X    default:
  864. X#ifdef SHOW_ZHDR_TYPE
  865. X        switch(Rxframeind)
  866. X        {
  867. X        case ZBIN:        hdrtyp = "B16"; break;
  868. X        case ZBIN32:    hdrtyp = "B32"; break;
  869. X        case ZHEX:        hdrtyp = "HEX"; break;
  870. X        }
  871. X        if(c >= -3 && c <= FRTYPES)
  872. X            sprintf(s128,"%s %s %ld",hdrtyp,frametypes[c+FTOFFSET],Rxpos);
  873. X        else
  874. X            sprintf(s128,"%s 0x%02x? %ld",hdrtyp,c,Rxpos);
  875. X#else
  876. X        if(c >= -3 && c <= FRTYPES)
  877. X            sprintf(s128,"hdr %s %ld",frametypes[c+FTOFFSET],Rxpos);
  878. X        else
  879. X            sprintf(s128,"hdr 0x%02x? %ld",c,Rxpos);
  880. X#endif
  881. X        report_last_rxhdr(s128,0);
  882. X    }
  883. X    report_rx_ind(0);
  884. X    return(c);
  885. X}
  886. X
  887. X/* Receive a binary style header (type and position) */
  888. Xint
  889. Xzrbhdr(hdr)
  890. Xregister char *hdr;
  891. X{
  892. X    register int c,n;
  893. X    register unsigned short crc;
  894. X
  895. X    if((c = zdlread()) & ~0377)
  896. X        return(c);
  897. X    Rxtype = c;
  898. X    crc = updcrc(c,0);
  899. X
  900. X    for(n=4; --n >= 0; ++hdr)
  901. X    {
  902. X        if((c = zdlread()) & ~0377)
  903. X            return(c);
  904. X        crc = updcrc(c,crc);
  905. X        *hdr = c;
  906. X    }
  907. X    if((c = zdlread()) & ~0377)
  908. X        return(c);
  909. X    crc = updcrc(c,crc);
  910. X    if((c = zdlread()) & ~0377)
  911. X        return(c);
  912. X    crc = updcrc(c,crc);
  913. X    if(crc & 0xFFFF)
  914. X    {
  915. X        if(evenp)
  916. X            report_str(masked,1);
  917. X        report_str(badcrc,0);
  918. X        return(ERROR);
  919. X    }
  920. X#if defined(ZMODEM)
  921. X    Protocol = ZMODEM;
  922. X#endif
  923. X    Zmodem = 1;
  924. X    return(Rxtype);
  925. X}
  926. X
  927. X/* Receive a binary style header (type and position) with 32 bit FCS */
  928. Xint
  929. Xzrbhdr32(hdr)
  930. Xregister char *hdr;
  931. X{
  932. X    register int c,n;
  933. X    register UNSL long crc;
  934. X
  935. X    if((c = zdlread()) & ~0377)
  936. X        return(c);
  937. X    Rxtype = c;
  938. X    crc = 0xFFFFFFFFL; 
  939. X    crc = UPDC32(c,crc);
  940. X
  941. X    for(n=4; --n >= 0; ++hdr)
  942. X    {
  943. X        if((c = zdlread()) & ~0377)
  944. X            return(c);
  945. X        crc = UPDC32(c,crc);
  946. X        *hdr = c;
  947. X    }
  948. X    for(n=4; --n >= 0;)
  949. X    {
  950. X        if((c = zdlread()) & ~0377)
  951. X            return(c);
  952. X        crc = UPDC32(c,crc);
  953. X    }
  954. X    if(crc != 0xDEBB20E3)
  955. X    {
  956. X        if(evenp)
  957. X            report_str(masked,1);
  958. X        report_str(badcrc,0);
  959. X        return(ERROR);
  960. X    }
  961. X#if defined(ZMODEM)
  962. X    Protocol = ZMODEM;
  963. X#endif
  964. X    Zmodem = 1;
  965. X    return(Rxtype);
  966. X}
  967. X
  968. X
  969. X/* Receive a hex style header (type and position) */
  970. Xint
  971. Xzrhhdr(hdr)
  972. Xchar *hdr;
  973. X{
  974. X    register int c;
  975. X    register unsigned short crc;
  976. X    register int n;
  977. X
  978. X    if((c = zgethex()) < 0)
  979. X        return(c);
  980. X    Rxtype = c;
  981. X    crc = updcrc(c,0);
  982. X
  983. X    for(n=4; --n >= 0; ++hdr)
  984. X    {
  985. X        if((c = zgethex()) < 0)
  986. X            return(c);
  987. X        crc = updcrc(c,crc);
  988. X        *hdr = c;
  989. X    }
  990. X    if((c = zgethex()) < 0)
  991. X        return(c);
  992. X    crc = updcrc(c,crc);
  993. X    if((c = zgethex()) < 0)
  994. X        return(c);
  995. X    crc = updcrc(c,crc);
  996. X    if(crc & 0xFFFF)
  997. X    {
  998. X        report_str(badcrc,0); 
  999. X        return(ERROR);
  1000. X    }
  1001. X    if(readline(1) == '\r')    /* Throw away possible cr/lf */
  1002. X        readline(1);
  1003. X#if defined(ZMODEM)
  1004. X    Protocol = ZMODEM;
  1005. X#endif
  1006. X    Zmodem = 1; 
  1007. X    return(Rxtype);
  1008. X}
  1009. X
  1010. X/* Decode two lower case hex digits into an 8 bit byte value */
  1011. Xint
  1012. Xzgeth1()
  1013. X{
  1014. X    register int c,n;
  1015. X
  1016. X    if((c = noxrd7()) < 0)
  1017. X        return(c);
  1018. X    n = c - '0';
  1019. X    if(n > 9)
  1020. X        n -= ('a' - ':');
  1021. X    if(n & ~0xF)
  1022. X        return(ERROR);
  1023. X    if((c = noxrd7()) < 0)
  1024. X        return(c);
  1025. X    c -= '0';
  1026. X    if(c > 9)
  1027. X        c -= ('a' - ':');
  1028. X    if(c & ~0xF)
  1029. X        return(ERROR);
  1030. X    c += (n<<4);
  1031. X    return(c);
  1032. X}
  1033. X
  1034. Xint
  1035. Xzgethex()
  1036. X{
  1037. X    return(zgeth1());
  1038. X}
  1039. X
  1040. X
  1041. X/*
  1042. X * Read a byte,checking for ZMODEM escape encoding
  1043. X *  including CAN*5 which represents a quick abort
  1044. X */
  1045. Xint
  1046. Xzdlread()
  1047. X{
  1048. X    register int c;
  1049. X
  1050. Xagain:
  1051. X    /* Quick check for non control characters */
  1052. X    if((c = readline(Rxtimeout)) & 0140)
  1053. X        return(c);
  1054. X    switch(c)
  1055. X    {
  1056. X    case ZDLE:
  1057. X        break;
  1058. X    case 023:
  1059. X    case 0223:
  1060. X    case 021:
  1061. X    case 0221:
  1062. X        goto again;
  1063. X    default:
  1064. X        if(Zctlesc && !(c & 0140))
  1065. X        {
  1066. X            goto again;
  1067. X        }
  1068. X        return(c);
  1069. X    }
  1070. Xagain2:
  1071. X    if((c = readline(Rxtimeout)) < 0)
  1072. X        return(c);
  1073. X    if(c == CAN && (c = readline(Rxtimeout)) < 0)
  1074. X        return(c);
  1075. X    if(c == CAN && (c = readline(Rxtimeout)) < 0)
  1076. X        return(c);
  1077. X    if(c == CAN && (c = readline(Rxtimeout)) < 0)
  1078. X        return(c);
  1079. X    switch(c)
  1080. X    {
  1081. X    case CAN:
  1082. X        return(GOTCAN);
  1083. X    case ZCRCE:
  1084. X    case ZCRCG:
  1085. X    case ZCRCQ:
  1086. X    case ZCRCW:
  1087. X        return(c | GOTOR);
  1088. X    case ZRUB0:
  1089. X        return(0177);
  1090. X    case ZRUB1:
  1091. X        return(0377);
  1092. X    case 023:
  1093. X    case 0223:
  1094. X    case 021:
  1095. X    case 0221:
  1096. X        goto again2;
  1097. X    default:
  1098. X        if(Zctlesc && ! (c & 0140))
  1099. X        {
  1100. X            goto again2;
  1101. X        }
  1102. X        if((c & 0140) ==  0100)
  1103. X            return(c ^ 0100);
  1104. X        break;
  1105. X    }
  1106. X    sprintf(s128,"Bad escape sequence %x",c);
  1107. X    report_str(s128,0);
  1108. X    return(ERROR);
  1109. X}
  1110. X
  1111. X/*
  1112. X * Read a character from the modem line with timeout.
  1113. X *  Eat parity,XON and XOFF characters.
  1114. X */
  1115. Xint
  1116. Xnoxrd7()
  1117. X{
  1118. X    register int c;
  1119. X
  1120. X    for(;;)
  1121. X    {
  1122. X        if((c = readline(Rxtimeout)) < 0)
  1123. X            return(c);
  1124. X        switch(c &= 0177)
  1125. X        {
  1126. X        case XON:
  1127. X        case XOFF:
  1128. X            continue;
  1129. X        default:
  1130. X            if(Zctlesc && !(c & 0140))
  1131. X                continue;
  1132. X        case '\r':
  1133. X        case '\n':
  1134. X        case ZDLE:
  1135. X            return(c);
  1136. X        }
  1137. X    }
  1138. X}
  1139. X
  1140. X/* Store long integer pos in Txhdr */
  1141. Xvoid
  1142. Xstohdr(pos)
  1143. Xlong pos;
  1144. X{
  1145. X    Txhdr[ZP0] = pos;
  1146. X    Txhdr[ZP1] = pos>>8;
  1147. X    Txhdr[ZP2] = pos>>16;
  1148. X    Txhdr[ZP3] = pos>>24;
  1149. X}
  1150. X
  1151. X/* Recover a long integer from a header */
  1152. Xlong
  1153. Xrclhdr(hdr)
  1154. Xregister char *hdr;
  1155. X{
  1156. X    register long l;
  1157. X
  1158. X    l = (hdr[ZP3] & 0377);
  1159. X    l = (l << 8) | (hdr[ZP2] & 0377);
  1160. X    l = (l << 8) | (hdr[ZP1] & 0377);
  1161. X    l = (l << 8) | (hdr[ZP0] & 0377);
  1162. X    return(l);
  1163. X}
  1164. X
  1165. X/* end of zmodem.c */
  1166. X/* vi: set tabstop=4 shiftwidth=4: */
  1167. SHAR_EOF
  1168. chmod 0644 z/zmodem.c ||
  1169. echo 'restore of z/zmodem.c failed'
  1170. Wc_c="`wc -c < 'z/zmodem.c'`"
  1171. test 17354 -eq "$Wc_c" ||
  1172.     echo 'z/zmodem.c: original size 17354, current size' "$Wc_c"
  1173. rm -f _shar_wnt_.tmp
  1174. fi
  1175. # ============= z/zmodem.h ==============
  1176. if test -f 'z/zmodem.h' -a X"$1" != X"-c"; then
  1177.     echo 'x - skipping z/zmodem.h (File already exists)'
  1178.     rm -f _shar_wnt_.tmp
  1179. else
  1180. > _shar_wnt_.tmp
  1181. echo 'x - extracting z/zmodem.h (Text)'
  1182. sed 's/^X//' << 'SHAR_EOF' > 'z/zmodem.h' &&
  1183. X/*+-------------------------------------------------------------------------
  1184. X    zmodem.h -- common include filefor ecurz/ecusz
  1185. X--------------------------------------------------------------------------*/
  1186. X/*+:EDITS:*/
  1187. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  1188. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  1189. X/*:08-28-1991-14:08-wht@n4hgf2-SVR4 cleanup by aega84!lh */
  1190. X/*:08-21-1991-06:23-wht@n4hgf-sun porting */
  1191. X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
  1192. X/*:08-14-1990-20:41-wht@n4hgf-ecu3.00-flush old edit history */
  1193. X
  1194. X#ifdef __STDC__
  1195. X#define VOLATILE volatile
  1196. X#else
  1197. X#define VOLATILE
  1198. X#endif
  1199. X
  1200. X#include "../ecu_types.h"
  1201. X#include "../ecu_stat.h"
  1202. X#if defined(sun)
  1203. X#include <termio.h>
  1204. X#define termio termios
  1205. X#undef TCGETA
  1206. X#undef TCSETA
  1207. X#undef TCSETAW
  1208. X#define TCGETA    TCGETS
  1209. X#define TCSETA    TCSETS
  1210. X#define TCSETAW    TCSETSW
  1211. X#undef ECHO
  1212. X#undef NL0
  1213. X#undef NL1
  1214. X#undef TAB0
  1215. X#undef TAB1
  1216. X#undef TAB2
  1217. X#undef XTABS
  1218. X#undef CR0
  1219. X#undef CR1
  1220. X#undef CR2
  1221. X#undef CR3
  1222. X#undef FF0
  1223. X#undef FF1
  1224. X#undef BS0
  1225. X#undef BS1
  1226. X#undef TOSTOP
  1227. X#undef FLUSHO
  1228. X#undef PENDIN
  1229. X#undef NOFLSH
  1230. X#else
  1231. X#include <termio.h>
  1232. X#endif /* sun */
  1233. X#include <sys/ioctl.h>
  1234. X#include <string.h>
  1235. X#define MODE2OK
  1236. X
  1237. X#if defined(M_UNIX)
  1238. X#undef M_XENIX
  1239. X#endif
  1240. X
  1241. X#if !defined(READCHECK)
  1242. X#if defined(FIONREAD)
  1243. X#define READCHECK
  1244. X#endif
  1245. X#if defined(SYSV)
  1246. X#define READCHECK
  1247. X#endif
  1248. X#endif
  1249. X
  1250. X#define ACK 6
  1251. X#define CAN ('X'&037)
  1252. X#define CPMEOF 032
  1253. X#define ENQ 005
  1254. X#define EOT 4
  1255. X#define ERROR (-1)
  1256. X#define ERRORMAX 5
  1257. X#define FALSE 0
  1258. X#define NAK 025
  1259. X#define OK 0
  1260. X#define PATHLEN 257    /* ready for 4.2 bsd ? */
  1261. X#define RCDO (-3)
  1262. X#define SOH 1
  1263. X#define STX 2
  1264. X#define TIMEOUT (-2)
  1265. X#define TRUE 1
  1266. X#define UNIXFILE 0xF000    /* The S_IFMT file mask bit for stat */
  1267. X#define WANTCRC 0103    /* send C not NAK to get crc not checksum */
  1268. X
  1269. X#define WANTG 0107    /* Send G not NAK to get nonstop batch xmsn */
  1270. X#define WCEOT (-10)
  1271. X#define XOFF ('s'&037)
  1272. X#define XON ('q'&037)
  1273. X
  1274. X/*
  1275. X * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. 
  1276. X *  NOTE: First argument must be in range 0 to 255.
  1277. X *        Second argument is referenced twice.
  1278. X * 
  1279. X * Programmers may incorporate any or all code into their programs, 
  1280. X * giving proper credit within the source. Publication of the 
  1281. X * source routines is permitted so long as proper credit is given 
  1282. X * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg, 
  1283. X * Omen Technology.
  1284. X */
  1285. X
  1286. X#define updcrc(cp, crc) ( crctab[(((unsigned)crc >> 8) & 255)] ^ (crc << 8) ^ (cp))
  1287. X#define UPDC32(b, c) (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF))
  1288. X
  1289. X
  1290. X#define ZPAD '*'    /* 052 Padding character begins frames */
  1291. X#define ZDLE 030    /* Ctrl-X Zmodem escape - `ala BISYNC DLE */
  1292. X#define ZDLEE (ZDLE^0100)    /* Escaped ZDLE as transmitted */
  1293. X#define ZBIN 'A'    /* Binary frame indicator */
  1294. X#define ZHEX 'B'    /* HEX frame indicator */
  1295. X#define ZBIN32 'C'    /* Binary frame with 32 bit FCS */
  1296. X
  1297. X/* Frame types (see array "frametypes" in zm.c) */
  1298. X#define ZRQINIT    0    /* Request receive init */
  1299. X#define ZRINIT    1    /* Receive init */
  1300. X#define ZSINIT 2    /* Send init sequence (optional) */
  1301. X#define ZACK 3        /* ACK to above */
  1302. X#define ZFILE 4        /* File name from sender */
  1303. X#define ZSKIP 5        /* To sender: skip this file */
  1304. X#define ZNAK 6        /* Last packet was garbled */
  1305. X#define ZABORT 7    /* Abort batch transfers */
  1306. X#define ZFIN 8        /* Finish session */
  1307. X#define ZRPOS 9        /* Resume data trans at this position */
  1308. X#define ZDATA 10    /* Data packet(s) follow */
  1309. X#define ZEOF 11        /* End of file */
  1310. X#define ZFERR 12    /* Fatal Read or Write error Detected */
  1311. X#define ZCRC 13        /* Request for file CRC and response */
  1312. X#define ZCHALLENGE 14    /* Receiver's Challenge */
  1313. X#define ZCOMPL 15    /* Request is complete */
  1314. X#define ZCAN 16        /* Other end canned session with CAN*5 */
  1315. X#define ZFREECNT 17    /* Request for free bytes on filesystem */
  1316. X#define ZCOMMAND 18    /* Command from sending program */
  1317. X#define ZSTDERR 19    /* Output to standard error, data follows */
  1318. X
  1319. X/* ZDLE sequences */
  1320. X#define ZCRCE 'h'    /* CRC next, frame ends, header packet follows */
  1321. X#define ZCRCG 'i'    /* CRC next, frame continues nonstop */
  1322. X#define ZCRCQ 'j'    /* CRC next, frame continues, ZACK expected */
  1323. X#define ZCRCW 'k'    /* CRC next, ZACK expected, end of frame */
  1324. X#define ZRUB0 'l'    /* Translate to rubout 0177 */
  1325. X#define ZRUB1 'm'    /* Translate to rubout 0377 */
  1326. X
  1327. X/* zdlread return values (internal) */
  1328. X/* -1 is general error, -2 is timeout */
  1329. X#define GOTOR 0400
  1330. X#define GOTCRCE (ZCRCE|GOTOR)    /* ZDLE-ZCRCE received */
  1331. X#define GOTCRCG (ZCRCG|GOTOR)    /* ZDLE-ZCRCG received */
  1332. X#define GOTCRCQ (ZCRCQ|GOTOR)    /* ZDLE-ZCRCQ received */
  1333. X#define GOTCRCW (ZCRCW|GOTOR)    /* ZDLE-ZCRCW received */
  1334. X#define GOTCAN    (GOTOR|030)    /* CAN*5 seen */
  1335. X
  1336. X/* Byte positions within header array */
  1337. X#define ZF0    3    /* First flags byte */
  1338. X#define ZF1    2
  1339. X#define ZF2    1
  1340. X#define ZF3    0
  1341. X#define ZP0    0    /* Low order 8 bits of position */
  1342. X#define ZP1    1
  1343. X#define ZP2    2
  1344. X#define ZP3    3    /* High order 8 bits of file position */
  1345. X
  1346. X/* Bit Masks for ZRINIT flags byte ZF0 */
  1347. X#define CANFDX    01    /* Rx can send and receive true FDX */
  1348. X#define CANOVIO    02    /* Rx can receive data during disk I/O */
  1349. X#define CANBRK    04    /* Rx can send a break signal */
  1350. X#define CANCRY    010    /* Receiver can decrypt */
  1351. X#define CANLZW    020    /* Receiver can uncompress */
  1352. X#define CANFC32    040    /* Receiver can use 32 bit Frame Check */
  1353. X#define ESCCTL 0100    /* Receiver expects ctl chars to be escaped */
  1354. X#define ESC8   0200    /* Receiver expects 8th bit to be escaped */
  1355. X
  1356. X/* Parameters for ZSINIT frame */
  1357. X#define ZATTNLEN 32    /* Max length of attention string */
  1358. X/* Bit Masks for ZSINIT flags byte ZF0 */
  1359. X#define TESCCTL 0100    /* Transmitter expects ctl chars to be escaped */
  1360. X#define TESC8   0200    /* Transmitter expects 8th bit to be escaped */
  1361. X
  1362. X/* Parameters for ZFILE frame */
  1363. X/* Conversion options one of these in ZF0 */
  1364. X#define ZCBIN    1    /* Binary transfer - inhibit conversion */
  1365. X#define ZCNL    2    /* Convert NL to local end of line convention */
  1366. X#define ZCRESUM    3    /* Resume interrupted file transfer */
  1367. X/* Management include options, one of these ored in ZF1 */
  1368. X#define ZMSKNOLOC    0200    /* Skip file if not present at rx */
  1369. X/* Management options, one of these ored in ZF1 */
  1370. X#define ZMMASK    037    /* Mask for the choices below */
  1371. X#define ZMNEWL    1    /* Transfer if source newer or longer */
  1372. X#define ZMCRC    2    /* Transfer if different file CRC or length */
  1373. X#define ZMAPND    3    /* Append contents to existing file (if any) */
  1374. X#define ZMCLOB    4    /* Replace existing file */
  1375. X#define ZMNEW    5    /* Transfer if source newer */
  1376. X    /* Number 5 is alive ... */
  1377. X#define ZMDIFF    6    /* Transfer if dates or lengths different */
  1378. X#define ZMPROT    7    /* Protect destination file */
  1379. X/* Transport options, one of these in ZF2 */
  1380. X#define ZTLZW    1    /* Lempel-Ziv compression */
  1381. X#define ZTCRYPT    2    /* Encryption */
  1382. X#define ZTRLE    3    /* Run Length encoding */
  1383. X/* Extended options for ZF3, bit encoded */
  1384. X#define ZXSPARS    64    /* Encoding for sparse file operations */
  1385. X
  1386. X/* Parameters for ZCOMMAND frame ZF0 (otherwise 0) */
  1387. X#define ZCACK1    1    /* Acknowledge, then do command */
  1388. X
  1389. X/* FTOFFSET is offset for frametypes array in ecuzm.c */
  1390. X#define FTOFFSET 3
  1391. X
  1392. Xlong rclhdr();
  1393. X
  1394. X#ifdef USE_PROTOS
  1395. X# include "protos.h"
  1396. X#endif
  1397. X
  1398. X/* vi: set tabstop=4 shiftwidth=4: */
  1399. SHAR_EOF
  1400. chmod 0644 z/zmodem.h ||
  1401. echo 'restore of z/zmodem.h failed'
  1402. Wc_c="`wc -c < 'z/zmodem.h'`"
  1403. test 7102 -eq "$Wc_c" ||
  1404.     echo 'z/zmodem.h: original size 7102, current size' "$Wc_c"
  1405. rm -f _shar_wnt_.tmp
  1406. fi
  1407. # ============= sea/ecusea.c ==============
  1408. if test -f 'sea/ecusea.c' -a X"$1" != X"-c"; then
  1409.     echo 'x - skipping sea/ecusea.c (File already exists)'
  1410.     rm -f _shar_wnt_.tmp
  1411. else
  1412. > _shar_wnt_.tmp
  1413. echo 'x - extracting sea/ecusea.c (Text)'
  1414. sed 's/^X//' << 'SHAR_EOF' > 'sea/ecusea.c' &&
  1415. Xchar *revision = "3.20";    /* cannot be longer than 7 chars (blk0.sender) */
  1416. X
  1417. X/* #define TABLE_CRC16 */
  1418. X#ifdef M_XENIX
  1419. X#define NO_SELECT
  1420. X#endif
  1421. X
  1422. X/*+-------------------------------------------------------------------------
  1423. X    ecusea.c - SEAlink - Sliding window file transfer protocol
  1424. X
  1425. X  Defined functions:
  1426. X    Nap(msec)
  1427. X    arg_token(parsestr,termchars)
  1428. X    cancel_transaction(sig)
  1429. X    crc_update(c,crc)
  1430. X    fname_split(cmd,arg,arg_max_quan,narg_rtn)
  1431. X    fname_too_long(fname)
  1432. X    fname_truncated()
  1433. X    getspeed(code)
  1434. X    lgetc_timeout(tenths)
  1435. X    lgetc_timeout_SIGALRM()
  1436. X    main(argc,argv,envp)
  1437. X    rdchk(fd)
  1438. X    receive_block(buf)
  1439. X    receive_file()
  1440. X    send_comm_block(blk,blknum)
  1441. X    send_file(name)
  1442. X    send_file_block(fp,blknum)
  1443. X    set_sf_state(place,new_state)
  1444. X    set_utime_1980(filename,secs_since_1980)
  1445. X    sf_state_text(state)
  1446. X    wait_for_rcvr_response()
  1447. X    xmit_ack(blknum)
  1448. X    xmit_cancel()
  1449. X    xmit_nak(blknum)
  1450. X
  1451. Xecu adaptation by W. Tucker
  1452. Xmodelled after MSDOS sealink.c, which carried the following proviso:
  1453. X
  1454. X              MS-DOS Version 1.20, created on 08/05/87
  1455. X              at 17:51:40 (C) COPYRIGHT 1986,87 by
  1456. X              System Enhancement Associates; ALL RIGHTS
  1457. X              RESERVED By: Thom Henderson
  1458. X
  1459. X              You are granted a license to use this
  1460. X              code in your programs, and to adapt it to
  1461. X              your particular situation and needs,
  1462. X              subject only to the following conditions:
  1463. X              1) You must refer to it as the SEAlink
  1464. X              protocol, and you must give credit to
  1465. X              System Enhancement Associates.  2) If you
  1466. X              modify it in such a way that your version
  1467. X              cannot converse with the original code as
  1468. X              supplied by us, then you should refer to
  1469. X              it as "SEAlink derived", or as a
  1470. X              "variation of SEAlink", or words to that
  1471. X              effect.  In short, we're not asking for
  1472. X              any money, but we'd like to get some
  1473. X              credit for our work.
  1474. X
  1475. X--------------------------------------------------------------------------*/
  1476. X/*+:EDITS:*/
  1477. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  1478. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  1479. X/*:08-16-1992-03:08-wht@n4hgf-head off another POSIX plot */
  1480. X/*:08-10-1992-04:01-wht@n4hgf-use init_Nap */
  1481. X/*:07-20-1992-13:30-wht@n4hgf-put hzmsec in AGAIN ?? */
  1482. X/*:07-17-1992-18:28-wht@n4hgf-remove Nap() and use common ../nap.o */
  1483. X/*:05-11-1992-16:43-wht@gyro-fix WORKING_SELECT nap once and for all */
  1484. X/*:05-08-1992-02:42-wht@n4hgf-select-based Nap was buggy */
  1485. X/*:09-01-1991-14:22-wht@n4hgf2-on sun, use termios */
  1486. X/*:08-30-1991-20:09-wht@n4hgf2-sun Nap was not returning a value */
  1487. X/*:08-30-1991-02:34-jdeitch@jadpc.cts.com-fix no hzmsec */
  1488. X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
  1489. X/*:03-18-1991-22:49-wht@n4hgf-ISC 2.2 has struct timeval in sys/time.h */
  1490. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  1491. X
  1492. X#include <stdio.h>
  1493. X#include <string.h>
  1494. X#include <ctype.h>
  1495. X#include <signal.h>
  1496. X#include <setjmp.h>
  1497. X#include <fcntl.h>
  1498. X#include <fcntl.h>
  1499. X#include <errno.h>
  1500. X#if defined(sun)
  1501. X#include <termios.h>
  1502. X#define termio termios
  1503. X#undef TCGETA
  1504. X#undef TCSETA
  1505. X#undef TCSETAW
  1506. X#define TCGETA    TCGETS
  1507. X#define TCSETA    TCSETS
  1508. X#define TCSETAW    TCSETSW
  1509. X#undef ECHO
  1510. X#undef NL0
  1511. X#undef NL1
  1512. X#undef TAB0
  1513. X#undef TAB1
  1514. X#undef TAB2
  1515. X#undef XTABS
  1516. X#undef CR0
  1517. X#undef CR1
  1518. X#undef CR2
  1519. X#undef CR3
  1520. X#undef FF0
  1521. X#undef FF1
  1522. X#undef BS0
  1523. X#undef BS1
  1524. X#undef TOSTOP
  1525. X#undef FLUSHO
  1526. X#undef PENDIN
  1527. X#undef NOFLSH
  1528. X#else
  1529. X#include <termio.h>
  1530. X#endif /* sun */
  1531. X#include <sys/param.h>
  1532. X#include <sys/ioctl.h>
  1533. X#include "../ecu_types.h"
  1534. X#include "../ecu_stat.h"
  1535. X#include <time.h>
  1536. X#include <memory.h>
  1537. X#if !defined(NO_SELECT)
  1538. X#if defined(M_SYSV) && !defined(SCO32v4)    /* SCO pre 3.2v4 */
  1539. X# include <sys/select.h>
  1540. X#else
  1541. X# include <sys/time.h>
  1542. X#endif
  1543. X#endif
  1544. X
  1545. X#ifdef USE_PROTOS
  1546. X# include "protos.h"
  1547. X#endif
  1548. X
  1549. Xextern int errno;
  1550. X
  1551. X/* Various system constants */
  1552. X#define WINDOW        6                    /* maximum size of window */
  1553. X#define TIMEOUT    0x0FFF
  1554. X#define OFFSET_1980    (time_t)315547200    /* time offset for 1970 <-> 1980 */
  1555. X
  1556. X/*
  1557. X * The section of code that is compiled when NAKEOT is defined is in the
  1558. X * original MS-DOS version 1.16 routine.  Its purpose is to send a NAK when
  1559. X * an EOT is received during receive_file(), apparently to confirm that this is
  1560. X * indeed the end of file.  However, in certain (apparently non - standard)
  1561. X * versions of the protocol, it is possible that the program will report an
  1562. X * error when in fact there isn't one.  Comment this out at your discretion.
  1563. X */
  1564. X#define NAKEOT
  1565. X
  1566. X/* SEAlink block zero data structure */
  1567. Xtypedef struct blk0
  1568. X{
  1569. X    long length;            /* length */
  1570. X    time_t secs_since_1980;    /* creation/last mod in secs since 1/1/80 */
  1571. X    char filename[17];        /* file name */
  1572. X    char sender[15];        /* sending program */
  1573. X    char send_no_acks;        /* true if rcvr need not ack */
  1574. X    char filler[87];        /* fill to 128 bytes */
  1575. X}    BLK0;
  1576. X
  1577. X/* protocol characters */
  1578. X#define SOH    0x01
  1579. X#define EOT    0x04
  1580. X#define ACK    0x06
  1581. X#define NAK    0x15
  1582. X#define CAN    0x18
  1583. X
  1584. X/*  send_file state (sf_state) values */
  1585. X#define SFS_GND        0    /* Ground state, ACK or NAK expected */
  1586. X#define SFS_ACK        1    /* ACK received */
  1587. X#define SFS_NAK        2    /* NAK received */
  1588. X#define SFS_ACKW    3    /* ACK, block# received */
  1589. X#define SFS_NAKW    4    /* NAK, block# received */
  1590. X#define SFS_RGND    5    /* Returning to ground state */
  1591. Xint sf_state;
  1592. X
  1593. Xint allow_slide = 1;    /* sliding windows allowed */
  1594. Xint crc_in_use;            /* check type, 1 = CRC, 0 = checksum */
  1595. Xchar *dfile = "/tmp/ecuSEA.log";
  1596. Xint error_count = 0;    /* total number of errors */
  1597. Xint iofd = 0;            /* file descriptor to use */
  1598. Xint no_ack_mode = 1;    /* true of ACKs not required */
  1599. Xint rf_done = 0;        /* receive file done */
  1600. Xint sf_ackw_count;        /* count of sliding ACKs seen */
  1601. Xint sf_ackblk;            /* number of last block ACKed */
  1602. Xint sf_blknum;            /* number of next block to send */
  1603. Xint sf_lastnum;            /* number of last block sent */
  1604. Xint sf_nakquan;            /* number of sequential NAKs */
  1605. Xint sf_slide;            /* true if sliding window */
  1606. Xint sigint = 0;            /* dummy for nap.c */
  1607. X
  1608. Xint sending_flag = -1;        /* send == 1, receive == 0, bad usage == -1 */
  1609. Xint log_packets = 0;
  1610. Xlong rx_char_count = 0;
  1611. Xlong tx_char_count = 0;
  1612. Xint Filcnt = 0;
  1613. Xint npaths = 0;
  1614. Xchar curr_dir[256];
  1615. Xchar s128[128];
  1616. Xunsigned baud_rate;
  1617. Xint exit_code;
  1618. Xint sent_EOT = 0;
  1619. X
  1620. Xstruct termio tio;
  1621. Xstruct termio tio0;
  1622. X
  1623. Xjmp_buf    lgetc_timeout_setjmp;
  1624. X
  1625. X/* CRC16 routine; finish CRC calculation for compare */
  1626. X
  1627. X#ifdef TABLE_CRC16
  1628. X
  1629. X/* crctab calculated by Mark G. Mendel,Network Systems Corporation */
  1630. Xunsigned short crctab[256] = 
  1631. X{
  1632. X    0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
  1633. X    0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
  1634. X    0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
  1635. X    0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
  1636. X    0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
  1637. X    0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
  1638. X    0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
  1639. X    0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
  1640. X    0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
  1641. X    0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
  1642. X    0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
  1643. X    0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
  1644. X    0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
  1645. X    0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
  1646. X    0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
  1647. X    0xFF9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
  1648. X    0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
  1649. X    0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
  1650. X    0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
  1651. X    0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
  1652. X    0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
  1653. X    0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
  1654. X    0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
  1655. X    0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
  1656. X    0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
  1657. X    0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
  1658. X    0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
  1659. X    0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
  1660. X    0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
  1661. X    0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
  1662. X    0xef1f,0xFF3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
  1663. X    0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
  1664. X};
  1665. X
  1666. X/*+-------------------------------------------------------------------------
  1667. X  updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. 
  1668. X  NOTE: First argument must be in range 0 to 255.
  1669. X        Second argument is referenced twice.
  1670. X  Programmers may incorporate any or all code into their programs, giving
  1671. X  proper credit within the source.  Publication of the source routines is
  1672. X  permitted so long as proper credit is given to Stephen Satchell,
  1673. X  Satchell Evaluations and Chuck Forsberg, Omen Technology.
  1674. X--------------------------------------------------------------------------*/
  1675. X#define crc_update(ch,crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ ch)
  1676. X
  1677. X#else /* calculated crc */
  1678. X
  1679. X/*+-------------------------------------------------------------------------
  1680. X    crc_update(c,crc)
  1681. X--------------------------------------------------------------------------*/
  1682. Xunsigned short
  1683. Xcrc_update(c,crc)
  1684. Xregister c;
  1685. Xregister unsigned crc;
  1686. X{
  1687. Xregister count;
  1688. X
  1689. X    for(count = 8; --count >= 0;)
  1690. X    {
  1691. X        if(crc & 0x8000)
  1692. X        {
  1693. X            crc <<= 1;
  1694. X            crc += (((c <<= 1) & 0400) != 0);
  1695. X            crc ^= 0x1021;
  1696. X        }
  1697. X        else 
  1698. X        {
  1699. X            crc <<= 1;
  1700. X            crc += (((c <<= 1) & 0400) != 0);
  1701. X        }
  1702. X    }
  1703. X    return(crc);
  1704. X}    /* end of crc_update */
  1705. X#endif /* crc calc selection */
  1706. X
  1707. X/*+-------------------------------------------------------------------------
  1708. X    rdchk(fd) - for systems without it but with FIONREAD
  1709. X--------------------------------------------------------------------------*/
  1710. X#if defined(sun) || defined(NO_RDCHK)
  1711. Xint
  1712. Xrdchk(fd)
  1713. Xint fd;
  1714. X{
  1715. Xint chars_waiting;
  1716. X
  1717. X    if(ioctl(fd,FIONREAD,&chars_waiting))
  1718. X        return(0);
  1719. X    else
  1720. X        return(!!chars_waiting);
  1721. X}    /* end of rdchk */
  1722. X#endif
  1723. X
  1724. X/*+-----------------------------------------------------------------------
  1725. X    arg_token(parsestr,termchars)
  1726. X
  1727. XGet next token from string parsestr ((char *)0 on 2nd, 3rd, etc.
  1728. Xcalls), where tokens are nonempty strings separated by runs of chars
  1729. Xfrom termchars.  Writes nulls into parsestr to end tokens.
  1730. Xtermchars need not remain constant from call to call.
  1731. X
  1732. XTreats multiple occurrences of a termchar as one delimiter (does not
  1733. Xallow null fields).
  1734. X------------------------------------------------------------------------*/
  1735. X#if defined(M_UNIX)
  1736. Xstatic char *arg_token_static = (char *)0;
  1737. Xchar *arg_token(parsestr,termchars)
  1738. Xchar *parsestr;
  1739. Xchar *termchars;
  1740. X{
  1741. Xregister char *parseptr;
  1742. Xchar *token;
  1743. X
  1744. X    if(parsestr == (char *)0 && arg_token_static == (char *)0)
  1745. X        return((char *)0);
  1746. X
  1747. X    if(parsestr)
  1748. X        parseptr = parsestr;
  1749. X    else
  1750. X       parseptr = arg_token_static;
  1751. X
  1752. X    while(*parseptr)
  1753. X    {
  1754. X        if(!strchr(termchars,*parseptr))
  1755. X            break;
  1756. X        parseptr++;
  1757. X    }
  1758. X
  1759. X    if(!*parseptr)
  1760. X    {
  1761. X        arg_token_static = (char *)0;
  1762. X        return((char *)0);
  1763. X    }
  1764. X
  1765. X    token = parseptr;
  1766. X    if(*token == '\'')
  1767. X    {
  1768. X        token++;
  1769. X        parseptr++;
  1770. X        while(*parseptr)
  1771. X        {
  1772. X            if(*parseptr == '\'')
  1773. X            {
  1774. X                arg_token_static = parseptr + 1;
  1775. X                *parseptr = 0;
  1776. X                return(token);
  1777. X            }
  1778. X            parseptr++;
  1779. X        }
  1780. X        arg_token_static = (char *)0;
  1781. X        return(token);
  1782. X    }
  1783. X    while(*parseptr)
  1784. X    {
  1785. X        if(strchr(termchars,*parseptr))
  1786. X        {
  1787. X            *parseptr = 0;
  1788. X            arg_token_static = parseptr + 1;
  1789. X            while(*arg_token_static)
  1790. X            {
  1791. X                if(!strchr(termchars,*arg_token_static))
  1792. X                    break;
  1793. X                arg_token_static++;
  1794. X            }
  1795. X            return(token);
  1796. X        }
  1797. X        parseptr++;
  1798. X    }
  1799. X    arg_token_static = (char *)0;
  1800. X    return(token);
  1801. X}    /* end of arg_token */
  1802. X#endif
  1803. X
  1804. X/*+-------------------------------------------------------------------------
  1805. X    fname_split(cmd,arg,arg_max_quan,&narg)
  1806. X--------------------------------------------------------------------------*/
  1807. X#if defined(M_UNIX)
  1808. Xvoid
  1809. Xfname_split(cmd,arg,arg_max_quan,narg_rtn)
  1810. Xchar *cmd;
  1811. Xchar **arg;
  1812. Xint arg_max_quan;
  1813. Xint *narg_rtn;
  1814. X{
  1815. Xregister itmp;
  1816. Xregister narg;
  1817. X
  1818. X    for(itmp = 0; itmp < arg_max_quan; itmp++)
  1819. X        arg[itmp] = (char *)0;
  1820. X    arg[0] = arg_token(cmd,"/");
  1821. X
  1822. X    for(narg = 1; narg < arg_max_quan; ++narg)
  1823. X    {
  1824. X        if((arg[narg] = arg_token((char *)0,"/")) == (char *)0) 
  1825. X            break;
  1826. X    }
  1827. X
  1828. X    *narg_rtn = narg;
  1829. X
  1830. X}    /* end of fname_split */
  1831. X#endif
  1832. X
  1833. X#if defined(M_UNIX)
  1834. X#define MAX_COMPONENT_LEN    14
  1835. X#define MAX_PATH_COMPONENTS    16
  1836. Xstatic char trunc_fname[257];
  1837. Xstatic char *trunc_components[MAX_PATH_COMPONENTS];
  1838. Xstatic int trunc_components_quan;
  1839. Xstatic int trunc_absolute_path;
  1840. X#endif
  1841. X
  1842. X/*+-------------------------------------------------------------------------
  1843. X    fname_too_long(fname) - check for any pathname component too long
  1844. X--------------------------------------------------------------------------*/
  1845. X#if defined(M_UNIX)
  1846. Xint
  1847. Xfname_too_long(fname)
  1848. Xregister char *fname;
  1849. X{
  1850. Xregister int itmp;
  1851. Xregister char **cpptr;
  1852. X
  1853. X    if(trunc_absolute_path = (*fname == '/'))
  1854. X        fname++;
  1855. X    strncpy(trunc_fname,fname,sizeof(trunc_fname) - 1);
  1856. X    fname_split(trunc_fname,trunc_components,
  1857. X        MAX_PATH_COMPONENTS,&trunc_components_quan);
  1858. X    itmp = trunc_components_quan;
  1859. X    cpptr = trunc_components;
  1860. X    while(itmp--)
  1861. X    {
  1862. X        if(strlen(*cpptr) > MAX_COMPONENT_LEN)
  1863. X            return(1);
  1864. X        cpptr++;
  1865. X    }
  1866. X    return(0);
  1867. X}    /* end of fname_too_long */
  1868. X#endif
  1869. X
  1870. X/*+-------------------------------------------------------------------------
  1871. X    fname_truncated() - build truncated path last checked by fname_too_long
  1872. X--------------------------------------------------------------------------*/
  1873. X#if defined(M_UNIX)
  1874. Xchar *
  1875. Xfname_truncated()
  1876. X{
  1877. Xregister int icomp;
  1878. Xchar new_fname[257];
  1879. Xregister char *cptr = new_fname;
  1880. X
  1881. X    if(trunc_absolute_path)
  1882. X    {
  1883. X        *cptr = '/';
  1884. X        *(cptr + 1) = 0;
  1885. X    }
  1886. X    else
  1887. X        *cptr = 0;
  1888. X    for(icomp = 0; icomp < trunc_components_quan; icomp++)
  1889. X    {
  1890. X        if(strlen(trunc_components[icomp]) > MAX_COMPONENT_LEN)
  1891. X            *(trunc_components[icomp] + MAX_COMPONENT_LEN) = 0;
  1892. X        strcat(cptr,trunc_components[icomp]);
  1893. X        if(icomp < trunc_components_quan - 1)
  1894. X            strcat(cptr,"/");
  1895. X    }
  1896. X    strcpy(trunc_fname,cptr);
  1897. X    return(trunc_fname);
  1898. X
  1899. X}    /* end of fname_truncated */
  1900. X#endif
  1901. X
  1902. X/*+-------------------------------------------------------------------------
  1903. X    xmit_cancel()
  1904. X--------------------------------------------------------------------------*/
  1905. Xvoid
  1906. Xxmit_cancel()
  1907. X{
  1908. Xchar *cancel_msg = "\030\030\030\030\030\030\030\030\b\b\b\b\b\b\b\b";
  1909. X
  1910. X    ioctl(iofd,TCFLSH,(char *)1);
  1911. X    write(iofd,cancel_msg,16);
  1912. X    tx_char_count += 16;
  1913. X    report_str("CANCELling transfer",1);
  1914. X    report_last_txhdr("CAN",0);
  1915. X
  1916. X}    /* end of xmit_cancel */
  1917. X
  1918. X/*+-------------------------------------------------------------------------
  1919. X    xmit_ack(blknum)
  1920. X--------------------------------------------------------------------------*/
  1921. Xvoid
  1922. Xxmit_ack(blknum)
  1923. Xregister int blknum;            /* block number */
  1924. X{
  1925. Xchar s16[16];
  1926. X
  1927. X    sprintf(s16,"ACK %3d",blknum);
  1928. X    report_last_txhdr(s16,0);
  1929. X
  1930. X    s16[0] = ACK;
  1931. X    s16[1] = blknum;            /* block number */
  1932. X    s16[2] = blknum ^ 0xFF;    /* block number check */
  1933. X    write(iofd,s16,3);
  1934. X    tx_char_count += 3;
  1935. X}    /* end of xmit_ack */
  1936. X
  1937. X/*+-------------------------------------------------------------------------
  1938. X    xmit_nak(blknum)
  1939. X--------------------------------------------------------------------------*/
  1940. Xvoid
  1941. Xxmit_nak(blknum)
  1942. Xregister int blknum;            /* block number */
  1943. X{
  1944. Xchar s16[16];
  1945. X
  1946. X    sprintf(s16,"NAK %d",blknum);
  1947. X    report_last_txhdr(s16,1);
  1948. X
  1949. X    if(crc_in_use)
  1950. X        s16[0] = 'C';
  1951. X    else
  1952. X        s16[0] = NAK;
  1953. X
  1954. X    s16[1] = blknum;            /* block number */
  1955. X    s16[2] = blknum ^ 0xFF;    /* block number check */
  1956. X    write(iofd,s16,3);
  1957. X    tx_char_count += 3;
  1958. X
  1959. X}    /* end of xmit_nak */
  1960. X
  1961. X/*+-------------------------------------------------------------------------
  1962. X    lgetc_timeout_SIGALRM() - called when alarm is caught by lgetc_timeout
  1963. X--------------------------------------------------------------------------*/
  1964. X#if defined(NO_SELECT)
  1965. Xvoid
  1966. Xlgetc_timeout_SIGALRM(sig)
  1967. Xint sig;
  1968. X{
  1969. X    longjmp(lgetc_timeout_setjmp,TIMEOUT);
  1970. X}    /* end of lgetc_timeout_SIGALRM */
  1971. X#endif
  1972. X
  1973. X/*+-------------------------------------------------------------------------
  1974. X    lgetc_timeout(tenths)
  1975. X
  1976. X reads one character from line unless timeout in tenths passes
  1977. X with no receipt.
  1978. X--------------------------------------------------------------------------*/
  1979. Xunsigned int
  1980. Xlgetc_timeout(tenths)
  1981. Xint tenths;
  1982. X{
  1983. X#if defined(NO_SELECT)
  1984. Xunsigned char rdchar;
  1985. Xlong msec;
  1986. Xint seconds;
  1987. Xlong Nap();
  1988. X#else
  1989. Xint fdmask;
  1990. Xstruct timeval tval;
  1991. Xunsigned char rdchar;
  1992. X#endif
  1993. X
  1994. X    if(!tenths)
  1995. X    {
  1996. X        if(!rdchk(iofd))
  1997. X            return(TIMEOUT);
  1998. X        else
  1999. X        {
  2000. X            read(iofd,&rdchar,1);
  2001. X            rx_char_count++;
  2002. X            return((unsigned int)rdchar);
  2003. X        }
  2004. X    }
  2005. X
  2006. X#if defined(NO_SELECT)
  2007. X
  2008. X/* there is a timeout ... if less than 2 secs, nap it out */
  2009. X    if(tenths <= 20)
  2010. X    {
  2011. X        msec = (tenths < 6) ? 60L : (long)tenths * 10;
  2012. X        while(msec)
  2013. X        {
  2014. X            msec -= Nap(20L);
  2015. X            if(rdchk(iofd))
  2016. X            {
  2017. X                read(iofd,&rdchar,1);
  2018. X                rx_char_count++;
  2019. X                return((unsigned int)rdchar);
  2020. X            }
  2021. X        }
  2022. X        report_last_rxhdr("TIMEOUT",0);
  2023. X        return(TIMEOUT);
  2024. X    }
  2025. X
  2026. X/* timeout is > 2 seconds use sleep */
  2027. X
  2028. X    seconds = (tenths / 10) + 1;
  2029. X
  2030. X    if(setjmp(lgetc_timeout_setjmp))
  2031. X    {
  2032. X        report_last_rxhdr("TIMEOUT",0);
  2033. X        return(TIMEOUT);
  2034. X    }
  2035. X
  2036. X    signal(SIGALRM,lgetc_timeout_SIGALRM);
  2037. X    alarm(seconds);
  2038. X    while(read(iofd,&rdchar,1) != 1)
  2039. X        ;
  2040. X    alarm(0);
  2041. X    signal(SIGALRM,SIG_DFL);
  2042. X
  2043. X#else
  2044. X
  2045. X    if(tenths < 6)
  2046. X        tenths = 6;
  2047. X    tval.tv_sec = tenths / 10L;
  2048. X    tval.tv_usec = (tenths % 10L) * 100000L;
  2049. X    fdmask = 1 << iofd;
  2050. X    if(select(32,&fdmask,(int *)0,(int *)0,&tval) != 1)
  2051. X    {
  2052. X        report_last_rxhdr("TIMEOUT",0);
  2053. X        return(TIMEOUT);
  2054. X    }
  2055. X    if((!rdchk(iofd)) || (read(iofd,&rdchar,1) < 0))
  2056. X    {
  2057. X        report_last_rxhdr("TIMEOUT",0);
  2058. X        return(TIMEOUT);
  2059. X    }
  2060. X
  2061. X#endif
  2062. X
  2063. X    rx_char_count++;
  2064. X    return((unsigned int)rdchar);
  2065. X
  2066. X}    /* end of lgetc_timeout */
  2067. X
  2068. X/*+-------------------------------------------------------------------------
  2069. X    sf_state_text(state)
  2070. X--------------------------------------------------------------------------*/
  2071. Xchar *
  2072. Xsf_state_text(state)
  2073. Xregister state;
  2074. X{
  2075. Xchar unrecog[16];
  2076. X
  2077. X    switch(state)
  2078. X    {
  2079. X        case SFS_GND:    return("GND");
  2080. X        case SFS_ACK:    return("ACK");
  2081. X        case SFS_NAK:    return("NAK");
  2082. X        case SFS_ACKW:    return("ACKW");
  2083. X        case SFS_NAKW:    return("NAKW");
  2084. X        case SFS_RGND:    return("RGND");
  2085. X        default:
  2086. X            sprintf(unrecog,"SFS_%d",state);
  2087. X            return(unrecog);
  2088. X    }
  2089. X
  2090. X}    /* end of sf_state_text */
  2091. X
  2092. X/*+-------------------------------------------------------------------------
  2093. X    set_sf_state(place,new_state)
  2094. X--------------------------------------------------------------------------*/
  2095. Xvoid
  2096. Xset_sf_state(place,new_state)
  2097. Xint place;
  2098. Xint new_state;
  2099. X{
  2100. X    if(log_packets)
  2101. X    {
  2102. X        sprintf(s128,"state from %s to %s (%d)",
  2103. X            sf_state_text(sf_state),sf_state_text(new_state),place);
  2104. X        report_str(s128,0);
  2105. X    }
  2106. X    sf_state = new_state;
  2107. X}    /* end of set_sf_state */
  2108. X
  2109. X/*+-------------------------------------------------------------------------
  2110. X    wait_for_rcvr_response() - check for ACK or NAK
  2111. X sets 'sf_state' to SFS_... value depending on response from file rcvr
  2112. X returns 1 if TIMEOUT at state other than ground, else 0
  2113. X--------------------------------------------------------------------------*/
  2114. Xint
  2115. Xwait_for_rcvr_response()
  2116. X{
  2117. Xint c;                        /* one byte of data */
  2118. Xstatic int rawblk = 0;        /* raw block number */
  2119. X
  2120. X    while((c = lgetc_timeout((sf_state == SFS_GND) ? 0 : 6)) != TIMEOUT)
  2121. X    {
  2122. X        if(c == CAN)
  2123. X        {                                    /* CANcel received? */
  2124. X            if((c = lgetc_timeout(20)) == CAN)
  2125. X            {
  2126. X                sf_nakquan = 11;
  2127. X                report_last_rxhdr("CAN",0);    /* error counted at cancel time */
  2128. X            }
  2129. X            break;
  2130. X        }
  2131. X        if(sf_state == SFS_ACKW || sf_state == SFS_NAKW)    /* windowed */
  2132. X        {
  2133. X            sf_slide = 0;                        /* assume this will fail */
  2134. X            /* see if we believe the number */
  2135. X            if(rawblk == (c ^ 0xFF))
  2136. X            {
  2137. X                rawblk = sf_blknum - ((sf_blknum - rawblk) & 0xFF);
  2138. X                if((rawblk >= 0) && (rawblk <= sf_blknum) &&
  2139. X                    (rawblk > (sf_blknum - 128)))
  2140. X                {                /* we have sliding window! */
  2141. X                    if(sf_state == SFS_ACKW)
  2142. X                    {
  2143. X                        sf_ackblk = (sf_ackblk > rawblk) ? sf_ackblk : rawblk;
  2144. X                        sf_slide = 1;
  2145. X                        if(no_ack_mode && (++sf_ackw_count > 10))
  2146. X                        {
  2147. X                            no_ack_mode = 0;
  2148. X                            report_str("Overdrive disengaged",0);
  2149. X                        }
  2150. X                    }
  2151. X                    else 
  2152. X                    {
  2153. X                        sf_blknum = (rawblk < 0) ? 0 : rawblk;
  2154. X                        sf_slide = (sf_nakquan < 4);
  2155. X                    }
  2156. X                    sprintf(s128,"%s %5d",
  2157. X                        (sf_state == SFS_ACKW) ? "ACKW" : "NAKW",rawblk);
  2158. X                    report_last_rxhdr(s128,(sf_state != SFS_ACKW) && rawblk);
  2159. X                }
  2160. X            }
  2161. X            set_sf_state(1,SFS_RGND);    /* return to ground state */
  2162. X        }
  2163. X
  2164. X        if(sf_state == SFS_ACK || sf_state == SFS_NAK)
  2165. X        {
  2166. X            rawblk = c;
  2167. X            if(sf_state == SFS_ACK)
  2168. X                set_sf_state(2,SFS_ACKW);
  2169. X            else
  2170. X                set_sf_state(3,SFS_NAKW);
  2171. X        }
  2172. X
  2173. X        if(!sf_slide || sf_state == SFS_GND)
  2174. X        {
  2175. X            if(c == ACK)
  2176. X            {
  2177. X                if(!sf_slide)
  2178. X                {
  2179. X                    sprintf(s128,"ACK %3d",sf_ackblk);
  2180. X                    report_last_rxhdr(s128,0);
  2181. X                    sf_ackblk++;
  2182. X                }
  2183. X                set_sf_state(4,SFS_ACK);
  2184. X                sf_nakquan = 0;
  2185. X            }
  2186. X            else if(c == 'C' || c == NAK)
  2187. X            {
  2188. X                /* if method not determined yet */
  2189. X                if(crc_in_use > 1)    /* then do what rcvr wants */
  2190. X                {
  2191. X                    crc_in_use = (c == 'C');
  2192. X                    report_protocol_crc_type(crc_in_use ? "/CRC16" : "/CHK");
  2193. X                }
  2194. X                ioctl(iofd,TCFLSH,(char *)1);
  2195. X                if(!sf_slide)
  2196. X                {
  2197. X                    sf_blknum = sf_ackblk + 1;
  2198. X                    sprintf(s128,"NAK %3d",sf_blknum);
  2199. X                    report_last_rxhdr(s128,(!!sf_blknum));
  2200. X                }
  2201. X                set_sf_state(5,SFS_NAK);
  2202. X                sf_nakquan++;
  2203. X                if(sf_lastnum)
  2204. X                    error_count++;
  2205. X            }
  2206. X        }
  2207. X
  2208. X        if(sf_state == SFS_RGND)
  2209. X            set_sf_state(6,SFS_GND);
  2210. X    }
  2211. X    return((sf_state != SFS_GND) && (c == TIMEOUT));
  2212. X}    /* end of wait_for_rcvr_response */
  2213. X
  2214. X/*+-------------------------------------------------------------------------
  2215. X    send_comm_block(blk,blknum) - format and transmit block
  2216. X--------------------------------------------------------------------------*/
  2217. Xint
  2218. Xsend_comm_block(blk,blknum)
  2219. Xchar *blk;                /* data to be shipped */
  2220. Xint blknum;                /* number of block */
  2221. X{
  2222. Xregister unsigned short rUINT16 = 0;
  2223. Xregister int itmp;
  2224. Xunsigned char chksum;
  2225. Xchar *cptr = blk;
  2226. Xchar s3[3];
  2227. X
  2228. X    s3[0] = SOH;                /* block header */
  2229. X    s3[1] = blknum;                /* block number */
  2230. X    s3[2] = blknum ^ 0xFF;        /* block number check value */
  2231. X
  2232. X/* calculate the crc or checksum */
  2233. X    itmp = 128;
  2234. X    if(crc_in_use)
  2235. X    {
  2236. X        while(itmp--)
  2237. X        {
  2238. X            rUINT16 = crc_update(*cptr,rUINT16);
  2239. X            cptr++;
  2240. X        }
  2241. X        rUINT16 = crc_update(0,rUINT16);
  2242. X        rUINT16 = crc_update(0,rUINT16);
  2243. X    }
  2244. X    else 
  2245. X    {
  2246. X        while(itmp--)
  2247. X            rUINT16 += *cptr++;
  2248. X    }
  2249. X
  2250. X/* write the block */
  2251. X
  2252. X    write(iofd,s3,3);                        /* the header */
  2253. X    write(iofd,blk,128);                    /* the block */
  2254. X    if(crc_in_use)                            /* the crc or checksum */
  2255. X    {
  2256. X        s3[0] = rUINT16 >> 8;
  2257. X        s3[1] = rUINT16 & 0xFF;
  2258. X        write(iofd,s3,2);
  2259. X        tx_char_count += 133;
  2260. X    }
  2261. X    else
  2262. X    {
  2263. X        chksum = rUINT16;
  2264. X        write(iofd,&chksum,1);
  2265. X        tx_char_count += 132;
  2266. X    }
  2267. X
  2268. X    return(1);
  2269. X}    /* end of send_comm_block */
  2270. X
  2271. X/*+-------------------------------------------------------------------------
  2272. X    send_file_block(fp,blknum) - read a block from file and send it
  2273. X--------------------------------------------------------------------------*/
  2274. Xvoid
  2275. Xsend_file_block(fp,blknum)
  2276. XFILE *fp;
  2277. Xint blknum;
  2278. X{
  2279. Xlong fileaddr;
  2280. Xchar buf[128];
  2281. X
  2282. X    fileaddr = (long)(blknum - 1) * 128L;
  2283. X    if(blknum != sf_lastnum + 1)
  2284. X        fseek(fp,fileaddr,0);    /* move where to */
  2285. X    sf_lastnum = blknum;
  2286. X    report_txpos(fileaddr);
  2287. X
  2288. X    memset(buf,0x1A,sizeof(buf));    /* fill buffer with control Zs */
  2289. X    fread(buf,1,sizeof(buf),fp);    /* read in some data */
  2290. X    send_comm_block(buf,blknum);    /* pump it out to the receiver */
  2291. X}    /* end of send_file_block */
  2292. X
  2293. X/*+-------------------------------------------------------------------------
  2294. X    send_file(name) - transmit a file
  2295. X--------------------------------------------------------------------------*/
  2296. Xint
  2297. Xsend_file(name)
  2298. Xchar *name;
  2299. X{
  2300. Xregister int endblk;    /* block number of EOT */
  2301. XFILE *fp = (FILE *)0;    /* file to send */
  2302. Xstruct stat fst;
  2303. XBLK0 blk0;
  2304. Xchar *basename;            /* base filename */
  2305. Xchar eot = EOT;
  2306. X
  2307. X    Filcnt++;
  2308. X    if(name && *name)            /* if sending a file */
  2309. X    {
  2310. X        if((fp = fopen(name,"r")) == NULL)
  2311. X        {
  2312. X            sprintf(s128,"Cannot open %s",name);
  2313. X            report_str(s128,1);
  2314. X            exit_code = 253;
  2315. X            return(0);
  2316. X        }
  2317. X
  2318. X        memset((char *)&blk0,0,sizeof(blk0)); /* clear out data block */
  2319. X
  2320. X        stat(name,&fst);    /* get file statistics */
  2321. X        blk0.length = (long)fst.st_size;
  2322. X
  2323. X        /* cnvt time from 1970 base to 1980 */
  2324. X        if((blk0.secs_since_1980 = fst.st_mtime-OFFSET_1980) < 0L)
  2325. X            blk0.secs_since_1980 = 0;
  2326. X
  2327. X        if((basename = strrchr(name,'/')) == NULL) /* find basename */
  2328. X            strcpy(blk0.filename,name);
  2329. X        else 
  2330. X        {
  2331. X            basename++;
  2332. X            strcpy(blk0.filename,basename);
  2333. X        }
  2334. X
  2335. X        strcpy(blk0.sender,"ecusea ");
  2336. X        strcat(blk0.sender,revision);
  2337. X        blk0.send_no_acks = no_ack_mode;
  2338. X
  2339. X        endblk = (int)((blk0.length + 127L) / 128L) + 1;
  2340. X        report_file_send_open(name,&fst);
  2341. X    }
  2342. X    else 
  2343. X    {
  2344. X        endblk = 0;                        /* fake for no file */
  2345. X        report_str("sending EOT indication",-1);
  2346. X        report_txpos(blk0.length);
  2347. X    }
  2348. X
  2349. X
  2350. X    sf_blknum = 1;                        /* set starting state */
  2351. X    sf_ackblk = -1;
  2352. X    sf_state = SFS_GND;
  2353. X    sf_lastnum = 0;
  2354. X    sf_slide = 0;
  2355. X    sf_nakquan = 0;
  2356. X    error_count = 0;
  2357. X    sf_ackw_count = 0;
  2358. X    crc_in_use = 2;                        /* undetermined */
  2359. X
  2360. X    while(sf_ackblk < endblk)            /* while not all there yet */
  2361. X    {
  2362. X        sent_EOT = 0;
  2363. X        if(sf_blknum <= sf_ackblk + ((sf_slide && allow_slide) ? WINDOW : 1))
  2364. X        {
  2365. X            if(sf_blknum < endblk)
  2366. X            {
  2367. X                if(sf_blknum > 0)
  2368. X                {
  2369. X                    sprintf(s128,"sending block %d",sf_blknum);
  2370. X                    report_last_txhdr(s128,0);
  2371. X                    send_file_block(fp,sf_blknum);
  2372. X                }
  2373. X                else
  2374. X                {
  2375. X                    sprintf(s128,"sending filename",sf_blknum);
  2376. X                    report_last_txhdr(s128,0);
  2377. X                    send_comm_block((char *)&blk0,0);
  2378. X                    report_txpos(0L);
  2379. X                }
  2380. X                if(no_ack_mode && sf_slide && allow_slide)
  2381. X                    sf_ackblk = sf_blknum;
  2382. X            }
  2383. X            else if(sf_blknum == endblk)
  2384. X            {
  2385. X                report_last_txhdr("EOT",0);
  2386. X                write(iofd,&eot,1);
  2387. X                sent_EOT = 1;
  2388. X                Nap(500L);
  2389. X                tx_char_count++;
  2390. X            }
  2391. X            sf_blknum++;
  2392. X        }
  2393. X
  2394. X        if(wait_for_rcvr_response() && sent_EOT)
  2395. X        {
  2396. X            report_str("Receiver did not ACK our EOT",-1);
  2397. X            break;
  2398. X        }
  2399. X
  2400. X        if(sf_nakquan > 10)
  2401. X            goto CANCEL_TRANSFER;
  2402. X    }
  2403. X
  2404. X    if(endblk)    /* if sending file, not EOT */
  2405. X        fclose(fp);
  2406. X    return(1);                            /* exit with good status */
  2407. X
  2408. XCANCEL_TRANSFER:
  2409. X    if(endblk)    /* if sending file, not EOT */
  2410. X        fclose(fp);
  2411. X    xmit_cancel();
  2412. SHAR_EOF
  2413. true || echo 'restore of sea/ecusea.c failed'
  2414. fi
  2415. echo 'End of ecu320 part 26'
  2416. echo 'File sea/ecusea.c is continued in part 27'
  2417. echo 27 > _shar_seq_.tmp
  2418. exit 0
  2419.  
  2420. exit 0 # Just in case...
  2421.