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

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
  4. Subject:  v32i062:  ecu - ECU Asynchronous Communications v3.20, Part27/40
  5. Message-ID: <1992Sep14.144840.22238@sparky.imd.sterling.com>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: 993df7828f781ca49290a84e9186045e
  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:40 GMT
  12. Approved: kent@sparky.imd.sterling.com
  13. Lines: 1950
  14.  
  15. Submitted-by: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
  16. Posting-number: Volume 32, Issue 62
  17. Archive-name: ecu/part27
  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.27 (part 27 of ecu320)
  24. # do not concatenate these parts, unpack them in order with /bin/sh
  25. # file sea/ecusea.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" != 27; 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 sea/ecusea.c'
  41. else
  42. echo 'x - continuing file sea/ecusea.c'
  43. sed 's/^X//' << 'SHAR_EOF' >> 'sea/ecusea.c' &&
  44. X    return(0);                          /* exit with bad status */
  45. X}    /* end of send_file */
  46. X
  47. X/*+-------------------------------------------------------------------------
  48. X    set_utime_1980(filename,secs_since_1980)
  49. X--------------------------------------------------------------------------*/
  50. Xvoid
  51. Xset_utime_1980(filename,secs_since_1980)
  52. Xchar *filename;                        /* file to set stamp on */
  53. Xlong secs_since_1980;
  54. X{
  55. Xtime_t times[2];
  56. Xtime_t time();
  57. X
  58. X    times[0] = time((long *) 0);                /* accessed */
  59. X    times[1] = secs_since_1980 + OFFSET_1980;    /* modified (convert time) */
  60. X    utime(filename,times);
  61. X}    /* end of set_utime_1980 */
  62. X
  63. X/*+-------------------------------------------------------------------------
  64. X    receive_block(buf) - get block from line
  65. Xreturn 0 if good chk/CRC, 1 if bad
  66. X--------------------------------------------------------------------------*/
  67. Xint
  68. Xreceive_block(buf)
  69. Xchar *buf;                /* data buffer */
  70. X{
  71. Xregister unsigned int rdchar;    
  72. Xregister unsigned short rUINT16 = 0;    /* calculated CRC or check value */
  73. Xint itmp;
  74. Xint timeout = no_ack_mode ? 200 : 5;    /* short block timeout */
  75. Xunsigned short rcvd_crc;                /* received CRC or check value */
  76. X
  77. X    itmp = 128;
  78. X    while(itmp--)
  79. X    {
  80. X        if((rdchar = lgetc_timeout(timeout)) == TIMEOUT)
  81. X            return(1);
  82. X        if(crc_in_use)
  83. X            rUINT16 = crc_update(rdchar,rUINT16);
  84. X        else
  85. X            rUINT16 += rdchar;
  86. X        *buf++ = rdchar;
  87. X    }
  88. X
  89. X    if(crc_in_use)
  90. X    {
  91. X        rUINT16 = crc_update(0,rUINT16);
  92. X        rUINT16 = crc_update(0,rUINT16);
  93. X        rdchar = lgetc_timeout(timeout);
  94. X        rcvd_crc = (rdchar << 8) | lgetc_timeout(timeout);
  95. X    }
  96. X    else 
  97. X    {
  98. X        rUINT16 &= 0xFF;
  99. X        rcvd_crc = lgetc_timeout(timeout) & 0xFF;
  100. X    }
  101. X
  102. X    if(rUINT16 != rcvd_crc)
  103. X    {
  104. X        sprintf(s128,"bad %s calc=%04x rcvd=%04x",
  105. X            crc_in_use ? "CRC" : "checksum",rcvd_crc,rUINT16);
  106. X        report_str(s128,-1);
  107. X    }
  108. X    return(rUINT16 != rcvd_crc);
  109. X}    /* end of receive_block */
  110. X
  111. X/*+-------------------------------------------------------------------------
  112. X    receive_file()
  113. X--------------------------------------------------------------------------*/
  114. Xchar *
  115. Xreceive_file()
  116. X{
  117. Xint rdchar;                    /* received character */
  118. Xint tries;                    /* retry counter */
  119. Xint blknum;                    /* desired block number */
  120. Xint inblk;                    /* this block number */
  121. XFILE *fp;
  122. Xchar buf[128];                /* data buffer */
  123. Xchar tmpname[100];            /* name of temporary file */
  124. Xstatic char outname[100];    /* name of final file */
  125. XBLK0 blk0;                    /* file header data storage */
  126. Xint endblk;                    /* block number of EOT, if known */
  127. Xlong left = 0;                /* bytes left to output */
  128. Xint itmp;                    /* index */
  129. Xint cnvrt;                    /* flag -- convert filename? */
  130. Xchar *onp;                    /* use to convert filename to l / rdchar */
  131. Xlong ftell();
  132. X
  133. X    *outname = '\0';        /* get name from transmitter */
  134. X    cnvrt = 1;        /* convert to local is necessary */
  135. X    sprintf(tmpname,"./SEA%05d.tmp",getpid());    /* use a unique temp filename */
  136. X
  137. X    if(!(fp = fopen(tmpname,"w")))
  138. X    {    /* open temporary file */
  139. X        sprintf(s128,"Cannot create temp file %s\n",tmpname);
  140. X        report_str(s128,0);
  141. X        xmit_cancel();
  142. X        return(NULL);
  143. X    }
  144. X
  145. X    blknum = 0;
  146. X    tries = -10;                /* kludge for first time around */
  147. X    crc_in_use = 1;                /* try for CRC error checking */
  148. X    error_count = 0;            /* no errors yet */
  149. X    endblk = 0;                    /* we don't know the size yet */
  150. X    no_ack_mode = 0;            /* we don't know about this yet */
  151. X    memset((char *)&blk0,0,sizeof(blk0));    /* or much of anything else */
  152. X    report_protocol_crc_type("/CRC16");
  153. X
  154. XSEND_NAK:                /* we got a bad block */
  155. X    if(blknum > 1)
  156. X    {
  157. X        error_count++;
  158. X        report_str("bad block",1);
  159. X    }
  160. X    if(++tries > 10)
  161. X        goto CANCEL_TRANSFER;
  162. X    if(tries == 0)            /* if CRC isn't going */
  163. X    {
  164. X        crc_in_use = 0;        /* then give checksum a try */
  165. X        report_protocol_crc_type("/CHK");
  166. X    }
  167. X
  168. X    xmit_nak(blknum);        /* send the NAK */
  169. X    if(no_ack_mode && error_count > 20)
  170. X    {    /* if no_ack_mode mode isn't working */
  171. X        no_ack_mode = 0;        /* then shut it off */
  172. X        report_str("Overdrive disengaged",0);
  173. X    }
  174. X
  175. XRECEIVE_NEXT_BLOCK:                /* start of "get a block" */
  176. X    report_rxpos(ftell(fp));
  177. X    while((rdchar = lgetc_timeout(30)) != TIMEOUT)
  178. X    {
  179. X        if(rdchar == CAN)
  180. X        {
  181. X            if((rdchar = lgetc_timeout(30)) == CAN)
  182. X            {
  183. X                xmit_cancel();
  184. X                return(NULL);
  185. X            }
  186. X            break;
  187. X        }
  188. X        if(rdchar == EOT)
  189. X        {
  190. X            if(!endblk || endblk == blknum)
  191. X                goto RECEIVE_EOT_SEEN;
  192. X        }
  193. X        else if(rdchar == SOH)
  194. X        {
  195. X            if((inblk = lgetc_timeout(5)) == TIMEOUT)
  196. X                goto SEND_NAK;
  197. X            if(lgetc_timeout(5) == (inblk ^ 0xFF))
  198. X            {
  199. X                sprintf(s128,"receiving %d",inblk);
  200. X                report_last_rxhdr(s128,0);
  201. X                goto GOT_START_OF_BLOCK;    /* we found a start */
  202. X            }
  203. X        }
  204. X    }
  205. X    goto SEND_NAK;
  206. X
  207. XGOT_START_OF_BLOCK:                /* start of block detected */
  208. X    rdchar = blknum & 0xFF;
  209. X    if(inblk == 0 && blknum <= 1)
  210. X    {    /* if this is the header */
  211. X        if(receive_block((char *)&blk0))
  212. X            goto SEND_NAK;        /* bad header block */
  213. X        else 
  214. X        {
  215. X            xmit_ack(inblk);    /* ack the header */
  216. X
  217. X#if defined(M_UNIX)
  218. X            if(fname_too_long(blk0.filename))
  219. X            {
  220. X                strcpy(s128,"truncated: ");
  221. X                strncat(s128,blk0.filename,sizeof(s128) - 12);
  222. X                report_str(s128,-1);
  223. X                strcpy(outname,fname_truncated());
  224. X            }
  225. X            else
  226. X#endif
  227. X                strcpy(outname,blk0.filename);
  228. X            report_file_rcv_started(outname,blk0.length,
  229. X                blk0.secs_since_1980 + OFFSET_1980);
  230. X            if(left = blk0.length)    /* length to transfer */
  231. X                endblk=(int)((left + 127L)/128L)+1;
  232. X            if(no_ack_mode != blk0.send_no_acks)
  233. X            {
  234. X                sprintf(s128,"Overdrive %sengaged",
  235. X                    (blk0.send_no_acks) ? "" : "dis");
  236. X                report_str(s128,0);
  237. X            }
  238. X            no_ack_mode = blk0.send_no_acks;
  239. X            blknum = 1;    /* now we want first data block */
  240. X            goto RECEIVE_NEXT_BLOCK;
  241. X        }
  242. X    }
  243. X
  244. X    if(inblk == rdchar)
  245. X    {            /* if this is the one we want */
  246. X        if(!receive_block(buf))
  247. X        {        /* else if we get it okay */
  248. X            if(!no_ack_mode)        /* if we're sending ACKs */
  249. X                xmit_ack(inblk);    /* then ACK the data */
  250. X            for(itmp = 0; itmp < 128; itmp++)
  251. X            {
  252. X                if(endblk)
  253. X                {    /* limit file size if known */
  254. X                    if(!left)
  255. X                        break;
  256. X                    left--;
  257. X                }
  258. X                if(fputc(buf[itmp],fp) == EOF)
  259. X                {
  260. X                    report_str("FILE WRITE ERROR",0);
  261. X                    goto CANCEL_TRANSFER;
  262. X                }
  263. X            }
  264. X            tries = 0;        /* reset try count */
  265. X            blknum++;        /* we want the next block */
  266. X            goto RECEIVE_NEXT_BLOCK;
  267. X        }
  268. X        goto SEND_NAK;        /* ask for a resend */
  269. X    }
  270. X
  271. X    if(inblk < rdchar || inblk > rdchar + 100)
  272. X    {    /* if resending what we have */
  273. X        receive_block(buf);            /* ignore it */
  274. X        xmit_ack(inblk);            /* but ack it */
  275. X    }
  276. X    goto RECEIVE_NEXT_BLOCK;        /* else if running ahead */
  277. X
  278. XRECEIVE_EOT_SEEN:
  279. X#ifdef NAKEOT
  280. X    xmit_nak(blknum);                /* NAK the EOT, make sure */
  281. X    if(lgetc_timeout(20) != EOT)    /* we're all done */
  282. X        goto SEND_NAK;
  283. X#endif /* NAKEOT */
  284. X    xmit_ack(blknum);                /* ACK it and clean up */
  285. X    report_last_rxhdr("EOT",0);
  286. X    if(blknum > 1)
  287. X    {                /* if we really got anything */
  288. X        fclose(fp);
  289. X        unlink(outname);        /* rename temp to proper name */
  290. X        for(onp = outname;cnvrt && *onp;onp++)
  291. X            /* find out if there's lower- */
  292. X            if(islower(*onp))    /* case letters filename */
  293. X                cnvrt = 0;    /*  there are, don't convert */
  294. X        if(cnvrt)            /* if there aren't, make all */
  295. X            for(onp = outname;*onp;onp++)    /* into uppercase */
  296. X                *onp = tolower(*onp);
  297. X        if(link(tmpname,outname) == 0)
  298. X            unlink(tmpname);
  299. X        if(blk0.secs_since_1980)        /* set stamp, if known */
  300. X            set_utime_1980(outname,blk0.secs_since_1980);
  301. X        return(outname);
  302. X    }
  303. X    else 
  304. X    {                /* else no real file */
  305. X        fclose(fp);
  306. X        unlink(tmpname);        /* discard empty file */
  307. X        report_str("end of transfer",0);
  308. X        rf_done = 1;
  309. X        return(NULL);
  310. X    }
  311. X
  312. XCANCEL_TRANSFER:
  313. X    fclose(fp);
  314. X    xmit_cancel();
  315. X    rf_done = 2;
  316. X    return(NULL);
  317. X}    /* end of receive_file */
  318. X
  319. X/*+-------------------------------------------------------------------------
  320. X    cancel_transaction(sig)
  321. X--------------------------------------------------------------------------*/
  322. XSIGTYPE
  323. Xcancel_transaction(sig)
  324. Xint sig;
  325. X{
  326. X    xmit_cancel();
  327. X    sprintf(s128,"signal %d ... exiting",sig);
  328. X    report_str(s128,1);
  329. X/*
  330. X    report_rx_ind(0);
  331. X    report_tx_ind(0);
  332. X*/
  333. X    report_uninit();
  334. X    if(sig == SIGQUIT)
  335. X        abort();
  336. X    exit(128+sig);
  337. X}    /* end of cancel_transaction */
  338. X
  339. X/*+-------------------------------------------------------------------------
  340. X    getspeed(code)
  341. X--------------------------------------------------------------------------*/
  342. Xstruct B_to_baud { unsigned baud; int B_code; };
  343. Xunsigned
  344. Xgetspeed(code)
  345. Xint code;
  346. X{
  347. Xregister itmp;
  348. Xstatic struct B_to_baud speeds[] = 
  349. X{
  350. X 50, B50, 75, B75, 110, B110, 300, B300, 600, B600, 1200, B1200,
  351. X 2400, B2400, 4800, B4800, 9600, B9600, 19200, EXTA, 38400, EXTB, 0
  352. X};
  353. X
  354. X    code &= CBAUD;
  355. X    for(itmp = 0; speeds[itmp].baud; itmp++)
  356. X        if(speeds[itmp].B_code == code)
  357. X            return(speeds[itmp].baud);
  358. X    return(38400);    /* Assume fifo if ioctl failed */
  359. X}    /* end of getspeed */
  360. X
  361. X/*+-------------------------------------------------------------------------
  362. X    main(argc,argv,envp)
  363. X--------------------------------------------------------------------------*/
  364. Xmain(argc,argv,envp)
  365. Xint argc;
  366. Xchar **argv;
  367. Xchar **envp;
  368. X{
  369. Xint ipaths;
  370. Xint ok = 0;
  371. X#define MAX_PATHS 512
  372. Xchar *paths[MAX_PATHS];
  373. Xchar **ppaths = paths;
  374. Xchar *cptr;
  375. Xchar **gargv = argv;
  376. Xint gargc = argc;
  377. X
  378. X    exit_code = 254;
  379. X    while(--argc)
  380. X    {
  381. X        cptr = *++argv;
  382. X        if(*cptr == '-')
  383. X        {
  384. X            cptr++;
  385. X            switch(*cptr++)
  386. X            {
  387. X            case ',':
  388. X                log_packets = 1;
  389. X                break;
  390. X            case '/':
  391. X                if(--argc < 1)
  392. X                    exit(255);
  393. X                strcpy(curr_dir,*++argv);
  394. X                break;
  395. X            case '.':
  396. X                if(--argc < 1)
  397. X                    exit(255);
  398. X                iofd = atoi(*++argv);
  399. X                break;
  400. X            case 'r':
  401. X                sending_flag = 0;
  402. X                break;
  403. X            case 's':
  404. X                sending_flag = 1;
  405. X            }
  406. X        }
  407. X        else if(argc > 0)
  408. X        {
  409. X            if(npaths < MAX_PATHS)
  410. X            {
  411. X                *ppaths++ = cptr;
  412. X                npaths++;
  413. X            }
  414. X            else
  415. X            {
  416. X                printf("too many filenames to send\n");
  417. X                exit(255);
  418. X            }
  419. X        }
  420. X    }
  421. X
  422. X    if(sending_flag == -1)
  423. X    {
  424. X        printf("no -r or -s\n");
  425. X        exit(255);
  426. X    }
  427. X
  428. X    if((npaths < 1) && sending_flag)
  429. X        exit(253);
  430. X
  431. X    if(npaths && !sending_flag)
  432. X        exit(255);
  433. X
  434. X    if(log_packets)
  435. X    {
  436. X        char log_packets_name[64];
  437. X        FILE *ftmp;
  438. X        int iargv;
  439. X        sprintf(log_packets_name,"/tmp/sea%05d.plog",getpid());
  440. X        unlink(log_packets_name);
  441. X        ftmp = fopen(log_packets_name,"w");
  442. X        fclose(ftmp);
  443. X        log_packets = open(log_packets_name,O_WRONLY,0644);
  444. X        if(log_packets < 0)
  445. X            log_packets = 0;
  446. X        else
  447. X        {
  448. X            write(log_packets,"exec: ",6);
  449. X            for(iargv = 0; iargv < gargc; iargv++)
  450. X            {
  451. X                write(log_packets,gargv[iargv],strlen(gargv[iargv]));
  452. X                write(log_packets," ",1);
  453. X            }
  454. X            write(log_packets,"\n",1);
  455. X        }
  456. X    }
  457. X
  458. X    sprintf(s128,"ecusea %s",revision);
  459. X    report_init(s128);
  460. X    report_top_line("System Enhancement Associates");
  461. X    signal(SIGHUP,cancel_transaction);
  462. X    signal(SIGQUIT,cancel_transaction);
  463. X    signal(SIGINT,cancel_transaction);
  464. X    signal(SIGTERM,cancel_transaction);
  465. X#if    defined(SIGSTOP)
  466. X    /*
  467. X     * call Roto-Rooter on POSIX plots
  468. X     */
  469. X    signal(SIGSTOP,SIG_IGN);
  470. X    signal(SIGTSTP,SIG_IGN);
  471. X    signal(SIGCONT,SIG_IGN);
  472. X    signal(SIGTTIN,SIG_IGN);
  473. X    signal(SIGTTOU,SIG_IGN);
  474. X#endif
  475. X
  476. X    ioctl(iofd,TCGETA,&tio0);
  477. X    tio = tio0;
  478. X
  479. X    tio.c_oflag = 0;
  480. X    tio.c_cflag &= ~PARENB;
  481. X    tio.c_cflag &= ~CSIZE;
  482. X    tio.c_cflag |= CS8;
  483. X
  484. X    /*
  485. X     * learn tick rate for various timers
  486. X     */
  487. X    init_Nap();
  488. X
  489. X    baud_rate = getspeed(tio.c_cflag);
  490. X    ioctl(iofd,TCSETA,&tio);
  491. X    report_line(baud_rate,"RAW");
  492. X
  493. X    switch(sending_flag)
  494. X    {
  495. X        case 0:                /* receive files */
  496. X            while(receive_file() != NULL)
  497. X                Nap(1000L);
  498. X            ok = (rf_done == 1);
  499. X            break;
  500. X
  501. X        case 1:                /* send files */
  502. X            ipaths = 0;
  503. X            while(ipaths < npaths)
  504. X            {
  505. X                if(!(ok = send_file(paths[ipaths])))
  506. X                    break;
  507. X                Nap(1000L);
  508. X                ipaths++;
  509. X            }
  510. X            if(ok)        /* no errors, send end marker */
  511. X                send_file("");
  512. X            report_str("end of transfer",0);
  513. X            break;
  514. X    }
  515. X
  516. X    ioctl(iofd,TCSETA,&tio0);
  517. X    report_line(baud_rate,"NORMAL");
  518. X    report_uninit();
  519. X    exit(ok ? 0 : exit_code);    /* and return error status */
  520. X
  521. X}    /* end of main */
  522. X
  523. SHAR_EOF
  524. echo 'File sea/ecusea.c is complete' &&
  525. chmod 0644 sea/ecusea.c ||
  526. echo 'restore of sea/ecusea.c failed'
  527. Wc_c="`wc -c < 'sea/ecusea.c'`"
  528. test 37329 -eq "$Wc_c" ||
  529.     echo 'sea/ecusea.c: original size 37329, current size' "$Wc_c"
  530. rm -f _shar_wnt_.tmp
  531. fi
  532. # ============= sea/scurses.c ==============
  533. if test -f 'sea/scurses.c' -a X"$1" != X"-c"; then
  534.     echo 'x - skipping sea/scurses.c (File already exists)'
  535.     rm -f _shar_wnt_.tmp
  536. else
  537. > _shar_wnt_.tmp
  538. echo 'x - extracting sea/scurses.c (Text)'
  539. sed 's/^X//' << 'SHAR_EOF' > 'sea/scurses.c' &&
  540. X/*+-------------------------------------------------------------------------
  541. X    scurses.c -- ecu file transfer program curses interface
  542. X
  543. X  000000000011111111112222222222333333333344444444445555555550
  544. X  012345678901234567890123456789012345678901234567890123456789
  545. X00.----------------------------------------------------------.
  546. X01|  SEAlink_6____  _39____________________________________  |
  547. X02|  File ### of ###: _38__________________________________  |
  548. X03|  File position:  _8______ length: _8______               |
  549. X04|  _55____________________________________________________ | transaction
  550. X05|  _55____________________________________________________ | last rx/tx hdr
  551. X06|  Comm I/O: rx _8______  tx _8______ bytes                |
  552. X07|  Baud rate: _5___ BINARY blklen: _____ comm mode: CBREAK |
  553. X08|  Time started: session: HH:MM:SS  this file: HH:MM:SS    |
  554. X09|                elpased: HH:MM:SS       time: HH:MM:SS    |
  555. X10|  Error counts: this file:  _4__  total: _6____           |
  556. X11|  _55____________________________________________________ |  err str
  557. X12|  _55____________________________________________________ |  comment str
  558. X13|  _55____________________________________________________ |  remote info
  559. X14`----------------------------------------------------------'
  560. X
  561. X  Defined functions:
  562. X    clear_area(w,row,col,len)
  563. X    clear_area_char(w,row,col,len,fillchar)
  564. X    get_elapsed_time(elapsed_secs)
  565. X    hhmmss(tod)
  566. X    report_error_count()
  567. X    report_file_byte_io(count)
  568. X    report_file_close()
  569. X    report_file_open_length(length)
  570. X    report_file_open_tod()
  571. X    report_file_rcv_started(filename,length,last_mod_time)
  572. X    report_file_send_open(filename,filestat)
  573. X    report_init(title)
  574. X    report_last_rxhdr(rptstr,error_flag)
  575. X    report_last_txhdr(rptstr,error_flag)
  576. X    report_line(baud_rate,mode)
  577. X    report_protocol_crc_type(str)
  578. X    report_rx_ind(status)
  579. X    report_rx_tx_count()
  580. X    report_rxpos(pos)
  581. X    report_str(rptstr,error_flag)
  582. X    report_top_line(topstr)
  583. X    report_transaction(str)
  584. X    report_tx_ind(status)
  585. X    report_txpos(pos)
  586. X    report_uninit()
  587. X    vanilla_ruling()
  588. X
  589. X------------------------------------------------------------------------*/
  590. X/*+:EDITS:*/
  591. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  592. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  593. X/*:04-24-1992-21:15-wht@n4hgf-sort out vannilla vs. at ruling */
  594. X/*:02-09-1992-16:08-root@n4hgf-ruling characters only on  SCO (tcap curses) */
  595. X/*:08-28-1991-14:08-wht@n4hgf2-SVR4 cleanup by aega84!lh */
  596. X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
  597. X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
  598. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  599. X
  600. X#include "../ecucurses.h"
  601. X#include "../ecu_types.h"
  602. X#include "../ecu_stat.h"
  603. X#include <ctype.h>
  604. X#include <signal.h>
  605. X#include <time.h>
  606. X#include <sys/timeb.h>
  607. X
  608. X#if defined(M_SYSV)
  609. X#   include <sys/machdep.h>
  610. X#else
  611. X#if defined(ISC) || defined(SVR4)
  612. X#  include <sys/at_ansi.h>
  613. X#  include <sys/kd.h>
  614. X#endif
  615. X#endif
  616. X
  617. X#include "../pc_scr.h"
  618. X
  619. X#ifdef USE_PROTOS
  620. X# include "protos.h"
  621. X#endif
  622. X
  623. Xlong time();
  624. Xextern char *tzname[];
  625. Xstruct tm *localtime();
  626. X
  627. X#define WIN_LINES    15
  628. X#define WIN_COLS    60
  629. X#define WIN_TOPY    2
  630. X#define WIN_LEFTX    8
  631. X
  632. Xextern char curr_dir[];
  633. Xextern char s128[];
  634. Xextern int Filcnt;
  635. Xextern int Restricted;
  636. Xextern int sending_flag;    /* send == 1, receive == 0 */
  637. Xextern int npaths;
  638. Xextern long rxpos;
  639. Xextern int log_packets;
  640. X
  641. XWINDOW    *win;
  642. Xint (*original_sigint_handler)();
  643. Xint (*original_sigquit_handler)();
  644. Xint (*original_sigterm_handler)();
  645. Xint curses_installed = 0;        /* curses not yet active */
  646. Xint this_file_errors = 0;
  647. Xint total_errors = 0;
  648. Xlong current_seconds;
  649. Xlong start_seconds;
  650. Xlong elapsed_seconds;
  651. Xunsigned long total_data_chars_xfered = 0L;
  652. X
  653. Xunsigned char sTL = at_TL;
  654. Xunsigned char sTR = at_TR;
  655. Xunsigned char sBL = at_BL;
  656. Xunsigned char sBR = at_BR;
  657. Xunsigned char sLT = at_LT;
  658. Xunsigned char sRT = at_RT;
  659. Xunsigned char sVR = at_VR;
  660. Xunsigned char sHR = at_HR;
  661. X
  662. Xchar *win_template[] =
  663. X{
  664. X/*00000000001111111111222222222233333333334444444444555555555 */
  665. X/*01234567890123456789012345678901234567890123456789012345678 */
  666. X/*.----------------------------------------------------------. */
  667. X  "  SEAlink                                                 ",    /* 1 */
  668. X  "  File ### of ###: _____________________________________  ",    /* 2 */
  669. X  "  File position:  ________ length: ________               ",    /* 3 */
  670. X  "                                                          ",    /* 4 */
  671. X  "  tx: ______________________  rx: ______________________  ",    /* 5 */
  672. X  "  Comm I/O: rx ________  tx ________ bytes                ",    /* 6 */
  673. X  "  Baud rate: _____ BINARY blklen: 128   comm mode: ______ ",    /* 7 */
  674. X  "  Time started: session: --:--:--  this file: --:--:--    ",    /* 8 */
  675. X  "                elapsed: --:--:--    current: --:--:--    ",    /* 9 */
  676. X  "  Error counts: this file:  ____  total: ______           ",    /* 10 */
  677. X  "                                                          ",    /* 11 */
  678. X  "                                                          ",    /* 12 */
  679. X  "                                                          ",    /* 13 */
  680. X/*`----------------------------------------------------------' */
  681. X(char *)0
  682. X};
  683. X
  684. X/*+-------------------------------------------------------------------------
  685. X    vanilla_ruling() - use ordinary ruling characters
  686. X--------------------------------------------------------------------------*/
  687. Xvoid
  688. Xvanilla_ruling()
  689. X{
  690. X    sTL = vanilla_TL;
  691. X    sTR = vanilla_TR;
  692. X    sBL = vanilla_BL;
  693. X    sBR = vanilla_BR;
  694. X    sLT = vanilla_LT;
  695. X    sRT = vanilla_RT;
  696. X    sVR = vanilla_VR;
  697. X    sHR = vanilla_HR;
  698. X
  699. X}    /* end of vanilla_ruling */
  700. X
  701. X/*+-----------------------------------------------------------------------
  702. X    char *get_elapsed_time(elapsed_secs)
  703. X    hh:mm:ss returned
  704. X  static string address is returned
  705. X------------------------------------------------------------------------*/
  706. Xchar *get_elapsed_time(elapsed_secs)
  707. Xlong elapsed_secs;
  708. X{
  709. X    static char elapsed_time_str[10];
  710. X    long hh,mm,ss;
  711. X
  712. X    hh = elapsed_secs / 3600;
  713. X    elapsed_secs -= hh * 3600;
  714. X    mm = elapsed_secs / 60L;
  715. X    elapsed_secs -= mm * 60L;
  716. X    ss = elapsed_secs;
  717. X
  718. X    sprintf(elapsed_time_str,"%02ld:%02ld:%02ld",hh,mm,ss);
  719. X    return(elapsed_time_str);
  720. X}    /* end of get_elapsed_time */
  721. X
  722. X/*+-----------------------------------------------------------------------
  723. X    char *hhmmss(tod) - get time of day in form "hh:mm:ss"
  724. X
  725. X  static string address is returned
  726. X  if tod != (char *)0, time is returned there too
  727. X------------------------------------------------------------------------*/
  728. Xchar *
  729. Xhhmmss(tod)
  730. Xchar *tod;
  731. X{
  732. X    long cur_time = 0;
  733. X    struct tm *lt;            /* local time */
  734. X    static char tod_str[32];
  735. X
  736. X    cur_time = time((long *)0);
  737. X    lt = localtime(&cur_time);
  738. X
  739. X    sprintf(tod_str,"%02d:%02d:%02d",lt->tm_hour,lt->tm_min,lt->tm_sec);
  740. X
  741. X    if(tod != (char *)0)
  742. X        strcpy(tod,tod_str);
  743. X
  744. X    return(tod_str);
  745. X
  746. X}    /* end of hhmmss */
  747. X
  748. X/*+-------------------------------------------------------------------------
  749. X    clear_area(w,row,col,len)
  750. X--------------------------------------------------------------------------*/
  751. Xclear_area(w,row,col,len)
  752. XWINDOW    *w;
  753. Xint row;
  754. Xint col;
  755. Xint len;
  756. X{
  757. X    wmove(w,row,col);
  758. X    while(len-- > 0)
  759. X        waddch(w,' ');
  760. X    wmove(w,row,col);
  761. X
  762. X}    /* end of clear_area */
  763. X
  764. X/*+-------------------------------------------------------------------------
  765. X    clear_area_char(w,row,col,len,fillchar)
  766. X--------------------------------------------------------------------------*/
  767. Xclear_area_char(w,row,col,len,fillchar)
  768. XWINDOW    *w;
  769. Xint row;
  770. Xint col;
  771. Xint len;
  772. Xchar fillchar;
  773. X{
  774. X    wmove(w,row,col);
  775. X    while(len-- > 0)
  776. X        waddch(w,fillchar);
  777. X    wmove(w,row,col);
  778. X
  779. X}    /* end of clear_area_char */
  780. X
  781. X/*+-------------------------------------------------------------------------
  782. X    report_top_line(topstr)
  783. X   top line: row 1 col 18 length 39
  784. X--------------------------------------------------------------------------*/
  785. Xvoid
  786. Xreport_top_line(topstr)
  787. Xchar *topstr;
  788. X{
  789. Xchar s42[42];
  790. X    clear_area(win,1,18,39);
  791. X    if(strlen(topstr) < 39)
  792. X        waddstr(win,topstr);
  793. X    else
  794. X    {
  795. X        strncpy(s42,topstr,39);
  796. X        s42[39] = 0;
  797. X        waddstr(win,s42);
  798. X    }
  799. X}    /* end of report_top_line */
  800. X
  801. X/*+-------------------------------------------------------------------------
  802. X    report_protocol_crc_type(str)
  803. X
  804. X  protocol crc type:  row 1 col 10 length 6
  805. X--------------------------------------------------------------------------*/
  806. Xreport_protocol_crc_type(str)
  807. Xregister char *str;
  808. X{
  809. Xchar s8[8];
  810. X
  811. X    if(strlen(str) > 6)
  812. X    {
  813. X        strncpy(s8,str,6);
  814. X        s8[6] = 0;
  815. X        str = s8;
  816. X    }
  817. X    clear_area(win,1,10,6);
  818. X    waddstr(win,str);
  819. X    wrefresh(win);
  820. X    if(log_packets)
  821. X    {
  822. X        write(log_packets,"chk:  ",6);
  823. X        write(log_packets,str,strlen(str));
  824. X        write(log_packets,"\n",1);
  825. X    }
  826. X
  827. X}    /* end of report_protocol_crc_type */
  828. X
  829. X/*+-------------------------------------------------------------------------
  830. X    report_error_count()
  831. X    DOES NOT PERFORM A REFRESH CYCLE
  832. X  this file: row 10 col 29 len 4
  833. X  total:     row 10 col 42 len 6
  834. X--------------------------------------------------------------------------*/
  835. Xvoid
  836. Xreport_error_count()
  837. X{
  838. X    char tmp[16];
  839. X
  840. X    clear_area(win,10,29,4);
  841. X    sprintf(tmp,"%4d",this_file_errors);
  842. X    waddstr(win,tmp);
  843. X
  844. X    clear_area(win,10,42,6);
  845. X    sprintf(tmp,"%6d",total_errors);
  846. X    waddstr(win,tmp);
  847. X    wrefresh(win);
  848. X
  849. X}    /* end of report_error_count */
  850. X
  851. X/*+-------------------------------------------------------------------------
  852. X    report_uninit()
  853. X--------------------------------------------------------------------------*/
  854. Xvoid
  855. Xreport_uninit()
  856. X{
  857. Xfloat total = (float)total_data_chars_xfered;
  858. X
  859. X    if(curses_installed)
  860. X    {
  861. X        if((total_data_chars_xfered != 0L) && (elapsed_seconds != 0L))
  862. X        {
  863. X            sprintf(s128,"Data xfer rate ~= %6.0f chars/sec",
  864. X                total / (float)elapsed_seconds);
  865. X            if(log_packets)
  866. X            {
  867. X                write(log_packets,"info: ",6);
  868. X                write(log_packets,s128,strlen(s128));
  869. X                write(log_packets,"\n",1);
  870. X            }
  871. X            report_top_line(s128);
  872. X        }
  873. X        report_file_byte_io(0L);
  874. X        report_rx_tx_count();
  875. X        wmove(win,WIN_LINES - 1,WIN_COLS - 1);
  876. X        wrefresh(win);
  877. X        endwin();
  878. X        fprintf(stderr,"\r\n\r\n\r\n");
  879. X        fflush(stderr);
  880. X        curses_installed = 0;
  881. X    }
  882. X
  883. X}    /* end of report_uninit */
  884. X
  885. X/*+-------------------------------------------------------------------------
  886. X    report_init(title)
  887. X--------------------------------------------------------------------------*/
  888. Xvoid
  889. Xreport_init(title)
  890. Xchar *title;
  891. X{
  892. Xregister int itmp;
  893. X#if defined(CONS_GET)
  894. Xint monitor_type;
  895. X#endif
  896. X
  897. X    if(curses_installed)
  898. X        return;
  899. X
  900. X#if defined(M_SYSV)
  901. X    if(ioctl(0,CONS_GET,&monitor_type) < 0)    /* not multiscreen */
  902. X#ifdef M_SYSV    /* SCO non AT console */
  903. X        vanilla_ruling();
  904. X#endif
  905. X#else
  906. X    vanilla_ruling();
  907. X#endif
  908. X
  909. X    initscr();
  910. X    crmode();
  911. X    noecho();
  912. X    nonl();
  913. X    clear();
  914. X    curses_installed = 1;
  915. X    win = newwin(WIN_LINES,WIN_COLS,WIN_TOPY,WIN_LEFTX);
  916. X    box(win,sVR,sHR);
  917. X#ifndef SVR4
  918. X    wmove(win,0,0); waddch(win,sTL);
  919. X    wmove(win,win->_maxy - 1,0); waddch(win,sBL);
  920. X    wmove(win,win->_maxy - 1,win->_maxx - 1); waddch(win,sBR);
  921. X    wmove(win,0,win->_maxx - 1); waddch(win,sTR);
  922. X#endif
  923. X    wmove(win,0,2);
  924. X    wstandout(win);
  925. X    waddch(win,'[');
  926. X    waddch(win,' ');
  927. X    waddstr(win,title);
  928. X    waddch(win,' ');
  929. X    waddch(win,']');
  930. X    wstandend(win);
  931. X#ifdef SVR4
  932. X    whline(win, (unsigned long)(sHR & 0x00ff), 2);
  933. X    wmove(win,0, 8 + strlen(title));
  934. X#else
  935. X    waddch(win,sHR);
  936. X    waddch(win,sHR);
  937. X#endif
  938. X    waddstr(win," dir: ");
  939. X    waddstr(win,curr_dir);
  940. X    waddch(win,' ');
  941. X
  942. X    itmp = 0;
  943. X    while(1)
  944. X    {
  945. X        if(win_template[itmp] == (char *)0)
  946. X            break;
  947. X        wmove(win,itmp + 1,1);
  948. X        waddstr(win,win_template[itmp++]);
  949. X    }
  950. X    if(sending_flag)
  951. X    {
  952. X        clear_area(win,2,15,3);
  953. X        sprintf(s128,"%3d",npaths);
  954. X        waddstr(win,s128);
  955. X    }
  956. X    else    /* ecurz */
  957. X    {
  958. X        clear_area(win,2,11,8);    /* clear "of ###" */
  959. X        waddstr(win,":");
  960. X    }
  961. X
  962. X    clear_area(win,1,11,47);
  963. X    report_error_count();
  964. X    clear_area(win,8,26,8);        /* starting time */
  965. X    waddstr(win,hhmmss((char *)0));
  966. X    start_seconds = time((long *)0);
  967. X    current_seconds = start_seconds;
  968. X
  969. X    wrefresh(win);
  970. X
  971. X}    /* end of report_init */
  972. X
  973. X/*+-------------------------------------------------------------------------
  974. X    report_rx_ind(status)
  975. X--------------------------------------------------------------------------*/
  976. Xvoid
  977. Xreport_rx_ind(status)
  978. Xint status;
  979. X{
  980. X    wmove(win,1,54);
  981. X    waddch(win,(status) ? 'R' : ' ');
  982. X    wmove(win,1,54);
  983. X    wrefresh(win);
  984. X}    /* end of report_rx_ind */
  985. X
  986. X/*+-------------------------------------------------------------------------
  987. X    report_tx_ind(status)
  988. X--------------------------------------------------------------------------*/
  989. Xvoid
  990. Xreport_tx_ind(status)
  991. Xint status;
  992. X{
  993. X    wmove(win,1,56);
  994. X    waddch(win,(status) ? 'T' : ' ');
  995. X    wmove(win,1,56);
  996. X    wrefresh(win);
  997. X}    /* end of report_tx_ind */
  998. X
  999. X/*+-------------------------------------------------------------------------
  1000. X    report_rx_tx_count()
  1001. X
  1002. X  rx char count: row 6 col 16 length 8 unsigned long
  1003. X  tx char count: row 6 col 29 length 8 unsigned long
  1004. X  now time of day: row 1 col 50 length 8 hh:mm:ss
  1005. X  This procedure may be counted upon to perform wrefresh(win)
  1006. X
  1007. Xelapsed time row 9 col 26 length 8
  1008. Xcurrent tod row 9 col 47 length 8
  1009. X--------------------------------------------------------------------------*/
  1010. Xreport_rx_tx_count()
  1011. X{
  1012. X    extern unsigned long rx_char_count;
  1013. X    extern unsigned long tx_char_count;
  1014. X
  1015. X    register char *cptr;
  1016. X
  1017. X    sprintf(s128,"%8ld",rx_char_count);
  1018. X    wmove(win,6,16);
  1019. X    waddstr(win,s128);
  1020. X    sprintf(s128,"%8ld",tx_char_count);
  1021. X    wmove(win,6,29);
  1022. X    waddstr(win,s128);
  1023. X
  1024. X    /* now time of day */
  1025. X    clear_area(win,9,47,8);
  1026. X    cptr = hhmmss((char *)0);
  1027. X    waddstr(win,cptr);
  1028. X    current_seconds = time((long *)0);
  1029. X    elapsed_seconds = current_seconds - start_seconds;
  1030. X    cptr = get_elapsed_time(elapsed_seconds);
  1031. X    clear_area(win,9,26,8);
  1032. X    waddstr(win,cptr);
  1033. X    wrefresh(win);        /* calling procs expect this to occur always */
  1034. X
  1035. X}    /* end of report_rx_tx_count */
  1036. X
  1037. X/*+-------------------------------------------------------------------------
  1038. X    report_line(baud_rate,mode)
  1039. X--------------------------------------------------------------------------*/
  1040. Xvoid
  1041. Xreport_line(baud_rate,mode)
  1042. Xunsigned baud_rate;
  1043. Xchar *mode;
  1044. X{
  1045. Xchar s16[16];
  1046. X    wmove(win,7,14);
  1047. X    sprintf(s16,"%5u",baud_rate);
  1048. X    waddstr(win,s16);
  1049. X    clear_area(win,7,52,6);
  1050. X    waddstr(win,mode);
  1051. X    wrefresh(win);
  1052. X}    /* end of report_line */
  1053. X
  1054. X/*+-------------------------------------------------------------------------
  1055. X    report_rxpos(pos) row 3 col 19 len 8
  1056. X--------------------------------------------------------------------------*/
  1057. Xvoid
  1058. Xreport_rxpos(pos)
  1059. Xlong pos;
  1060. X{
  1061. Xchar tmp[16];
  1062. Xchar refr;
  1063. X
  1064. X    if(rdchk(0))
  1065. X    {
  1066. X        read(0,&refr,1);
  1067. X        if(refr == 0x0C || refr == 0x012)    /* ^L or ^R */
  1068. X        {
  1069. X            write(2,"\033[2J",4);
  1070. X            Nap((long)60);
  1071. X            touchwin(stdscr);
  1072. X            wrefresh(stdscr);
  1073. X            touchwin(win);
  1074. X            wrefresh(win);
  1075. X        }
  1076. X    }
  1077. X
  1078. X    if((pos > 99999999L) || (pos < 0L))
  1079. X        return;
  1080. X
  1081. X    sprintf(tmp,"%8lu",pos);
  1082. X    wmove(win,3,19);
  1083. X    waddstr(win,tmp);
  1084. X    wrefresh(win);
  1085. X    report_rx_tx_count();    /* which will do a refresh */
  1086. X}    /* end of report_rxpos */
  1087. X
  1088. X/*+-------------------------------------------------------------------------
  1089. X    report_txpos(pos)
  1090. X--------------------------------------------------------------------------*/
  1091. Xvoid
  1092. Xreport_txpos(pos)
  1093. Xlong pos;
  1094. X{
  1095. X    report_rxpos(pos);
  1096. X}    /* end of report_txpos */
  1097. X
  1098. X/*+-------------------------------------------------------------------------
  1099. X    report_last_txhdr(rptstr,error_flag)
  1100. X    5,7,22
  1101. X--------------------------------------------------------------------------*/
  1102. Xvoid
  1103. Xreport_last_txhdr(rptstr,error_flag)
  1104. Xregister char *rptstr;
  1105. Xint error_flag;
  1106. X{
  1107. Xchar s24[24];
  1108. X
  1109. X    if(log_packets)
  1110. X    {
  1111. X        write(log_packets,"tx:   ",6);
  1112. X        write(log_packets,rptstr,strlen(rptstr));
  1113. X        write(log_packets,"\n",1);
  1114. X    }
  1115. X
  1116. X    if(strlen(rptstr) > 22)
  1117. X    {
  1118. X        strncpy(s24,rptstr,22);
  1119. X        s24[23] = 0;
  1120. X        rptstr = s24;
  1121. X    }
  1122. X    clear_area(win,5,7,22);
  1123. X    waddstr(win,rptstr);
  1124. X    wrefresh(win);
  1125. X
  1126. X    if(error_flag)
  1127. X    {
  1128. X        ++this_file_errors;
  1129. X        ++total_errors;
  1130. X        report_error_count();
  1131. X    }
  1132. X}    /* end of report_last_txhdr */
  1133. X
  1134. X/*+-------------------------------------------------------------------------
  1135. X    report_last_rxhdr(rptstr,error_flag)
  1136. X    5,35,22
  1137. X--------------------------------------------------------------------------*/
  1138. Xvoid
  1139. Xreport_last_rxhdr(rptstr,error_flag)
  1140. Xregister char *rptstr;
  1141. Xint error_flag;
  1142. X{
  1143. Xchar s24[24];
  1144. Xextern int log_packets;
  1145. X
  1146. X    if(log_packets)
  1147. X    {
  1148. X        write(log_packets,"rx: ",4);
  1149. X        write(log_packets,(error_flag) ? "E " : "  ",2);
  1150. X        write(log_packets,rptstr,strlen(rptstr));
  1151. X        write(log_packets,"\n",1);
  1152. X    }
  1153. X
  1154. X    if(strlen(rptstr) > 22)
  1155. X    {
  1156. X        strncpy(s24,rptstr,22);
  1157. X        s24[23] = 0;
  1158. X        rptstr = s24;
  1159. X    }
  1160. X    clear_area(win,5,35,22);
  1161. X    waddstr(win,rptstr);
  1162. X    wrefresh(win);
  1163. X
  1164. X    if(error_flag)
  1165. X    {
  1166. X        ++this_file_errors;
  1167. X        ++total_errors;
  1168. X        report_error_count();
  1169. X    }
  1170. X
  1171. X}    /* end of report_last_rxhdr */
  1172. X
  1173. X/*+-------------------------------------------------------------------------
  1174. X    report_str(rptstr,error_flag) row 11/12 col 3 len 55
  1175. X
  1176. X  error_flag == 0 for status/progress message
  1177. X             == 1 for bump error count, unless rptstr is null
  1178. X                  in which case, merely clear error string area
  1179. X             == 2 write string on bottom line (not an error)
  1180. X             == 3 write string on transaction line (not an error)
  1181. X             == -1 use error line but do not bump error count
  1182. X--------------------------------------------------------------------------*/
  1183. Xvoid
  1184. Xreport_str(rptstr,error_flag)
  1185. Xregister char *rptstr;
  1186. Xint error_flag;
  1187. X{
  1188. Xchar s60[60];
  1189. Xextern int log_packets;
  1190. X
  1191. X    if(strlen(rptstr) > 55)
  1192. X    {
  1193. X        strncpy(s60,rptstr,55);
  1194. X        s60[56] = 0;
  1195. X        rptstr = s60;
  1196. X    }
  1197. X
  1198. X    switch(error_flag)
  1199. X    {
  1200. X        case 0:
  1201. X            clear_area(win,12,3,55);
  1202. X            break;
  1203. X        case 1:
  1204. X            ++this_file_errors;
  1205. X            ++total_errors;
  1206. X            report_error_count();
  1207. X        case -1:
  1208. X            clear_area(win,11,3,55);
  1209. X            break;
  1210. X        case 2:
  1211. X            clear_area(win,13,3,55);
  1212. X            break;
  1213. X        case 3:
  1214. X            clear_area(win,4,3,55);
  1215. X            break;
  1216. X    }
  1217. X
  1218. X    waddstr(win,rptstr);
  1219. X    wrefresh(win);
  1220. X
  1221. X    if(log_packets)
  1222. X    {
  1223. X        write(log_packets,"info: ",6);
  1224. X        sprintf(s60,"%2d ",error_flag);
  1225. X        write(log_packets,s60,3);
  1226. X        write(log_packets,rptstr,strlen(rptstr));
  1227. X        write(log_packets,"\n",1);
  1228. X    }
  1229. X
  1230. X}    /* end of report_str */
  1231. X
  1232. X/*+-------------------------------------------------------------------------
  1233. X    report_transaction()
  1234. X--------------------------------------------------------------------------*/
  1235. Xvoid
  1236. Xreport_transaction(str)
  1237. Xchar *str;
  1238. X{
  1239. X    report_str(str,3);
  1240. X}    /* end of report_transaction */
  1241. X
  1242. X/*+-------------------------------------------------------------------------
  1243. X    report_file_open_tod() -- time of start of this file
  1244. X
  1245. X  this file open time: row 8 col 47 length 8
  1246. X--------------------------------------------------------------------------*/
  1247. Xvoid
  1248. Xreport_file_open_tod()
  1249. X{
  1250. X    clear_area(win,8,47,8);
  1251. X    waddstr(win,hhmmss((char *)0));
  1252. X    wrefresh(win);
  1253. X}    /* end of report_file_open_tod */
  1254. X
  1255. X/*+-------------------------------------------------------------------------
  1256. X    report_file_open_length(long_length)
  1257. X  length:   row 3 col 36 len  8
  1258. X--------------------------------------------------------------------------*/
  1259. Xreport_file_open_length(length)
  1260. Xlong length;
  1261. X{
  1262. X    clear_area(win,3,36,8);
  1263. X    if(length <= 0)
  1264. X        waddstr(win,"unknown");
  1265. X    else
  1266. X    {
  1267. X        sprintf(s128,"%8lu",length);
  1268. X        waddstr(win,s128);
  1269. X    }
  1270. X    wrefresh(win);
  1271. X}    /* end of report_file_open_length */
  1272. X
  1273. X/*+-------------------------------------------------------------------------
  1274. X    report_file_send_open(filename,filestat)
  1275. X
  1276. X  filename: row 2 col 20 len 38
  1277. X  number:   row 2 col 8 len 3
  1278. X  length:   row 3 col 36 len  8
  1279. X  mode:     row 3 col 46 len 10
  1280. X  time of start of this file: row 4 col 47 length 8 hh:mm:ss
  1281. X--------------------------------------------------------------------------*/
  1282. Xvoid
  1283. Xreport_file_send_open(filename,filestat)
  1284. Xchar *filename;
  1285. Xstruct stat *filestat;
  1286. X{
  1287. Xchar s50[50];
  1288. Xregister char *cptr = filename;
  1289. X
  1290. X    if(log_packets)
  1291. X    {
  1292. X        write(log_packets,"file: ",6);
  1293. X        write(log_packets,filename,strlen(filename));
  1294. X        write(log_packets,"\n",1);
  1295. X    }
  1296. X
  1297. X    /* number */
  1298. X    clear_area(win,2,8,3);
  1299. X    sprintf(s50,"%3d",Filcnt);
  1300. X    waddstr(win,s50);
  1301. X
  1302. X    /* filename */
  1303. X    if(strlen(filename) > 38)
  1304. X    {
  1305. X        strncpy(s50,filename,38);
  1306. X        s50[39] = 0;
  1307. X        cptr = s50;
  1308. X    }
  1309. X    clear_area(win,2,20,38);
  1310. X    waddstr(win,cptr);
  1311. X
  1312. X#if defined(LOG_XFER)
  1313. X    sprintf(s128,"sending %s",filename);
  1314. X    ecu_log_event(getppid(),s128);
  1315. X#endif
  1316. X
  1317. X    /* length */
  1318. X    report_file_open_length(filestat->st_size);
  1319. X
  1320. X    /* time of start of this file */
  1321. X    report_file_open_tod();
  1322. X
  1323. X    this_file_errors = 0;
  1324. X    report_error_count();
  1325. X}    /* end of report_file_send_open */
  1326. X
  1327. X/*+-------------------------------------------------------------------------
  1328. X    report_file_rcv_started(filename,length,last_mod_time)
  1329. X
  1330. X  filename: row 2 col 7 len 50
  1331. X  length:   row 3 col 36 len  8 if not xmodem
  1332. X  time of start of this file: row 4 col 47 length 8 hh:mm:ss
  1333. X--------------------------------------------------------------------------*/
  1334. Xreport_file_rcv_started(filename,length,last_mod_time)
  1335. Xchar *filename;
  1336. Xlong length;                    /* if < 0, "UNKNOWN" */
  1337. Xlong last_mod_time;            /* not currently displayed */
  1338. X{
  1339. Xregister char *cptr;
  1340. Xchar s50[50];
  1341. X
  1342. X    if(log_packets)
  1343. X    {
  1344. X        write(log_packets,"file: ",6);
  1345. X        write(log_packets,filename,strlen(filename));
  1346. X        write(log_packets,"\n",1);
  1347. X    }
  1348. X
  1349. X    /* filename */
  1350. X    if(strlen(filename) > 38)
  1351. X    {
  1352. X        strncpy(s50,filename,38);
  1353. X        s50[39] = 0;
  1354. X        cptr = s50;
  1355. X    }
  1356. X    else
  1357. X        cptr = filename;
  1358. X
  1359. X#if defined(LOG_XFER)
  1360. X    sprintf(s128,"receiving %s",filename);
  1361. X    ecu_log_event(getppid(),s128);
  1362. X#endif
  1363. X
  1364. X    clear_area(win,2,20,38);
  1365. X    waddstr(win,cptr);
  1366. X
  1367. X    /* file number */
  1368. X    clear_area(win,2,8,3);
  1369. X    sprintf(s50,"%3d",Filcnt);    /* rz uses as file number 1-n */
  1370. X    waddstr(win,s50);
  1371. X
  1372. X/* if remote sender provides a file count, display it */
  1373. X    if(npaths)
  1374. X    {
  1375. X        clear_area(win,2,12,7);    /* clear "of ###" */
  1376. X        sprintf(s50,"of %3d:",npaths);
  1377. X        waddstr(win,s50);
  1378. X    }
  1379. X
  1380. X    /* length */
  1381. X    report_file_open_length(length);
  1382. X
  1383. X    /* time of start of this file */
  1384. X    report_file_open_tod();
  1385. X
  1386. X    this_file_errors = 0;
  1387. X    report_error_count();
  1388. X}    /* end of report_file_rcv_started */
  1389. X
  1390. X/*+-------------------------------------------------------------------------
  1391. X    report_file_close()
  1392. X--------------------------------------------------------------------------*/
  1393. Xvoid report_file_close()
  1394. X{
  1395. X    report_str("End of file",0);
  1396. X    wrefresh(win);
  1397. X
  1398. X}    /* end of report_file_close */
  1399. X
  1400. X/*+-------------------------------------------------------------------------
  1401. X    report_file_byte_io(count)
  1402. X--------------------------------------------------------------------------*/
  1403. Xreport_file_byte_io(count)
  1404. Xlong count;
  1405. X{
  1406. X
  1407. X    total_data_chars_xfered += (long)count;
  1408. X    if(total_data_chars_xfered)
  1409. X    {
  1410. X        sprintf(s128,"Total file bytes transferred: %lu",
  1411. X            total_data_chars_xfered);
  1412. X        report_str(s128,-1);
  1413. X    }
  1414. X
  1415. X}    /* end of report_file_byte_io */
  1416. X
  1417. X/* end of scurses.c */
  1418. X/* vi: set tabstop=4 shiftwidth=4: */
  1419. SHAR_EOF
  1420. chmod 0644 sea/scurses.c ||
  1421. echo 'restore of sea/scurses.c failed'
  1422. Wc_c="`wc -c < 'sea/scurses.c'`"
  1423. test 22195 -eq "$Wc_c" ||
  1424.     echo 'sea/scurses.c: original size 22195, current size' "$Wc_c"
  1425. rm -f _shar_wnt_.tmp
  1426. fi
  1427. # ============= sea/sealink.doc ==============
  1428. if test -f 'sea/sealink.doc' -a X"$1" != X"-c"; then
  1429.     echo 'x - skipping sea/sealink.doc (File already exists)'
  1430.     rm -f _shar_wnt_.tmp
  1431. else
  1432. > _shar_wnt_.tmp
  1433. echo 'x - extracting sea/sealink.doc (Text)'
  1434. sed 's/^X//' << 'SHAR_EOF' > 'sea/sealink.doc' &&
  1435. X                                     SEALINK
  1436. X
  1437. X                             File Transfer Protocol
  1438. X
  1439. X                                 9 February 1987
  1440. X
  1441. X
  1442. X
  1443. X          (C) COPYRIGHT 1986,87 by System Enhancement Associates, Inc.
  1444. X
  1445. X
  1446. X
  1447. X     This document describes briefly the  SEAlink  file  transfer  protocol
  1448. X     developers' package.  SEAlink is a sliding  window  protocol  that  is
  1449. X     fully  backwards compatible with XMODEM in all tested implementations.
  1450. X
  1451. X     The intent of SEAlink is to provide a file transfer protocol that does
  1452. X     not  suffer  from  propagation  delays,  such  as  are  introduced  by
  1453. X     satellite relays or packet switched  networks.  Actual  tests  of  the
  1454. X     enclosed  routines  has  shown  that  SEAlink  is capable of virtually
  1455. X     eliminating propagation delays and turnaround delays.  File  transfers
  1456. X     between New Jersey and Hawaii,  which normally suffer a degradation of
  1457. X     50% or more  due  to  satellite  relays,  proceed  as  fast  as  local
  1458. X     transfers.  Even transfers within the local exchange are speeded up by
  1459. X     up to 20% at 2400 baud by the elimination of turnaround delays.  Large
  1460. X     volume  tests  show  that SEAlink is capable of coming to within 2% of
  1461. X     the theoretical minimum time for data transfer.
  1462. X
  1463. X
  1464. X
  1465. X     The developers' package contains the following files:
  1466. X
  1467. X         SEALINK.DOC    This document.
  1468. X         SEALINK.C      A set of C routines for implementing SEAlink.
  1469. X         CLINK.EXE      A sample TTY program that implements SEAlink.
  1470. X
  1471. X
  1472. X
  1473. X     You are granted a license to use this code in your  programs,  and  to
  1474. X     adapt  it to your particular situation and needs,  subject only to the
  1475. X     following conditions:
  1476. X
  1477. X     1) You must refer to it as the SEAlink protocol,  and  you  must  give
  1478. X        credit to System Enhancement Associates.
  1479. X
  1480. X     2) If  you  modify  it in such a way that your version cannot converse
  1481. X        with the original code as supplied by us,  then you should refer to
  1482. X        it as "SEAlink derived",  or as a "variation of SEAlink",  or words
  1483. X        to that effect.
  1484. X
  1485. X     In short,  we're not asking for any money,  but we'd like to get  some
  1486. X     credit for our work.
  1487. X
  1488. X
  1489. X     This  document  is  not  meant  to  be  a  rigorous  definition of the
  1490. X     protocol.  The code provided should serve to document the details  and
  1491. X     fine  points  of  implementing SEAlink.  We will,  however,  present a
  1492. X     brief synopsis of how SEAlink adds sliding windows to XMODEM,  and why
  1493. X     XMODEM doesn't mind.
  1494. X
  1495. X     First of all,  SEAlink adds a block number to the ACK and NAK used  in
  1496. X     XMODEM.(1)  We  thus  create  "ACK/NAK  packets",  with  the following
  1497. X     structure:
  1498. X
  1499. X         Byte 0:   ACK, NAK, or C
  1500. X         Byte 1:   Block number
  1501. X         Byte 2:   One's compliment of block number
  1502. X
  1503. X     This is identical in form to the first three bytes of a  data  packet,
  1504. X     except that the SOH has been replaced with an ACK or NAK.(2)
  1505. X
  1506. X     From the receiver's point of view,  it does not matter if  the  trans-
  1507. X     mitter  is using sliding window or not.  The receiver simply sends ACK
  1508. X     and NAK packets as appropriate.  Any XMODEM driver tested to date will
  1509. X     simply ignore this excess data behind the ACK or NAK.
  1510. X
  1511. X     From the transmitter's point of view,  it just barely matters  if  the
  1512. X     receiver can handle sliding window.  The transmitter always acts as if
  1513. X     it  is  sending sliding window,  but varies the window size.  If it is
  1514. X     seeing valid block numbers and check values behind the  received  ACKs
  1515. X     and NAKs,  it sets the window size to six blocks.  Otherwise,  it sets
  1516. X     the  window  size  to  one  block.  The  result is that it only "sends
  1517. X     ahead" if the receiver can handle it.
  1518. X
  1519. X     It  should  be  a fairly simple matter to apply the underlying SEAlink
  1520. X     logic to almost any variant of XMODEM.
  1521. X
  1522. X
  1523. X     The  SEAlink  routines  provided  in  this package are also capable of
  1524. X     passing system dependent information,  such as true file size and time
  1525. X     of  last modification.  This data is passed in a special header block.
  1526. X     The header block looks exactly like any other block, except that it is
  1527. X     block number zero.
  1528. X
  1529. X     This is still backwards compatible with XMODEM,  as a SEAlink receiver
  1530. X     does  not  mind if block zero is missing,  and any XMODEM receiver yet
  1531. X     tested will regard block zero as a duplicate block and ACK it.
  1532. X
  1533. X     The data portion of block zero contains the following fields:
  1534. X
  1535. X
  1536. X         Offset    Size      Contents
  1537. X         ======    ====      ========
  1538. X
  1539. X            0        4       Original file length.
  1540. X            4        4       Date  and  time  file  was  last mofified,  in
  1541. X                             seconds since 1979.
  1542. X            8       17       Original  file  name,  as  a  null  terminated
  1543. X                             string.
  1544. X           25       15       Name  of  transmitting  program,   as  a  null
  1545. X                             terminated string.
  1546. X           40       88       Null filler and expansion area.
  1547. X
  1548. X
  1549. X     (1) XMODEM/CRC uses a "C" in place of  a  NAK  to  indicate  CRC  error
  1550. X         detection.  SEAlink  follows  this convention,  and supports either
  1551. X         checksum or CRC.  For brevity,  this document will use the term NAK
  1552. X         to mean either a true NAK (hex 15) or a C (hex 43).
  1553. X     (2) See previous footnote.
  1554. X
  1555. X     Any field which the transmitter cannot support should be  set  to  all
  1556. X     zeros.  Conversly,  the  receiver  should ignore any null fields.  The
  1557. X     receiver may ignore any field which he cannot support.
  1558. X
  1559. X
  1560. X
  1561. X     The  routines  enclosed  in  this package should be reasonably easy to
  1562. X     implement in your application.  We have attempted to exclude  compiler
  1563. X     dependent and system dependent logic from these routines.
  1564. X
  1565. X
  1566. X     You will need to alter our references to our communications driver  to
  1567. X     conform  to  your  own driver.  The communications related routines we
  1568. X     use are:
  1569. X
  1570. X         com_putc(c)         Output character c to comm port.
  1571. X
  1572. X         int com_getc(t)     Get character from comm port within  t  tenths
  1573. X                             of   a  second.   Return  EOF  if  time  limit
  1574. X                             expires.
  1575. X
  1576. X         com_dump()          Discard any pending output without sending it.
  1577. X
  1578. X
  1579. X     In  addition,  we  use  the  following  routines for controlling timed
  1580. X     loops:
  1581. X
  1582. X         long timerset(t)    Set a timer.  Returns a timer value which will
  1583. X                             expire in t tenths of a second.
  1584. X
  1585. X         int timeup(z)       Check a timer.  Returns true if  timer  z  has
  1586. X                             expired yet, or false otherwise.
  1587. X
  1588. X
  1589. X     These routines also make reference to the following functions for
  1590. X     system dependent information, which is optional:
  1591. X
  1592. X         filestat(name,&fs)  Read directory entry for  a  file  and  return
  1593. X                             system dependent information.
  1594. X
  1595. X         setstamp(f,dtg)     Set a file's date/time of last modification.
  1596. X
  1597. X
  1598. X
  1599. X
  1600. X     The SEAlink  implementation  provided  in  this  package  is  used  by
  1601. X     invoking the two primary routines:
  1602. X
  1603. X
  1604. X         int xmtfile(name)             /* transmit a file */
  1605. X         char *name;                   /* name of file to transmit */
  1606. X
  1607. X     This  routine is used to send a file.  One file is sent at a time.  If
  1608. X     the  name  is blank (name is null or *name points to a null),  then an
  1609. X     end of transmission marker is sent.
  1610. X
  1611. X     This routine returns a one if the file is successfully transmitted, or
  1612. X     a zero if a fatal error occurs.
  1613. X
  1614. X
  1615. X         char *rcvfile(name)           /* receive a file */
  1616. X         char *name;                   /* name of file (optional) */
  1617. X
  1618. X     This routine is used to receive a file.  One file is  received.  If  a
  1619. X     name is specified for the file,  then that name WILL be used,  and any
  1620. X     name  sent  by  the transmitter will be ignored.  If the name is blank
  1621. X     (name is null or *name points to a null),  then the  transmitter  must
  1622. X     provide a name for the file.
  1623. X
  1624. X     This routine returns a pointer to  the  name  of  the  file  that  was
  1625. X     received.  If the file transfer is not successful, then a null pointer
  1626. X     is returned.
  1627. X
  1628. X     The  pointer  returned  by  rcvfile()  points to a static data buffer.
  1629. X     This does not have to be freed (and should not be),  but  it  will  be
  1630. X     overwritten the next time rcvfile() is called.
  1631. X
  1632. X     The  rcvfile()  function  works  on a temporary file whose name is the
  1633. X     same as the final file,  but with a dash ("-") added at the beginning.
  1634. X     If  a  file  transfer  is  aborted,  then  this temporary file will be
  1635. X     retained.  An aborted file transfer will not harm a pre-existing  file
  1636. X     of the same name.
  1637. X
  1638. X
  1639. X
  1640. X     These  routines  can  be  used  for  either  single  or  multiple file
  1641. X     transfers.
  1642. X
  1643. X     To  send  multiple  files,  send  each  file one by one until either a
  1644. X     transmit fails or all files are sent.  If all  files  are  sent,  then
  1645. X     signal the end by calling xmtfile() with a null pointer.
  1646. X
  1647. X     To receive multiple files,  call rcvfile() repeatedly until it returns
  1648. X     a null pointer.
  1649. X
  1650. X
  1651. X
  1652. X     This  package includes a demonstration program named CLINK (pronounced
  1653. X     "clink"),  which is a  simple  TTY  program  for  doing  SEAlink  file
  1654. X     transfers.  CLINK  does  not  perform  any  sort of terminal emulation
  1655. X     whatsoever.  However,  she will make use of the ANSI.SYS screen driver
  1656. X     if you have it installed.
  1657. X
  1658. X
  1659. X     CLINK may be used in either of two ways: interactive mode or command
  1660. X     mode.
  1661. X
  1662. X     To use CLINK in the interactive mode, give the command "CLINK" with no
  1663. X     arguments.  Press  the  "ESCape"  key to give a command to CLINK.  The
  1664. X     command "?" (question mark) instructs CLINK to tell you what  commands
  1665. X     she understands.
  1666. X
  1667. X     To  use  CLINK  in the command mode,  give the command "CLINK" with an
  1668. X     argument.  There are three arguments you can give CLINK in the command
  1669. X     mode.  These are:
  1670. X
  1671. X      1) Receive files;  Do this with a command of the form:
  1672. X
  1673. X              CLINK R
  1674. X
  1675. X         CLINK  will  attempt  to receive one or more files from COM1,  and
  1676. X         will terminate as soon as all files  are  received,  or  when  the
  1677. X         transfer aborts.
  1678. X
  1679. X      2) Transmit files; Do this with a command of the form:
  1680. X
  1681. X              CLINK T <filename> ...
  1682. X
  1683. X         CLINK  will  attempt  to transmit the listed files over COM1,  and
  1684. X         will terminate as soon as all files are sent,  or the transfer  is
  1685. X         aborted.  <filename> may be one or more file names with or without
  1686. X         drive and path specifiers.  Wildcards may be used.
  1687. X
  1688. X      3) Give help;  If you type:
  1689. X
  1690. X              CLINK ?
  1691. X
  1692. X         or any invalid command,  CLINK will display a  brief  reminder  of
  1693. X         what arguments she understands in command mode.
  1694. X
  1695. X     In all cases, CLINK in the command mode will not alter the serial port
  1696. X     other than to set eight data bits,  one stop bit,  and no parity.  Any
  1697. X     previously installed serial drivers will be  replaced,  and  the  baud
  1698. X     rate will not be changed.
  1699. X
  1700. X
  1701. X
  1702. X     CLINK comes with her own serial driver built in for the IBM PC  family
  1703. X     and true compatibles,  but she is capable of using any standard FOSSIL
  1704. X     driver.
  1705. X
  1706. SHAR_EOF
  1707. chmod 0644 sea/sealink.doc ||
  1708. echo 'restore of sea/sealink.doc failed'
  1709. Wc_c="`wc -c < 'sea/sealink.doc'`"
  1710. test 11247 -eq "$Wc_c" ||
  1711.     echo 'sea/sealink.doc: original size 11247, current size' "$Wc_c"
  1712. rm -f _shar_wnt_.tmp
  1713. fi
  1714. # ============= sea/sealink.imp ==============
  1715. if test -f 'sea/sealink.imp' -a X"$1" != X"-c"; then
  1716.     echo 'x - skipping sea/sealink.imp (File already exists)'
  1717.     rm -f _shar_wnt_.tmp
  1718. else
  1719. > _shar_wnt_.tmp
  1720. echo 'x - extracting sea/sealink.imp (Text)'
  1721. sed 's/^X//' << 'SHAR_EOF' > 'sea/sealink.imp' &&
  1722. X    SEAlink - Sliding window file transfer protocol
  1723. X
  1724. X    XENIX System V version by Scott Reynolds
  1725. X    additional XENIX modifications by Sanford Zelkovitz, without whose help
  1726. X    this couldn't have been accomplished
  1727. X
  1728. X    Based on:
  1729. X
  1730. X    MS-DOS Version 1.16, created on 01/15/87 at 01:40:52
  1731. X(C) COPYRIGHT 1986,87 by System Enhancement Associates; ALL RIGHTS RESERVED
  1732. X    By:  Thom Henderson
  1733. X
  1734. X    Description:
  1735. X
  1736. X    This file contains a set of routines to illustrate the SEAlink
  1737. X    sliding window file transfer protocol.  SEAlink is fully backward
  1738. X    compatible to XMODEM, and can be easily adapted to most XMODEM
  1739. X    variants.
  1740. X
  1741. X    The intent of SEAlink is to provide a file transfer protocol that
  1742. X    does not suffer from propagation delays, such as are introduced
  1743. X    by satellite relays or packet switched networks.
  1744. X
  1745. X    Instructions:
  1746. X
  1747. X    Two routines are provided to implement SEAlink file transfers.
  1748. X
  1749. X    int xmtfile(name)        /+ transmit a file +/
  1750. X    char *name;            /+ name of file to transmit +/
  1751. X
  1752. X    This routine is used to send a file.  One file is sent at a time.
  1753. X    If the name is blank (name is null or *name points to a null),
  1754. X    then only an end of transmission marker is sent.
  1755. X
  1756. X    This routine returns a one if the file is successfully
  1757. X    transmitted, or a zero if a fatal error occurs.
  1758. X
  1759. X    char *rcvfile(name)        /+ receive a file +/
  1760. X    char *name;            /+ name of file (optional) +/
  1761. X
  1762. X    This routine is used to receive a file.  One file is received.
  1763. X    The name, if given, takes precedence and will be the name of
  1764. X    the resulting file.  If the name is blank (name is null or *name
  1765. X    points to a null), then the name given by the transmitter is used.
  1766. X    If the transmitter does not give a name, then the file transfer
  1767. X    is aborted.
  1768. X
  1769. X    This routine returns a pointer to the name of the file that
  1770. X    was received.  If the file transfer is not successful, then
  1771. X    a null pointer is returned.
  1772. X
  1773. X    The pointer returned by rcvfile() points to a static data buffer.
  1774. X    This does not have to be freed (and should not be), but it will
  1775. X    be overwritten the next time rcvfile() is called.
  1776. X
  1777. X    The rcvfile() function works on a temporary file whose name is
  1778. X    the same as the final file, but with a period (".") added at the
  1779. X    beginning.  If a file transfer is aborted, then this temporary
  1780. X    file will be retained.  An aborted file transfer will not harm
  1781. X    a pre-existing file of the same name.
  1782. X
  1783. X    Programming notes:
  1784. X
  1785. X    These routines can be used for either single or multiple file
  1786. X    transfers.
  1787. X
  1788. X    To send multiple files, send each one one at a time until either
  1789. X    a transmit fails or all files are sent.  If all files are sent,
  1790. X    then signal the end by calling xmtfile() with a null pointer.
  1791. X
  1792. X    To receive multiple files, call rcvfile() repeatedly until it
  1793. X    returns a null pointer.
  1794. X
  1795. X    These routines pass a "block zero", which contains information
  1796. X    about the original file name, size, and date/time of last
  1797. X    modification.  If you cannot implement block zero, then you can
  1798. X    leave it out.  If you cannot set any given field in block zero
  1799. X    when transmitting, then you should leave it set to zeros.  If you
  1800. X    cannot use any given field of block zero when receiving, then
  1801. X    you should ignore it.
  1802. X
  1803. X    These routines are fully compatible with XMODEM, including the
  1804. X    original checksum method and later CRC adaptations.  It can be
  1805. X    easily adapted to Modem7 protocol by adding a Modem7 filename
  1806. X    transfer shell, though we do not recommend it.  The underlying
  1807. X    logic, of course, can be adapted to almost any variant of XMODEM.
  1808. X
  1809. X    License:
  1810. X
  1811. X    You are granted a license to use this code in your programs, and
  1812. X    to adapt it to your particular situation and needs, subject only
  1813. X    to the following conditions:
  1814. X
  1815. X    1)   You must refer to it as the SEAlink protocol, and you must
  1816. X         give credit to System Enhancement Associates.
  1817. X
  1818. X    2)   If you modify it in such a way that your version cannot
  1819. X         converse with the original code as supplied by us, then
  1820. X         you should refer to it as "SEAlink derived", or as a
  1821. X         "variation of SEAlink", or words to that effect.
  1822. X
  1823. X    In short, we're not asking for any money, but we'd like to
  1824. X    get some credit for our work.
  1825. X
  1826. X    Language:
  1827. X
  1828. X    Computer Innovations C86
  1829. X    Adapted for IBM PC XENIX 2.00.2 C using UNIX System V compatible calls
  1830. X
  1831. X    Notes on XENIX modifications:
  1832. X
  1833. X    The com_getc() routine has a minimum delay of .1 seconds, due
  1834. X    to the nature of the read() system call.  Attempts to eliminate
  1835. X    this delay have proven more costly than leaving it in.
  1836. X
  1837. X    CRC maintenance functions were added to the original code, as
  1838. X    they are not library calls under XENIX.
  1839. X
  1840. X    All output is performed through file descriptor 0, and is done
  1841. X    in blocks using the write() system call rather than individual
  1842. X    character writes.  File descriptor 1 may be selected by invoking
  1843. X    the program with a "-1" argument.
  1844. X
  1845. X    Most low level routines utilize register class variables to
  1846. X    decrease overhead and improve overall system response slightly.
  1847. X
  1848. X    A rudimentary command line processor was added to the original
  1849. X    routines to drive the transmitter and receiver.  The two
  1850. X    options, "s" and "r", are for sending and receiving respectively.
  1851. X
  1852. X    When invoked without proper arguments the program will display
  1853. X    a short message including usage notes.
  1854. X
  1855. X    -- Scott Reynolds, Sysop U.S.S. Enterprise BBS, (906)228-9460
  1856. SHAR_EOF
  1857. chmod 0644 sea/sealink.imp ||
  1858. echo 'restore of sea/sealink.imp failed'
  1859. Wc_c="`wc -c < 'sea/sealink.imp'`"
  1860. test 5213 -eq "$Wc_c" ||
  1861.     echo 'sea/sealink.imp: original size 5213, current size' "$Wc_c"
  1862. rm -f _shar_wnt_.tmp
  1863. fi
  1864. # ============= gendial/README ==============
  1865. if test -f 'gendial/README' -a X"$1" != X"-c"; then
  1866.     echo 'x - skipping gendial/README (File already exists)'
  1867.     rm -f _shar_wnt_.tmp
  1868. else
  1869. > _shar_wnt_.tmp
  1870. echo 'x - extracting gendial/README (Text)'
  1871. sed 's/^X//' << 'SHAR_EOF' > 'gendial/README' &&
  1872. XI have done at least rudimentary testing of each of these
  1873. Xdialers in an SCO XENIX or UNIX.  I have good faith in
  1874. Xthe HA24, USR24, MPAD, T2500 and MC9624 dialers.
  1875. XSome many things and ROMs have been called Trailblazer Plus
  1876. Xthat I juust dunno.
  1877. X
  1878. XdialgHA24       Hayes 2400
  1879. XdialgMC9624     Microcom AX/9624c
  1880. XdialgMPAD       AT&T Tridom VSAT modem emulation PAD
  1881. XdialgT2500      Telebit T2500
  1882. XdialgTBPlus     Telebit Trailblazer rom version 5.01
  1883. XdialgUSR24      US Robotic Courier 2400
  1884. SHAR_EOF
  1885. chmod 0644 gendial/README ||
  1886. echo 'restore of gendial/README failed'
  1887. Wc_c="`wc -c < 'gendial/README'`"
  1888. test 480 -eq "$Wc_c" ||
  1889.     echo 'gendial/README: original size 480, current size' "$Wc_c"
  1890. rm -f _shar_wnt_.tmp
  1891. fi
  1892. # ============= gendial/install_dialer ==============
  1893. if test -f 'gendial/install_dialer' -a X"$1" != X"-c"; then
  1894.     echo 'x - skipping gendial/install_dialer (File already exists)'
  1895.     rm -f _shar_wnt_.tmp
  1896. else
  1897. > _shar_wnt_.tmp
  1898. echo 'x - extracting gendial/install_dialer (Text)'
  1899. sed 's/^X//' << 'SHAR_EOF' > 'gendial/install_dialer' &&
  1900. X:
  1901. X#+----------------------------------------------------------
  1902. X# install_dialer -  ECU gendial modem dial installation
  1903. X# usage: install_dialer directory executeable 
  1904. X#+----------------------------------------------------------
  1905. X#+:EDITS:*/
  1906. X#:09-10-1992-13:59-wht@n4hgf-ECU release 3.20
  1907. X#:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA
  1908. X#:04-30-1991-16:07-root@n4hgf-add header and ls -l
  1909. X
  1910. Xlib="$1"
  1911. X
  1912. Xecho ''
  1913. Xwhile [ x$2 != x ]
  1914. Xdo
  1915. X    echo Installing dialer $2 in $lib
  1916. X    rm -f $lib/$2 $lib/$2~
  1917. X    if [ -f $lib/$2 ]; then mv $lib/$2 $lib/$2~; fi
  1918. X    cp $2 $lib/$2
  1919. X    strip $lib/$2
  1920. X    if [ -x /usr/bin/mcs ]; then /usr/bin/mcs -d $lib/$2; fi
  1921. X    chown uucp $lib/$2; chgrp uucp $lib/$2; chmod 711 $lib/$2
  1922. X    ls -l $lib/$2
  1923. X    shift
  1924. X    echo ''
  1925. Xdone
  1926. X
  1927. SHAR_EOF
  1928. chmod 0755 gendial/install_dialer ||
  1929. echo 'restore of gendial/install_dialer failed'
  1930. Wc_c="`wc -c < 'gendial/install_dialer'`"
  1931. test 720 -eq "$Wc_c" ||
  1932.     echo 'gendial/install_dialer: original size 720, current size' "$Wc_c"
  1933. rm -f _shar_wnt_.tmp
  1934. fi
  1935. # ============= gendial/dceHA24.c ==============
  1936. if test -f 'gendial/dceHA24.c' -a X"$1" != X"-c"; then
  1937.     echo 'x - skipping gendial/dceHA24.c (File already exists)'
  1938.     rm -f _shar_wnt_.tmp
  1939. else
  1940. > _shar_wnt_.tmp
  1941. echo 'x - extracting gendial/dceHA24.c (Text)'
  1942. sed 's/^X//' << 'SHAR_EOF' > 'gendial/dceHA24.c' &&
  1943. X/*+-------------------------------------------------------------------------
  1944. X    dceHA24.c - DCE-specific portion of generic SCO UUCP dialer
  1945. X    Driver for generic Hayes-style 2400 baud modem
  1946. X    wht@n4hgf.Mt-Park.GA.US
  1947. X
  1948. X Necessary DCE switch setting or other configuration:
  1949. X   enable onhook upon loss of DTR
  1950. X--------------------------------------------------------------------------*/
  1951. X/*+:EDITS:*/
  1952. X/*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  1953. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  1954. X/*:02-02-1992-18:01-root@n4hgf-proper ordering of DCE_result entries */
  1955. X/*:01-26-1992-15:30-wht@n4hgf-gendial 1.2 for ecu 3.20- better hangup */
  1956. SHAR_EOF
  1957. true || echo 'restore of gendial/dceHA24.c failed'
  1958. fi
  1959. echo 'End of ecu320 part 27'
  1960. echo 'File gendial/dceHA24.c is continued in part 28'
  1961. echo 28 > _shar_seq_.tmp
  1962. exit 0
  1963.  
  1964. exit 0 # Just in case...
  1965.