home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume32 / ecu / part26 < prev    next >
Encoding:
Text File  |  1992-09-13  |  56.9 KB  |  2,415 lines

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