home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume32 / ecu / part24 < prev    next >
Text File  |  1992-09-14  |  58KB  |  2,499 lines

  1. Newsgroups: comp.sources.misc
  2. From: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
  3. Subject:  v32i059:  ecu - ECU Asynchronous Communications v3.20, Part24/40
  4. Message-ID: <1992Sep14.144547.21857@sparky.imd.sterling.com>
  5. X-Md4-Signature: e7d67ace6a79887f7136fbfc90e24ad3
  6. Date: Mon, 14 Sep 1992 14:45:47 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 59
  11. Archive-name: ecu/part24
  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.24 (part 24 of ecu320)
  18. # do not concatenate these parts, unpack them in order with /bin/sh
  19. # file z/ecurz.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" != 24; 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/ecurz.c'
  35. else
  36. echo 'x - continuing file z/ecurz.c'
  37. sed 's/^X//' << 'SHAR_EOF' >> 'z/ecurz.c' &&
  38. X            report_str(s128,0);
  39. X            return(ERROR);
  40. X        case ZNAK:
  41. X        case TIMEOUT:
  42. X            if( --n < 0)
  43. X            {
  44. X                sprintf(s128,got_garbage_txt,c);
  45. X                report_str(s128,0);
  46. X                return(ERROR);
  47. X            }
  48. X        case ZFILE:
  49. X            zrdata(secbuf,1024);
  50. X            continue;
  51. X        case ZEOF:
  52. X            if(rclhdr(Rxhdr) != rxfilepos)
  53. X            {
  54. X                /*
  55. X                 * Ignore eof if it's at wrong place - force
  56. X                 *  a timeout because the eof might have gone
  57. X                 *  out before we sent our zrpos.
  58. X                 */
  59. X                errors = 0;
  60. X                goto nxthdr;
  61. X            }
  62. X            if(can_on_eof)
  63. X            {
  64. X                send_cancel(0);
  65. X                send_cancel(0);
  66. X                close_and_report();
  67. X                report_uninit(0);
  68. X                exit(0);
  69. X            }
  70. X            if(close_and_report())
  71. X            {
  72. X                tryzhdrtype = ZFERR;
  73. X                return(ERROR);
  74. X            }
  75. X            report_str("End of file",0);
  76. X            return(c);
  77. X        case ERROR:    /* Too much garbage in header search error */
  78. X            if( --n < 0)
  79. X            {
  80. X                sprintf(s128,got_garbage_txt,c);
  81. X                report_str(s128,0);
  82. X                return(ERROR);
  83. X            }
  84. X            zmputs(Attn);
  85. X            continue;
  86. X        case ZSKIP:
  87. X            close_and_report();
  88. X            sprintf(s128,"Sender SKIPPED file");
  89. X            report_str(s128,-1);
  90. X            return(c);
  91. X        case ZDATA:
  92. X            if(rclhdr(Rxhdr) != rxfilepos)
  93. X            {
  94. X                if( --n < 0)
  95. X                {
  96. X                    return(ERROR);
  97. X                }
  98. X                zmputs(Attn);
  99. X                continue;
  100. X            }
  101. Xmoredata:
  102. X            report_receive_progress(rxfilepos);
  103. X            switch(c = zrdata(secbuf,1024))
  104. X            {
  105. X            case ZCAN:
  106. X                sprintf(s128,got_garbage_txt,c);
  107. X                report_str(s128,0);
  108. X                return(ERROR);
  109. X            case ERROR:    /* CRC error */
  110. X                if( --n < 0)
  111. X                {
  112. X                    sprintf(s128,got_garbage_txt,c);
  113. X                    report_str(s128,0);
  114. X                    return(ERROR);
  115. X                }
  116. X                zmputs(Attn);
  117. X                continue;
  118. X            case TIMEOUT:
  119. X                if( --n < 0)
  120. X                {
  121. X                    sprintf(s128,got_garbage_txt,c);
  122. X                    report_str(s128,0);
  123. X                    return(ERROR);
  124. X                }
  125. X                continue;
  126. X            case GOTCRCW:
  127. X                n = 20;
  128. X                write_sec_to_disk(secbuf,Rxcount);
  129. X                rxfilepos += Rxcount;
  130. X                stohdr(rxfilepos);
  131. X                zshhdr(ZACK,Txhdr);
  132. X                sendline(XON);
  133. X                report_str("",-1);
  134. X                goto nxthdr;
  135. X            case GOTCRCQ:
  136. X                n = 20;
  137. X                write_sec_to_disk(secbuf,Rxcount);
  138. X                rxfilepos += Rxcount;
  139. X                stohdr(rxfilepos);
  140. X                zshhdr(ZACK,Txhdr);
  141. X                report_str("",-1);
  142. X                goto moredata;
  143. X            case GOTCRCG:
  144. X                n = 20;
  145. X                write_sec_to_disk(secbuf,Rxcount);
  146. X                rxfilepos += Rxcount;
  147. X                goto moredata;
  148. X            case GOTCRCE:
  149. X                n = 20;
  150. X                write_sec_to_disk(secbuf,Rxcount);
  151. X                rxfilepos += Rxcount;
  152. X                goto nxthdr;
  153. X            }
  154. X        }
  155. X    }
  156. X    /*NOTREACHED*/
  157. X
  158. X}    /* end of rzfile */
  159. X
  160. X/*+-------------------------------------------------------------------------
  161. X    rzfiles() - receive file(s) with ZMODEM protocol
  162. X--------------------------------------------------------------------------*/
  163. Xint
  164. Xrzfiles()
  165. X{
  166. X    register c;
  167. X
  168. X    for(;;)
  169. X    {
  170. X        switch(c = rzfile())
  171. X        {
  172. X        case ZEOF:
  173. X        case ZSKIP:
  174. X            switch(tryz())
  175. X            {
  176. X                case ZCOMPL:
  177. X                    return(OK);
  178. X                default:
  179. X                    return(ERROR);
  180. X                case ZFILE:
  181. X                    break;
  182. X            }
  183. X            continue;
  184. X        default:
  185. X            return(c);
  186. X        case ERROR:
  187. X            return(ERROR);
  188. X        }
  189. X    }
  190. X    /*NOTREACHED*/
  191. X}    /* end of rzfiles */
  192. X
  193. X/*+-------------------------------------------------------------------------
  194. X    close_and_report() - close the received file, set mod time and chmod
  195. X(specifically exclude set uid and gid from chmod)
  196. X--------------------------------------------------------------------------*/
  197. Xint
  198. Xclose_and_report()
  199. X{
  200. X    fflush(fout);
  201. X    fstat(fileno(fout),&fout_stat);
  202. X    report_file_byte_io((long)fout_stat.st_size - initial_filepos);
  203. X
  204. X    report_file_close(0);
  205. X    if(fclose(fout)==ERROR)
  206. X    {
  207. X        if(errno > sys_nerr)
  208. X            sprintf(s128,"finish close errno %d",errno);
  209. X        else
  210. X            sprintf(s128,"finish close error: %s",sys_errlist[errno]);
  211. X        ecu_log_event(getppid(),s128);
  212. X        fout = (FILE *)0;
  213. X        return(ERROR);
  214. X    }
  215. X
  216. X#if defined(LOG_XFER)
  217. X    sprintf(s128,"RECEIVE success: %s (%ld bytes)",Pathname,fout_stat.st_size);
  218. X    ecu_log_event(getppid(),s128);
  219. X#endif
  220. X
  221. X
  222. X    if(Modtime)
  223. X    {
  224. X        timep[0] = time(NULL);
  225. X        timep[1] = Modtime;
  226. X        utime(Pathname,timep);
  227. X    }
  228. X
  229. X    if((Filemode & S_IFMT) == S_IFREG)
  230. X    {
  231. X        Filemode &= ~(S_ISUID | S_ISGID);
  232. X        chmod(Pathname,(unsigned short)(07777 & Filemode));
  233. X    }
  234. X
  235. X    return(OK);
  236. X
  237. X}    /* end of close_and_report */
  238. X
  239. X/*+-------------------------------------------------------------------------
  240. X    sys2(shellcmd) - execute shell command
  241. X
  242. X Strip leading ! if present
  243. X--------------------------------------------------------------------------*/
  244. Xint
  245. Xsys2(shellcmd)
  246. Xregister char *shellcmd;
  247. X{
  248. X    if(*shellcmd == '!')
  249. X        ++shellcmd;
  250. X    return(system(shellcmd));
  251. X} /* end of sys2 */
  252. X
  253. X/*+-------------------------------------------------------------------------
  254. X    main(argc,argv,envp)
  255. X--------------------------------------------------------------------------*/
  256. Xmain(argc,argv,envp)
  257. Xint argc;
  258. Xchar **argv;
  259. Xchar **envp;
  260. X{
  261. X    register char *cp;
  262. X    char **patts = (char **)0;
  263. X    char *getenv();
  264. X    int exitcode = 0;
  265. X
  266. X    gargv = argv;
  267. X    gargc = argc;
  268. X
  269. X    signal(SIGINT,bye_bye);
  270. X    signal(SIGTERM,bye_bye);
  271. X#if    defined(SIGSTOP)
  272. X    /*
  273. X     * call Roto-Rooter on POSIX plots
  274. X     */
  275. X    signal(SIGSTOP,SIG_IGN);
  276. X    signal(SIGTSTP,SIG_IGN);
  277. X    signal(SIGCONT,SIG_IGN);
  278. X    signal(SIGTTIN,SIG_IGN);
  279. X    signal(SIGTTOU,SIG_IGN);
  280. X#endif
  281. X
  282. X    get_curr_dir(curr_dir,sizeof(curr_dir));
  283. X
  284. X    Rxtimeout = 100;
  285. X
  286. X    npats = 0;
  287. X    while(--argc)
  288. X    {
  289. X        cp = *++argv;
  290. X        if(*cp == '-')
  291. X        {
  292. X            while( *++cp)
  293. X            {
  294. X                switch(*cp)
  295. X                {
  296. X                case 'X':
  297. X                    required_type = 1;
  298. X                    Batch = 0;
  299. X                    break;
  300. X                case 'Y':
  301. X                    required_type = 1;
  302. X                    Nozmodem = 1;
  303. X                    Batch = 1;
  304. X                    break;
  305. X                case 'Z':
  306. X                    required_type = 1;
  307. X                    Nozmodem = 0;
  308. X                    Batch = 1;
  309. X                    break;
  310. X                case '+':
  311. X                    Lzmanag = ZMAPND;
  312. X                    break;
  313. X                case 'a':
  314. X                    Rxascii=1;
  315. X                    break;
  316. X                case 'b':
  317. X                    Rxbinary=1;
  318. X                    break;
  319. X                case 'c':
  320. X                    Crcflg=1;
  321. X                    break;
  322. X                case 'e':
  323. X                    Zctlesc = 1;
  324. X                    break;
  325. X                case 'p':
  326. X                    Lzmanag = ZMPROT;
  327. X                    break;
  328. X                case '@':
  329. X                    force_dumbtty = 1;
  330. X                    break;
  331. X                case ',':
  332. X                    log_packets = 1;
  333. X                    break;
  334. X                case ':':
  335. X                    can_on_eof = 1;
  336. X                    break;
  337. X                case '.':
  338. X                    if(--argc < 1)
  339. X                    {
  340. X                        usage("no iofd after -.");
  341. X                    }
  342. X                    iofd = atoi(*++argv);
  343. X                    break;
  344. X                case 't':
  345. X                    if(--argc < 1)
  346. X                    {
  347. X                        usage("no rcvr timeout after -t");
  348. X                    }
  349. X                    Rxtimeout = atoi(*++argv);
  350. X                    if(Rxtimeout<10 || Rxtimeout>1000)
  351. X                        usage("illegal timeout: must be 10 <= t <= 1000");
  352. X                    break;
  353. X                case 'w':
  354. X                    if(--argc < 1)
  355. X                    {
  356. X                        usage("no Zrwindow after -w");
  357. X                    }
  358. X                    Zrwindow = atoi(*++argv);
  359. X                    break;
  360. X                case 'C':
  361. X                    if(--argc < 1)
  362. X                        usage("no label after -C");
  363. X                    bottom_label = *++argv;
  364. X                    break;
  365. X                case 'u':
  366. X                    MakeLCPathname=0;
  367. X                    break;
  368. X                case 'y':
  369. X                    Rxclob=1;
  370. X                    break;
  371. X                default:
  372. X                    sprintf(s128,"Unknown switch -%c",*cp);
  373. X                    usage(s128);
  374. X                }
  375. X            }
  376. X        }
  377. X        else if( !npats && argc>0)
  378. X        {
  379. X            if(argv[0][0])
  380. X            {
  381. X                npats=argc;
  382. X                patts=argv;
  383. X            }
  384. X        }
  385. X    }
  386. X
  387. X    if(determine_output_mode())
  388. X    {
  389. X        setbuf(stdout,NULL);
  390. X        setbuf(stderr,NULL);
  391. X    }
  392. X
  393. X    if(!required_type || !iofd)
  394. X    {
  395. X        printf("can only be run by ecu\n");
  396. X        exit(255);
  397. X    }
  398. X
  399. X    if(log_packets)
  400. X    {
  401. X        char log_packets_name[64];
  402. X        int iargv;
  403. X        sprintf(log_packets_name,"/tmp/rz%05d.plog",getpid());
  404. X        unlink(log_packets_name);
  405. X        log_packets = open(log_packets_name,O_CREAT|O_WRONLY,0644);
  406. X        if(log_packets < 0)
  407. X            log_packets = 0;
  408. X        else
  409. X        {
  410. X            write(log_packets,"exec: ",6);
  411. X            for(iargv = 0; iargv < gargc; iargv++)
  412. X            {
  413. X                write(log_packets,gargv[iargv],strlen(gargv[iargv]));
  414. X                write(log_packets," ",1);
  415. X            }
  416. X            write(log_packets,"\n",1);
  417. X        }
  418. X    }
  419. X
  420. X    /*
  421. X     * learn tick rate for various timers
  422. X     */
  423. X    init_Nap();
  424. X
  425. X    if(Batch && npats)
  426. X        usage("Cannot specify batch receive and filename");
  427. X    if(npats > 1)
  428. X        usage("only one filename allowed");
  429. X    sprintf(s128,"%s",numeric_revision + 4);
  430. X    report_init(s128);
  431. X    mode(1);
  432. X    signal(SIGINT,cancel_transaction);
  433. X    signal(SIGTERM,cancel_transaction);
  434. X    signal(SIGQUIT,cancel_transaction);
  435. X    if(wcreceive(npats,patts)==ERROR)
  436. X    {
  437. X        exitcode=0200;
  438. X        send_cancel(1);
  439. X    }
  440. X    mode(0);
  441. X    if(exitcode && !Zmodem)    /* bellow again with all thy might. */
  442. X        send_cancel(1);
  443. X    report_uninit(0);
  444. X    exit(exitcode);
  445. X}    /* end of main */
  446. X
  447. X/* vi: set tabstop=4 shiftwidth=4: */
  448. X/* end of ecurz.c */
  449. SHAR_EOF
  450. echo 'File z/ecurz.c is complete' &&
  451. chmod 0644 z/ecurz.c ||
  452. echo 'restore of z/ecurz.c failed'
  453. Wc_c="`wc -c < 'z/ecurz.c'`"
  454. test 46240 -eq "$Wc_c" ||
  455.     echo 'z/ecurz.c: original size 46240, current size' "$Wc_c"
  456. rm -f _shar_wnt_.tmp
  457. fi
  458. # ============= z/ecusz.c ==============
  459. if test -f 'z/ecusz.c' -a X"$1" != X"-c"; then
  460.     echo 'x - skipping z/ecusz.c (File already exists)'
  461.     rm -f _shar_wnt_.tmp
  462. else
  463. > _shar_wnt_.tmp
  464. echo 'x - extracting z/ecusz.c (Text)'
  465. sed 's/^X//' << 'SHAR_EOF' > 'z/ecusz.c' &&
  466. Xchar *numeric_revision = "@(#)ecusz 3.20";
  467. X#define BUFFERED_WRITE
  468. X/*+-------------------------------------------------------------------------
  469. X    ecusz.c - X/Y/ZMODEM send program
  470. X  Derived from public domain source by Chuck Forsberg, Omen Technologies
  471. X  Adaptation for ecu 1989 wht@n4hgf.Mt-Park.GA.US
  472. X
  473. X    Usage:    ecusz [-X -Y -Z] [-12+abdefkLlNnquvwy] [-] file ...
  474. X        (Y) = Option applies to YMODEM only
  475. X        (Z) = Option applies to ZMODEM only
  476. X        a (ASCII) change NL to CR/LF
  477. X        b Binary file transfer override
  478. X        f send Full pathname (Y/Z)
  479. X        k Send 1024 byte packets (Y)
  480. X        L N Limit subpacket length to N bytes (Z)
  481. X        l N Limit frame length to N bytes (l>=L) (Z)
  482. X        n send file if source newer (Z)
  483. X        N send file if source newer or longer (Z)
  484. X        o Use 16 bit CRC instead of 32 bit CRC (Z)
  485. X        p Protect existing destination file (Z)
  486. X        r Resume/Recover interrupted file transfer (Z)
  487. X        q Quiet (no progress reports)
  488. X        u Unlink file after transmission
  489. X        w N Window is N bytes (Z)
  490. X        y Yes,overwrite existing file (Z)
  491. X        @file reads a list of filenames from 'file'
  492. X
  493. X  Defined functions:
  494. X    SIGALRM_handler(sig)
  495. X    bye_bye(sig)
  496. X    cancel_transaction(sig)
  497. X    determine_transaction_time()
  498. X    flushline()
  499. X    get_file_list_name(namep)
  500. X    getinsync(flag)
  501. X    getnak()
  502. X    getzrxinit()
  503. X    log_packet_buffer(buf,len)
  504. X    main(argc,argv)
  505. X    onintr()
  506. X    purgeline()
  507. X    readline(n)
  508. X    readock(timeout,count)
  509. X    report_rcvr_cancelled(place_happened)
  510. X    report_rcvr_skipped()
  511. X    report_send_progress(filepos)
  512. X    report_send_transaction()
  513. X    rewind_file_list()
  514. X    saybibi()
  515. X    send_cancel(error)
  516. X    sendline(ch)
  517. X    sendzsinit()
  518. X    set_file_list(pathc,pathv)
  519. X    substr(str,str2)
  520. X    usage()
  521. X    wcputsec(buf,sectnum,cseclen)
  522. X    wcs(oname)
  523. X    wcsend()
  524. X    wctx(flen)
  525. X    wctxpn(name)
  526. X    xbuf_build(buf,count)
  527. X    xsendline(ch)
  528. X    zbuf_build(buf,count)
  529. X    zsendfdata()
  530. X    zsendfile(buf,blen)
  531. X
  532. X--------------------------------------------------------------------------*/
  533. X/*+:EDITS:*/
  534. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  535. X/*:09-05-1992-14:26-wht@n4hgf-zrpos_seen was not set 1 on first ZRPOS */
  536. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  537. X/*:08-16-1992-03:08-wht@n4hgf-head off another POSIX plot */
  538. X/*:08-10-1992-04:01-wht@n4hgf-use init_Nap */
  539. X/*:07-20-1992-13:39-wht@n4hgf-need hzmsec for nap.c */
  540. X/*:09-01-1991-14:18-wht@n4hgf2-improve sun flushline */
  541. X/*:08-29-1991-02:17-wht@n4hgf2-flush "rz" to line before nap */
  542. X/*:08-28-1991-14:08-wht@n4hgf2-SVR4 cleanup by aega84!lh */
  543. X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
  544. X/*:02-03-1991-17:27-wht@n4hgf-version number change - see zcurses.c */
  545. X/*:12-18-1990-21:26-wht@n4hgf-better output control */
  546. X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
  547. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  548. X
  549. X/*
  550. X  Error return conditions
  551. X    255:     usage
  552. X    254:     protocol failed (bad line conditions,brain dead remote)
  553. X    253:     curses problem
  554. X    253:     could not open any files
  555. X    128-192: process terminated with signal==code-128 (64 signals allowed for)
  556. X             signal 0 == program logic error (see cancel_transaction)
  557. X    127:     127 or more files not transmitted (see ~/.ecu/log)
  558. X    1-126:   count of files not transmitted (see ~/.ecu/log)
  559. X    0:       file transfer completely successful
  560. X*/
  561. X
  562. Xchar *substr();
  563. Xchar *getenv();
  564. X
  565. X#include <stdio.h>
  566. X#include <signal.h>
  567. X#include <setjmp.h>
  568. X#include <ctype.h>
  569. X#include <string.h>
  570. X#include <fcntl.h>
  571. X#include "zmodem.h"
  572. X#include <sys/param.h>
  573. X
  574. Xextern char *sys_errlist[];
  575. Xextern unsigned short crctab[];    /* wht */
  576. Xextern unsigned long total_data_bytes_xfered; /* zcurses.c */
  577. Xextern int errno;
  578. Xextern int show_window;
  579. Xextern int Rxtimeout;    /* Tenths of seconds to wait for something */
  580. Xextern char Rxhdr[4];    /* Received header */
  581. Xextern char Txhdr[4];    /* Transmitted header */
  582. Xextern int Txfcs32;        /* TURE means send binary frames with 32 bit FCS */
  583. Xextern long Rxpos;    /* Received file position */
  584. Xextern long Txpos;    /* Transmitted file position */
  585. Xextern char *frametypes[];
  586. Xextern char Attn[];        /* Attention string rx sends to tx on err */
  587. Xextern char s128[128];
  588. X
  589. X#define RETRYMAX 10        /* non-zmodem retry count on block send */
  590. X#define VMIN_COUNT 2    /* must not exceed 255 */
  591. Xunsigned char vmin_count = VMIN_COUNT;
  592. Xint iofd = 0;        /* line io fd */
  593. X#ifdef BUFFERED_WRITE
  594. XFILE *iofp;
  595. X#endif
  596. X
  597. X
  598. X/*
  599. X * Attention string to be executed by receiver to interrupt streaming data
  600. X *  when an error is detected.  A pause (0336) may be needed before the
  601. X *  ^C (03) or after it.
  602. X */
  603. X#if defined(READCHECK)
  604. Xchar Myattn[] = { 0 };
  605. X#else
  606. Xchar Myattn[] = { 03,0336,0 };
  607. X#endif
  608. X
  609. XFILE *in;
  610. X
  611. Xchar *Cmdstr;        /* Pointer to the command string */
  612. Xchar *bottom_label = (char *)0;
  613. Xchar Crcflg;
  614. Xchar Lastrx;
  615. Xchar Lzconv;        /* Local ZMODEM file conversion request */
  616. Xchar Lzmanag;        /* Local ZMODEM file management request */
  617. Xchar Lztrans;
  618. Xchar Pathname[PATHLEN];
  619. Xchar curr_dir[256];
  620. Xchar txbuf[1024];
  621. Xchar zconv;                /* ZMODEM file conversion request */
  622. Xchar zmanag;            /* ZMODEM file management request */
  623. Xchar ztrans;            /* ZMODEM file transport request */
  624. Xint Ascii;            /* Add CR's for brain damaged programs */
  625. Xint Cmdack1;            /* Rx ACKs command,then do it */
  626. Xint Cmdtries = 11;
  627. Xint Command;        /* Send a command,then exit. */
  628. Xint Dontread;            /* Don't read the buffer,it's still there */
  629. Xint Dottoslash;        /* Change foo.bar.baz to foo/bar/baz */
  630. Xint Exitcode;
  631. Xint Filcnt;            /* count of number of files opened */
  632. Xint FilesTotal;
  633. Xint Filesleft;
  634. Xint Fullname;            /* transmit full pathname */
  635. Xint Lastn;                /* Count of last buffer read or -1 */
  636. Xint Lfseen;
  637. Xint Noeofseen;
  638. Xint Nozmodem;
  639. Xint Optiong;            /* no wait for block ACK's */
  640. Xint Quiet;            /* overrides logic that would otherwise set verbose */
  641. Xint Rxflags;
  642. Xint SameZrposAgain;    /* How many times we've been ZRPOS'd same place (wht) */
  643. Xint Tframlen;        /* Override for tx frame length */
  644. Xint Totsecs;            /* total number of blocks this file */
  645. Xint Twostop;        /* use two stop bits */
  646. Xint Unlinkafter;        /* Unlink file after it is sent */
  647. Xint Wantfcs32 = TRUE;    /* want to send 32 bit FCS */
  648. Xint Xmodem;            /* XMODEM Protocol - don't send pathnames */
  649. Xint Zctlesc;            /* Encode control characters */
  650. Xint Zmodem;            /* ZMODEM protocol requested by receiver */
  651. Xint Zrwindow = 1400;    /* RX window size (controls garbage count) */
  652. Xint blklen=128;            /* length of transmitted records */
  653. Xint blklen_original;
  654. Xint blkopt;            /* Override value for zmodem blklen */
  655. Xint ecusz_flag = 1;
  656. Xint force_dumbtty;
  657. Xint got_xfer_type;
  658. Xint seen_zrpos;
  659. Xint skip_count;        /* skipped files */
  660. Xint errors;
  661. Xint firstsec;
  662. Xint log_packets;
  663. Xint no_files;
  664. Xint npats;
  665. Xlong Lastread;        /* Beginning offset of last buffer read */
  666. Xlong Lastsync;        /* Last offset to which we got a ZRPOS */
  667. Xlong Lrxpos;            /* Receiver's last reported offset */
  668. Xlong TotalLeft;
  669. Xlong TotalToSend;
  670. Xlong bytcnt;
  671. Xlong rx_char_count;
  672. Xlong this_file_length;
  673. Xlong tx_char_count;
  674. Xlong initial_filepos;        /* initial file position */
  675. Xunsigned Baudrate;
  676. Xunsigned Rxbuflen = 16384;    /* Receiver's max buffer length */
  677. Xunsigned Txwcnt;        /* Counter used to space ack requests */
  678. Xunsigned Txwindow;        /* Control the size of the transmitted window */
  679. Xunsigned Txwspac;        /* Spacing between zcrcq requests */
  680. Xunsigned int bad_condx_blklen;    /* if <>0,blklen has been reduced (wht) */
  681. Xunsigned int bad_condx_frame_count;    /* frame # last SameZrposAgain (wht) */
  682. Xunsigned int this_file_frame_count;    /* count of frames sent this file (wht) */
  683. X
  684. X#define MAX_PATHS 512
  685. Xchar *paths[MAX_PATHS];
  686. X
  687. Xjmp_buf tohere;        /* For the interrupt on RX timeout */
  688. Xjmp_buf intrjmp;    /* For the interrupt on RX CAN */
  689. X
  690. Xint file_list_pathc;
  691. Xint file_list_path_current;
  692. Xchar **file_list_pathv;
  693. XFILE *fpflst = (FILE *)0;
  694. X
  695. Xvoid send_cancel();
  696. Xvoid purgeline();
  697. Xvoid usage();
  698. Xvoid saybibi();
  699. Xvoid determine_transaction_time();
  700. Xvoid sendline();
  701. Xvoid xsendline();
  702. X
  703. X/*+-------------------------------------------------------------------------
  704. X    log_packet_buffer(buf,len)
  705. X--------------------------------------------------------------------------*/
  706. Xvoid
  707. Xlog_packet_buffer(buf,len)
  708. Xregister unsigned char *buf;
  709. Xregister int len;
  710. X{
  711. X    char xbuf[32];
  712. X
  713. X    while(len--)
  714. X    {
  715. X        sprintf(xbuf,"%02x ",*buf++);
  716. X        write(log_packets,xbuf,strlen(xbuf));
  717. X    }
  718. X    write(log_packets,"\n",1);
  719. X
  720. X}    /* end of log_packet_buffer */
  721. X
  722. X/*+-------------------------------------------------------------------------
  723. X    rewind_file_list()
  724. X--------------------------------------------------------------------------*/
  725. Xvoid
  726. Xrewind_file_list()
  727. X{
  728. X    file_list_path_current = 0;
  729. X    if(fpflst)
  730. X    {
  731. X        fclose(fpflst);
  732. X        fpflst = (FILE *)0;
  733. X    }
  734. X}    /* end of rewind_file_list */
  735. X
  736. X/*+-------------------------------------------------------------------------
  737. X    set_file_list(pathc,pathv)
  738. X--------------------------------------------------------------------------*/
  739. Xvoid
  740. Xset_file_list(pathc,pathv)
  741. Xint pathc;
  742. Xchar **pathv;
  743. X{
  744. X    file_list_pathc = pathc;
  745. X    file_list_pathv = pathv;
  746. X    rewind_file_list();
  747. X
  748. X}    /* end of set_file_list */
  749. X
  750. X/*+-------------------------------------------------------------------------
  751. X    get_file_list_name(namep)
  752. Xreturn 1 if @lst found else 0
  753. X--------------------------------------------------------------------------*/
  754. Xint
  755. Xget_file_list_name(namep)
  756. Xchar **namep;
  757. X{
  758. X    register char *cptr;
  759. X    static char name[256];
  760. X
  761. Xtry_fpflst:
  762. X    if(fpflst)
  763. X    {
  764. X        if(fgets(name,sizeof(name),fpflst) != NULL)
  765. X        {
  766. X            name[strlen(name) - 1] = 0;
  767. X            *namep = name;
  768. X            return(1);
  769. X        }
  770. X        fclose(fpflst);
  771. X        fpflst = (FILE *)0;
  772. X    }
  773. X
  774. Xnext_arg:
  775. X    if(file_list_path_current == file_list_pathc)
  776. X        return(0);
  777. X    cptr = file_list_pathv[file_list_path_current++];
  778. X    if(*cptr != '@')
  779. X    {
  780. X        *namep = cptr;
  781. X        return(1);
  782. X    }
  783. X    cptr++;
  784. X    if((fpflst = fopen(cptr,"r")) == NULL)
  785. X        goto next_arg;
  786. X    goto try_fpflst;
  787. X
  788. X}    /* end of get_file_list_name */
  789. X
  790. X/*+-------------------------------------------------------------------------
  791. X    bye_bye(sig)
  792. X--------------------------------------------------------------------------*/
  793. Xvoid
  794. Xbye_bye(sig)
  795. Xint sig;
  796. X{
  797. X    exit(sig+128);
  798. X}    /* end of bye_bye */
  799. X
  800. X/*+-------------------------------------------------------------------------
  801. X    cancel_transaction(sig)
  802. Xcalled by signal interrupt or terminate to clean things up
  803. X--------------------------------------------------------------------------*/
  804. Xvoid
  805. Xcancel_transaction(sig)
  806. Xint sig;
  807. X{
  808. X    if(Zmodem)
  809. X        zmputs(Attn);
  810. X    send_cancel(1);
  811. X    mode(0);
  812. X    if(sig >= 0)
  813. X    {
  814. X        sprintf(s128,"ecusz aborted (signal %d)",sig);
  815. X        report_str(s128,0);
  816. X    }
  817. X    report_tx_ind(0);
  818. X    report_rx_ind(0);
  819. X    report_uninit(0);
  820. X    bye_bye(sig);
  821. X}    /* end of cancel_transaction */
  822. X
  823. X/*+-------------------------------------------------------------------------
  824. X    onintr() - Called when ZMODEM gets an interrupt (^X)
  825. X--------------------------------------------------------------------------*/
  826. Xonintr()
  827. X{
  828. X    signal(SIGINT,SIG_IGN);
  829. X    report_rx_ind(0);
  830. X    report_tx_ind(0);
  831. X    longjmp(intrjmp,-1);
  832. X}    /* end of onintr */
  833. X
  834. X
  835. X
  836. X/*+-------------------------------------------------------------------------
  837. X    report_send_transaction()
  838. X--------------------------------------------------------------------------*/
  839. Xvoid
  840. Xreport_send_transaction()
  841. X{
  842. X    if(Xmodem)
  843. X    {
  844. X        long blocks = (TotalToSend >> 7) + ((TotalToSend % 128) != 0);
  845. X        long secs = 7        /* slightly worse than average first nak delay */
  846. X            + (blocks / 5L)                /* assume .2 sec ack time */
  847. X            + ((blocks * (128L + 16L)) / (Baudrate / 10));
  848. X        if(!secs)
  849. X            secs = 10L;
  850. X        sprintf(s128,"Sending %ld blocks time ~= %ld:%02ld",
  851. X            blocks,secs/60,secs % 60);
  852. X    }
  853. X    else
  854. X    {
  855. X        long min_100 =
  856. X            (FilesTotal * 2L) + (((TotalToSend * 11L)) * 10L) / (Baudrate * 6L);
  857. X        if(!min_100)
  858. X            min_100 = 4L;
  859. X#if defined(M_I286)    /* slower */
  860. X        else if(Baudrate > 4800)
  861. X        {
  862. X            min_100 *= 13;
  863. X            min_100 /= 9;    /* yech ... empirical */
  864. X        }
  865. X#endif
  866. X        sprintf(s128,
  867. X            "Total transaction %ld bytes (xfer time ~= %2lu:%02lu)",
  868. X            TotalToSend,min_100 / 100,((min_100 % 100) * 60L) / 100L);
  869. X    }
  870. X    report_transaction(s128);
  871. X
  872. X}    /* end of report_send_transaction */
  873. X
  874. X/*+-------------------------------------------------------------------------
  875. X    report_send_progress(filepos)
  876. X--------------------------------------------------------------------------*/
  877. Xvoid
  878. Xreport_send_progress(filepos)
  879. Xlong filepos;
  880. X{
  881. X
  882. X    if(Xmodem)
  883. X    {
  884. X        sprintf(s128,"File %d%% complete",
  885. X            (this_file_length == 0) ? (int)100 :
  886. X            (int)((filepos * 100L) / this_file_length));
  887. X    }
  888. X    else
  889. X    {
  890. X        sprintf(s128,"This file %d%%, transaction %d%% complete",
  891. X            (this_file_length == 0) ? (int)100 :
  892. X                    (int)((filepos * 100L)/this_file_length),
  893. X            (TotalToSend == 0) ? (int)100 :
  894. X                    (int)(((total_data_bytes_xfered + filepos) * 100L)
  895. X                        / TotalToSend));
  896. X    }
  897. X    report_str(s128,0);
  898. X    report_txpos(filepos);
  899. X
  900. X}    /* end of report_send_progress */
  901. X
  902. X/*+-------------------------------------------------------------------------
  903. X    report_rcvr_cancelled(place_happened)
  904. X--------------------------------------------------------------------------*/
  905. Xvoid
  906. Xreport_rcvr_cancelled(place_happened)
  907. Xchar *place_happened;
  908. X{
  909. X    strcpy(s128,"SEND CANCELLED");
  910. X    report_str(s128 + 5,1);
  911. X#if defined(LOG_XFER)
  912. X    strcat(s128," (");
  913. X    strcat(s128,place_happened);
  914. X    strcat(s128,")");
  915. X    ecu_log_event(getppid(),s128);
  916. X#endif
  917. X    skip_count++;
  918. X    report_error_count();
  919. X}    /* end of report_rcvr_cancelled */
  920. X
  921. X/*+-------------------------------------------------------------------------
  922. X    report_rcvr_skipped()
  923. X--------------------------------------------------------------------------*/
  924. Xvoid
  925. Xreport_rcvr_skipped()
  926. X{
  927. X    sprintf(s128,"SEND skipped: %s",Pathname);
  928. X    report_str(s128 + 5,-1);
  929. X#if defined(LOG_SKIP)
  930. X    ecu_log_event(getppid(),s128);
  931. X#endif
  932. X    skip_count++;
  933. X    report_error_count();
  934. X    TotalToSend -= this_file_length;
  935. X    report_send_transaction();
  936. X}    /* end of report_rcvr_skipped */
  937. X
  938. X
  939. X/*+-------------------------------------------------------------------------
  940. X    xsendline(ch)
  941. X--------------------------------------------------------------------------*/
  942. Xvoid
  943. Xxsendline(ch)
  944. Xchar ch;
  945. X{
  946. X#ifdef BUFFERED_WRITE
  947. X    fputc(ch,iofp);
  948. X#else
  949. X    write(iofd,&ch,1);
  950. X#endif
  951. X    ++tx_char_count;
  952. X}    /* end of xsendline */
  953. X
  954. X/*+-------------------------------------------------------------------------
  955. X    sendline(ch)
  956. X--------------------------------------------------------------------------*/
  957. Xvoid
  958. Xsendline(ch)
  959. Xchar ch;
  960. X{
  961. X    xsendline(ch);
  962. X}    /* end of sendline */
  963. X
  964. X/*+-------------------------------------------------------------------------
  965. X    flushline() - ensure all queued data to line is on the wire
  966. X--------------------------------------------------------------------------*/
  967. Xvoid
  968. Xflushline()
  969. X{
  970. X#if defined(sun)
  971. Xint retries = 50;
  972. Xint outq_count;
  973. Xint old_outq_count = 0;
  974. X#else
  975. Xstruct termio tio;
  976. X#endif
  977. X
  978. X#ifdef BUFFERED_WRITE
  979. X    fflush(iofp);
  980. X#endif
  981. X
  982. X#if defined(sun)
  983. X    do {
  984. X        ioctl(iofd,TIOCOUTQ,&outq_count);
  985. X        if(!outq_count)
  986. X            break;
  987. X        if(old_outq_count == outq_count) /* don't hang if flow control lock */
  988. X            retries--;
  989. X        old_outq_count = outq_count;
  990. X        Nap(50);
  991. X    } while(outq_count && retries);
  992. X#else
  993. X    ioctl(iofd,TCGETA,(char *)&tio);
  994. X    ioctl(iofd,TCSETAW,(char *)&tio);
  995. X#endif
  996. X}    /* end of flushline */
  997. X
  998. X/*+-------------------------------------------------------------------------
  999. X    main(argc,argv)
  1000. X--------------------------------------------------------------------------*/
  1001. Xmain(argc,argv)
  1002. Xint argc;
  1003. Xchar **argv;
  1004. X{
  1005. Xregister char *cp;
  1006. Xchar **patts = paths;
  1007. Xchar **gargv = argv;
  1008. Xint gargc = argc;
  1009. X
  1010. X    signal(SIGINT,bye_bye);
  1011. X    signal(SIGTERM,bye_bye);
  1012. X#if    defined(SIGSTOP)
  1013. X    /*
  1014. X     * call Roto-Rooter on POSIX plots
  1015. X     */
  1016. X    signal(SIGSTOP,SIG_IGN);
  1017. X    signal(SIGTSTP,SIG_IGN);
  1018. X    signal(SIGCONT,SIG_IGN);
  1019. X    signal(SIGTTIN,SIG_IGN);
  1020. X    signal(SIGTTOU,SIG_IGN);
  1021. X#endif
  1022. X
  1023. X    get_curr_dir(curr_dir,sizeof(curr_dir));
  1024. X
  1025. X    Rxtimeout = 600;
  1026. X    npats=0;
  1027. X    if(argc<2)
  1028. X        usage();
  1029. X    while(--argc)
  1030. X    {
  1031. X        cp = *++argv;
  1032. X        if(*cp == '-')
  1033. X        {
  1034. X            cp++;
  1035. X            switch(*cp++)
  1036. X            {
  1037. X            case 'X':
  1038. X                got_xfer_type = 1;
  1039. X                Xmodem = TRUE;
  1040. X                break;
  1041. X            case 'Y':
  1042. X                got_xfer_type = 1;
  1043. X                Nozmodem = TRUE;
  1044. X                blklen=1024;
  1045. X                break;
  1046. X            case 'Z':
  1047. X                show_window = 1;
  1048. X                got_xfer_type = 1;
  1049. X                break;
  1050. X
  1051. X            case '+':
  1052. X                Lzmanag = ZMAPND;
  1053. X                break;
  1054. X            case 'a':
  1055. X                Lzconv = ZCNL;
  1056. X                Ascii = TRUE;
  1057. X                break;
  1058. X            case 'b':
  1059. X                Lzconv = ZCBIN;
  1060. X                break;
  1061. X            case 'd':
  1062. X                ++Dottoslash;
  1063. X                /* **** FALL THROUGH TO **** */
  1064. X            case 'f':
  1065. X                Fullname=TRUE;
  1066. X                break;
  1067. X            case ',':
  1068. X                log_packets = 1;
  1069. X                break;
  1070. X            case '@':
  1071. X                force_dumbtty = 1;
  1072. X                break;
  1073. X            case '/':
  1074. X                if(--argc < 1)
  1075. X                    usage();
  1076. X                strcpy(curr_dir,*++argv);
  1077. X                break;
  1078. X            case '.':
  1079. X                if(--argc < 1)
  1080. X                    usage();
  1081. X                iofd = atoi(*++argv);
  1082. X                break;
  1083. X            case 'C':
  1084. X                if(--argc < 1)
  1085. X                    usage("no label after -C");
  1086. X                bottom_label = *++argv;
  1087. X                break;
  1088. X            case 'e':
  1089. X                Zctlesc = 1;
  1090. X                break;
  1091. X            case 'k':
  1092. X                blklen=1024;
  1093. X                break;
  1094. X            case 'L':
  1095. X                if(--argc < 1)
  1096. X                {
  1097. X                    usage();
  1098. X                }
  1099. X                blkopt = atoi(*++argv);
  1100. X                if(blkopt<24 || blkopt>1024)
  1101. X                        usage();
  1102. X                break;
  1103. X            case 'l':
  1104. X                if(--argc < 1)
  1105. X                {
  1106. X                    usage();
  1107. X                }
  1108. X                Tframlen = atoi(*++argv);
  1109. X                if(Tframlen<32 || Tframlen>1024)
  1110. X                    usage();
  1111. X                break;
  1112. X            case 'N':
  1113. X                Lzmanag = ZMNEWL;
  1114. X                break;
  1115. X            case 'n':
  1116. X                Lzmanag = ZMNEW;
  1117. X                break;
  1118. X            case 'o':
  1119. X                Wantfcs32 = FALSE;
  1120. X                break;
  1121. X            case 'p':
  1122. X                Lzmanag = ZMPROT;
  1123. X                break;
  1124. X            case 'r':
  1125. X                Lzconv = ZCRESUM;
  1126. X                break;
  1127. X            case 't':
  1128. X                if(--argc < 1)
  1129. X                {
  1130. X                    usage();
  1131. X                }
  1132. X                Rxtimeout = atoi(*++argv);
  1133. X                if(Rxtimeout<10 || Rxtimeout>1000)
  1134. X                    usage();
  1135. X                break;
  1136. X            case 'u':
  1137. X                ++Unlinkafter;
  1138. X                break;
  1139. X            case 'w':
  1140. X                if(--argc < 1)
  1141. X                {
  1142. X                    usage();
  1143. X                }
  1144. X                Txwindow = atoi(*++argv);
  1145. X                if(Txwindow < 256)
  1146. X                    Txwindow = 256;
  1147. X                Txwindow = (Txwindow/64) * 64;
  1148. X                Txwspac = Txwindow/4;
  1149. X                if(blkopt > Txwspac || (!blkopt && Txwspac < 1024))
  1150. X                    blkopt = Txwspac;
  1151. X                break;
  1152. X            case 'y':
  1153. X                Lzmanag = ZMCLOB;
  1154. X                break;
  1155. X            default:
  1156. X                usage();
  1157. X            }
  1158. X        }
  1159. X        else if(argc > 0)
  1160. X        {
  1161. X            if(npats < MAX_PATHS)
  1162. X            {
  1163. X                npats++;
  1164. X                *patts++ = cp;
  1165. X            }
  1166. X            else
  1167. X            {
  1168. X                printf("too many filenames to send\n");
  1169. X                exit(255);
  1170. X            }
  1171. X        }
  1172. X    }
  1173. X    if(!got_xfer_type || !iofd)
  1174. X    {
  1175. X        printf("can only be run by ecu\n");
  1176. X        exit(255);
  1177. X    }
  1178. X
  1179. X    if(determine_output_mode())
  1180. X    {
  1181. X        setbuf(stdout,NULL);
  1182. X        setbuf(stderr,NULL);
  1183. X    }
  1184. X
  1185. X    if(npats < 1 && !Command)
  1186. X        usage();
  1187. X
  1188. X    set_file_list(npats,paths);
  1189. X    sprintf(s128,"%s",numeric_revision + 4);
  1190. X
  1191. X    if(log_packets)
  1192. X    {
  1193. X    char log_packets_name[64];
  1194. X    FILE *ftmp;
  1195. X    int iargv;
  1196. X        sprintf(log_packets_name,"/tmp/sz%05d.plog",getpid());
  1197. X        unlink(log_packets_name);
  1198. X        ftmp = fopen(log_packets_name,"w");
  1199. X        fclose(ftmp);
  1200. X        log_packets = open(log_packets_name,O_WRONLY,0644);
  1201. X        if(log_packets < 0)
  1202. X            log_packets = 0;
  1203. X        else
  1204. X        {
  1205. X            write(log_packets,"exec: ",6);
  1206. X            for(iargv = 0; iargv < gargc; iargv++)
  1207. X            {
  1208. X                write(log_packets,gargv[iargv],strlen(gargv[iargv]));
  1209. X                write(log_packets," ",1);
  1210. X            }
  1211. X            write(log_packets,"\n",1);
  1212. X        }
  1213. X    }
  1214. X
  1215. X    /*
  1216. X     * learn tick rate for various timers
  1217. X     */
  1218. X    init_Nap();
  1219. X
  1220. X    report_init(s128);
  1221. X    mode(1);
  1222. X
  1223. X    if(signal(SIGINT,cancel_transaction) == SIG_IGN)
  1224. X        signal(SIGINT,SIG_IGN);
  1225. X    else
  1226. X        signal(SIGINT,cancel_transaction);
  1227. X    signal(SIGTERM,cancel_transaction);
  1228. X
  1229. X    report_str("calculating transaction time",-1);
  1230. X    determine_transaction_time();
  1231. X#ifdef BUFFERED_WRITE
  1232. X    iofp = fdopen(iofd,"w");
  1233. X#endif
  1234. X    if(!Xmodem)
  1235. X    {
  1236. X        TotalToSend = TotalLeft;
  1237. X        report_send_transaction();
  1238. X        report_str("starting remote receiver",-1);
  1239. X        report_last_txhdr("begin transfer",0);
  1240. X        if(!Nozmodem)
  1241. X            write(iofd,"rz\r",3);
  1242. X        else    /* wht -- why not? */
  1243. X            write(iofd,"rb\r",3);        /* wht */
  1244. X        flushline();
  1245. X        Nap(750L);
  1246. X        report_str("",-1);
  1247. X        if(!Nozmodem)
  1248. X        {
  1249. X            stohdr(0L);
  1250. X            zshhdr(ZRQINIT,Txhdr);
  1251. X        }
  1252. X    }
  1253. X    else
  1254. X    {
  1255. X        report_str("",-1);
  1256. X        report_last_txhdr("begin transfer",0);
  1257. X    }
  1258. X
  1259. X    if(wcsend()==ERROR)
  1260. X    {
  1261. X        Exitcode=254;        /*wht was 0200 */
  1262. X        send_cancel(1);
  1263. X    }
  1264. X    mode(0);
  1265. X    report_uninit(0);
  1266. X    if(no_files)
  1267. X        Exitcode = 253;
  1268. X    exit(Exitcode ? Exitcode : (skip_count > 127) ? 127 : skip_count);
  1269. X    /*NOTREACHED*/
  1270. X}    /* end of main */
  1271. X
  1272. X
  1273. X/*+-------------------------------------------------------------------------
  1274. X    wcsend(argc,argp) -- send group of files
  1275. X--------------------------------------------------------------------------*/
  1276. Xint
  1277. Xwcsend()
  1278. X{
  1279. X    char *name;
  1280. X
  1281. X    Crcflg=FALSE;
  1282. X    firstsec=TRUE;
  1283. X    bytcnt = -1;
  1284. X    rewind_file_list();
  1285. X    while(get_file_list_name(&name))
  1286. X    {
  1287. X        Totsecs = 0;
  1288. X        if(wcs(name)==ERROR)
  1289. X            return(ERROR);
  1290. X    }
  1291. X    Totsecs = 0;
  1292. X    if(Filcnt==0)
  1293. X    {    /* bitch if we couldn't open ANY files */
  1294. X        send_cancel(1);
  1295. X        strcpy(s128,"SEND cannot open any requested files");
  1296. X        report_str(s128 + 5,1);
  1297. X#if defined(LOG_XFER)
  1298. X        ecu_log_event(getppid(),s128);
  1299. X#endif
  1300. X        sleep(2);        /* allow time for other rz to get ready */
  1301. X        no_files = 1;
  1302. X        return(ERROR);    /* ... then cancel */
  1303. X    }
  1304. X    if(Zmodem)
  1305. X        saybibi();
  1306. X    else if(!Xmodem)
  1307. X        wctxpn("");
  1308. X    return(OK);
  1309. X}
  1310. X
  1311. X/*+-------------------------------------------------------------------------
  1312. X    wcs(oname) -- send a file
  1313. X--------------------------------------------------------------------------*/
  1314. Xint
  1315. Xwcs(oname)
  1316. Xchar *oname;
  1317. X{
  1318. Xregister c;
  1319. Xstruct stat f;
  1320. X
  1321. X    strcpy(Pathname,oname);    /* global copy of name */
  1322. X
  1323. X    if((in=fopen(oname,"r"))==NULL)
  1324. X    {
  1325. X        sprintf(s128,"SEND %s: %s",sys_errlist[errno],oname);
  1326. X#if defined(LOG_XFER)
  1327. X        ecu_log_event(getppid(),s128);
  1328. X#endif
  1329. X        report_str(s128 + 5,1);
  1330. X        skip_count++;
  1331. X        report_error_count();
  1332. X        return(OK);    /* pass over it,there may be others */
  1333. X    }
  1334. X    seen_zrpos = 0;
  1335. X    ++Noeofseen;
  1336. X    Lastread = 0;
  1337. X    Lastn = -1;
  1338. X    Dontread = FALSE;
  1339. X    /* Check for directory or block special files */
  1340. X    fstat(fileno(in),&f);
  1341. X    c = f.st_mode & S_IFMT;
  1342. X    if(c == S_IFDIR || c == S_IFBLK)
  1343. X    {
  1344. X        sprintf(s128,"SEND %s: %s",
  1345. X            (c == S_IFDIR) ? "directory" : "block device",oname);
  1346. X        report_str(s128 + 5,1);
  1347. X#if defined(LOG_SKIP)
  1348. X        ecu_log_event(getppid(),s128);
  1349. X#endif
  1350. X        skip_count++;
  1351. X        report_error_count();
  1352. X        fclose(in);
  1353. X        return(OK);
  1354. X    }
  1355. X    f.st_mode &= ~(S_ISUID | S_ISGID);
  1356. X    Filcnt++;
  1357. X    report_file_send_open(oname,&f);
  1358. X    this_file_length = f.st_size;
  1359. X    report_send_progress(0L);
  1360. X    switch(wctxpn(Pathname))
  1361. X    {
  1362. X    case ERROR:
  1363. X        sprintf(s128,"SEND protocol failure: %s",oname);
  1364. X        report_str(s128 + 5,1);
  1365. X#if defined(LOG_XFER)
  1366. X        ecu_log_event(getppid(),s128);
  1367. X#endif
  1368. X        skip_count++;
  1369. X        report_error_count();
  1370. X        report_file_close(2);
  1371. X        fclose(in);
  1372. X        return(ERROR);
  1373. X    case ZSKIP:
  1374. X        report_rcvr_skipped();
  1375. X        return(OK);
  1376. X    }
  1377. X    if(!Zmodem && wctx(f.st_size)==ERROR)
  1378. X        return(ERROR);
  1379. X    if(Unlinkafter)
  1380. X        unlink(oname);
  1381. X    return(0);
  1382. X}
  1383. X
  1384. X/*+-------------------------------------------------------------------------
  1385. X    wctxpn(name)
  1386. X
  1387. Xgenerate and transmit pathname block consisting of pathname (null
  1388. Xterminated), file length,mode time and file mode in octal as
  1389. Xprovided by the Unix fstat call.  N.B.: modifies the passed
  1390. Xname,may extend it!
  1391. X--------------------------------------------------------------------------*/
  1392. Xint
  1393. Xwctxpn(name)
  1394. Xchar *name;
  1395. X{
  1396. X    register char *p,*q;
  1397. X    char name2[PATHLEN];
  1398. X    struct stat f;
  1399. X
  1400. X    if(Xmodem)
  1401. X    {
  1402. X        if((in!=stdin) && *name && fstat(fileno(in),&f)!= -1)
  1403. X        {
  1404. X            TotalToSend = f.st_size;
  1405. X            report_protocol_type("XMODEM");
  1406. X            report_send_transaction();
  1407. X            report_xfer_mode((Ascii) ? "ASCII" : "BINARY");
  1408. X            report_last_txhdr("Waiting on NAK",0);
  1409. X        }
  1410. X        return(OK);
  1411. X    }
  1412. X    if(!Zmodem)
  1413. X    {
  1414. X        report_last_txhdr("START PENDING",0);
  1415. X        if(getnak())
  1416. X        {
  1417. X            report_str("Timeout on pathname nak",1);
  1418. X            return(ERROR);
  1419. X        }
  1420. X    }
  1421. X
  1422. X    q = (char *) 0;
  1423. X    if(Dottoslash)
  1424. X    {        /* change . to . */
  1425. X        for(p=name; *p; ++p)
  1426. X        {
  1427. X            if(*p == '/')
  1428. X                q = p;
  1429. X            else if(*p == '.')
  1430. X                *(q=p) = '/';
  1431. X        }
  1432. X        if(q && strlen(++q) > (unsigned)8)
  1433. X        {    /* If name>8 chars */
  1434. X            q += 8;            /*   make it .ext */
  1435. X            strcpy(name2,q);    /* save excess of name */
  1436. X            *q = '.';
  1437. X            strcpy(++q,name2);    /* add it back */
  1438. X        }
  1439. X    }
  1440. X
  1441. X    for(p=name,q=txbuf ; *p; )
  1442. X        if((*q++ = *p++) == '/' && !Fullname)
  1443. X            q = txbuf;
  1444. X    *q++ = 0;
  1445. X    p=q;
  1446. X    while(q < (txbuf + 1024))
  1447. X        *q++ = 0;
  1448. X    if(!Ascii && (in != stdin) && *name && !fstat(fileno(in),&f))
  1449. X        sprintf(p,"%lu %lo %o 0 %d %ld",f.st_size,f.st_mtime,
  1450. X            f.st_mode &= ~(S_ISUID | S_ISGID),
  1451. X            Filesleft,TotalLeft);
  1452. X    report_xfer_mode((Lzconv == ZCNL) ? "ASCII" : "BINARY");
  1453. X    TotalLeft -= f.st_size;
  1454. X    if(--Filesleft <= 0)
  1455. X        TotalLeft = 0;
  1456. X    if(TotalLeft < 0)
  1457. X        TotalLeft = 0;
  1458. X
  1459. X    /* force 1k blocks if name won't fit in 128 byte block */
  1460. X    if(txbuf[125])
  1461. X        blklen=1024;
  1462. X    else
  1463. X    {        /* A little goodie for IMP/KMD */
  1464. X        txbuf[127] = (f.st_size + 127) >>7;
  1465. X        txbuf[126] = (f.st_size + 127) >>15;
  1466. X    }
  1467. X    if(Zmodem)
  1468. X        return(zsendfile(txbuf,1+strlen(p)+(p-txbuf)));
  1469. X    report_protocol_type("YMODEM");
  1470. X    if(wcputsec(txbuf,0,128)==ERROR)
  1471. X        return(ERROR);
  1472. X    return(OK);
  1473. X}    /* end of wctxpn */
  1474. X
  1475. X
  1476. X/*+-------------------------------------------------------------------------
  1477. X    getnak()
  1478. X--------------------------------------------------------------------------*/
  1479. Xint
  1480. Xgetnak()
  1481. X{
  1482. X    register firstch;
  1483. X
  1484. X    Lastrx = 0;
  1485. X    for(;;)
  1486. X    {
  1487. X        switch(firstch = readock(50,1))
  1488. X        {
  1489. X        case ZPAD:
  1490. X            if(getzrxinit())
  1491. X                return(ERROR);
  1492. X            Ascii = 0;    /* Receiver does the conversion */
  1493. X            return(FALSE);
  1494. X        case TIMEOUT:
  1495. X            report_str("Timeout",1);
  1496. X            return(TRUE);
  1497. X        case WANTG:
  1498. X#if defined(MODE2OK)
  1499. X            mode(2);    /* Set cbreak,XON/XOFF,etc. */
  1500. X#endif
  1501. X            Optiong = TRUE;
  1502. X            blklen=1024;
  1503. X        case WANTCRC:
  1504. X            Crcflg = TRUE;
  1505. X        case NAK:
  1506. X            return(FALSE);
  1507. X        case CAN:
  1508. X            if((firstch = readock(20,1)) == CAN && Lastrx == CAN)
  1509. X                return(TRUE);
  1510. X        default:
  1511. X            break;
  1512. X        }
  1513. X        Lastrx = firstch;
  1514. X    }
  1515. X    /*NOTREACHED*/
  1516. X}    /* end of getnak */
  1517. X
  1518. X
  1519. X/*+-------------------------------------------------------------------------
  1520. X    wctx(flen)
  1521. X--------------------------------------------------------------------------*/
  1522. Xwctx(flen)
  1523. Xlong flen;
  1524. X{
  1525. X    register int thisblklen;
  1526. X    register int firstch;
  1527. X    register int sectnum;
  1528. X    register int attempts;
  1529. X    long charssent;
  1530. X
  1531. X    charssent = 0;
  1532. X    firstsec=TRUE;
  1533. X    thisblklen = blklen;
  1534. X    report_txblklen(blklen);
  1535. X
  1536. X    attempts = 8;
  1537. X    while(((firstch = readock(Rxtimeout,2)) != NAK) &&
  1538. X        (firstch  !=  WANTCRC) && (firstch  !=  WANTG) &&
  1539. X        (firstch != TIMEOUT) && (firstch != CAN))
  1540. X    {
  1541. X        if(!--attempts)
  1542. X        {
  1543. X            report_str("bad start stimulus",1);
  1544. X            send_cancel(1);
  1545. X            return(ERROR);
  1546. X        }
  1547. X    }
  1548. X
  1549. X    if(firstch==CAN)
  1550. X    {
  1551. X        report_str("receiver CAN",1);
  1552. X        return(ERROR);
  1553. X    }
  1554. X
  1555. X    if((firstch==WANTCRC) || (firstch==WANTG))
  1556. X        Crcflg=TRUE;
  1557. X
  1558. X    report_protocol_crc_type((Crcflg)
  1559. X            ? ((firstch== WANTG) ? "/CRC-g" : "/CRC")
  1560. X            : "/CHK");
  1561. X
  1562. X    sectnum=0;
  1563. X    for(;;)
  1564. X    {
  1565. X        if(flen <= (charssent + 896L))
  1566. X        {
  1567. X            thisblklen = 128;
  1568. X            report_txblklen(thisblklen);
  1569. X        }
  1570. X        if(!xbuf_build(txbuf,thisblklen))
  1571. X            break;
  1572. X        if(wcputsec(txbuf,++sectnum,thisblklen)==ERROR)
  1573. X            return(ERROR);
  1574. X        charssent += thisblklen;
  1575. X    }
  1576. X
  1577. X    /* file transfer completed */
  1578. X    report_file_byte_io(this_file_length - initial_filepos);
  1579. X    report_file_close(0);
  1580. X    fclose(in);
  1581. X
  1582. X#if defined(LOG_XFER)
  1583. X    sprintf(s128,"SEND success: %s",Pathname);
  1584. X    ecu_log_event(getppid(),s128);
  1585. X#endif
  1586. X
  1587. X    attempts=0;
  1588. X    do
  1589. X    {
  1590. X        purgeline();
  1591. X        sendline(EOT);
  1592. X        flushline();
  1593. X        report_last_txhdr("EOT",0);
  1594. X        ++attempts;
  1595. X    }    while((firstch=(readock(Rxtimeout,1)) != ACK) && attempts < RETRYMAX);
  1596. X    if(attempts == RETRYMAX)
  1597. X    {
  1598. X        report_str("No ACK on EOT",1);
  1599. X        return(ERROR);
  1600. X    }
  1601. X    else
  1602. X        return(OK);
  1603. X}
  1604. X
  1605. X/*+-------------------------------------------------------------------------
  1606. X    wcputsec(buf,sectnum,cseclen)
  1607. X--------------------------------------------------------------------------*/
  1608. Xint
  1609. Xwcputsec(buf,sectnum,cseclen)
  1610. Xunsigned char *buf;
  1611. Xint sectnum;
  1612. Xint cseclen;    /* data length of this block to send */
  1613. X{
  1614. X    register int checksum;
  1615. X    register int wcj;
  1616. X    register unsigned char *cp;
  1617. X    unsigned short oldcrc;
  1618. X    int firstch;
  1619. X    int attempts;
  1620. X
  1621. X    firstch=0;    /* part of logic to detect CAN CAN */
  1622. X
  1623. X    sprintf(s128,"Sending block %d",sectnum);
  1624. X    report_last_txhdr(s128,0);
  1625. X    if(log_packets)
  1626. X    {
  1627. X        log_packet_buffer(buf,cseclen);
  1628. X    }
  1629. X
  1630. X    for(attempts=0; attempts <= RETRYMAX; attempts++)
  1631. X    {
  1632. X        Lastrx= firstch;
  1633. X        sendline(cseclen == 1024 ? STX : SOH);
  1634. X        sendline(sectnum);
  1635. X        sendline(-sectnum - 1);
  1636. X        oldcrc=checksum=0;
  1637. X
  1638. X        for(wcj = cseclen,cp = buf; --wcj >= 0; )
  1639. X        {
  1640. X            sendline(*cp);
  1641. X            oldcrc=updcrc(*cp,oldcrc);
  1642. X            checksum += *cp++;
  1643. X        }
  1644. X        if(Crcflg)
  1645. X        {
  1646. X            oldcrc=updcrc(0,updcrc(0,oldcrc));
  1647. X            sendline((int)(oldcrc >> 8));
  1648. X            sendline((int)(oldcrc & 0xFF));
  1649. X        }
  1650. X        else
  1651. X            sendline(checksum);
  1652. X        flushline();
  1653. X
  1654. X        if(Optiong)
  1655. X        {
  1656. X            firstsec = FALSE;
  1657. X            return(OK);
  1658. X        }
  1659. X        firstch = readock(Rxtimeout,(Noeofseen&§num) ? 2:1);
  1660. Xgotnak:
  1661. X        switch(firstch)
  1662. X        {
  1663. X        case CAN:
  1664. X            if(Lastrx == CAN)
  1665. X            {
  1666. Xcancan:
  1667. X                report_last_rxhdr("CAN",1);
  1668. X                return(ERROR);
  1669. X            }
  1670. X            break;
  1671. X        case TIMEOUT:
  1672. X            report_last_rxhdr("Timeout",1);
  1673. X            continue;
  1674. X        case WANTCRC:
  1675. X            if(firstsec)
  1676. X                Crcflg = TRUE;
  1677. X        case NAK:
  1678. X            report_last_rxhdr("NAK",1);
  1679. X            continue;
  1680. X        case ACK:
  1681. X            report_last_rxhdr("ACK",0);
  1682. X            firstsec=FALSE;
  1683. X            Totsecs += (cseclen>>7);
  1684. X            return(OK);
  1685. X        case ERROR:
  1686. X            report_last_rxhdr("Noise",0);
  1687. X            break;
  1688. X        default:
  1689. X            sprintf(s128,"0x%02x ???",firstch);
  1690. X            report_last_rxhdr(s128,1);
  1691. X            break;
  1692. X        }
  1693. X        for(;;)
  1694. X        {
  1695. X            Lastrx = firstch;
  1696. X            if((firstch = readock(Rxtimeout,2)) == TIMEOUT)
  1697. X                break;
  1698. X            if(firstch == NAK || firstch == WANTCRC)
  1699. X                goto gotnak;
  1700. X            if(firstch == CAN && Lastrx == CAN)
  1701. X                goto cancan;
  1702. X        }
  1703. X    }
  1704. X    report_str("retry count exceeded",1);
  1705. X    return(ERROR);
  1706. X}    /* end of wcputsec */
  1707. X
  1708. X
  1709. X/*+-------------------------------------------------------------------------
  1710. X    xbuf_build(buf,count)
  1711. X  fill buf with count chars padding with ^Z for CPM and DOS
  1712. X--------------------------------------------------------------------------*/
  1713. Xxbuf_build(buf,count)
  1714. Xregister char *buf;
  1715. Xint count;
  1716. X{
  1717. X    register c,m;
  1718. X    long lseek();
  1719. X    long X_txpos = lseek(fileno(in),0L,1);
  1720. X    char diag_str[64];
  1721. X
  1722. X    report_send_progress(X_txpos);
  1723. X    if( !Ascii)
  1724. X    {
  1725. X        m = read(fileno(in),buf,count);
  1726. X        if(log_packets)
  1727. X        {
  1728. X            sprintf(diag_str,"read rtnd %d of %d",m,count);
  1729. X            report_str(diag_str,1);
  1730. X        }
  1731. X        if(m <= 0)
  1732. X            return(0);
  1733. X        while(m < count)
  1734. X            buf[m++] = 032;
  1735. X        return(count);
  1736. X    }
  1737. X    m=count;
  1738. X    if(Lfseen)
  1739. X    {
  1740. X        *buf++ = 012;
  1741. X        --m;
  1742. X        Lfseen = 0;
  1743. X    }
  1744. X    while((c=fgetc(in))!=EOF)
  1745. X    {
  1746. X        if(c == 012)
  1747. X        {
  1748. X            *buf++ = 015;
  1749. X            if(--m == 0)
  1750. X            {
  1751. X                Lfseen = TRUE;
  1752. X                break;
  1753. X            }
  1754. X        }
  1755. X        *buf++ =c;
  1756. X        if(--m == 0)
  1757. X            break;
  1758. X    }
  1759. X    if(m==count)
  1760. X        return(0);
  1761. X    else
  1762. X        while(--m>=0)
  1763. X            *buf++ = CPMEOF;
  1764. X    return(count);
  1765. X}    /* end of xbuf_build */
  1766. X
  1767. X/*+-------------------------------------------------------------------------
  1768. X    zbuf_build(buf,count) - fill buf with count chars 
  1769. X--------------------------------------------------------------------------*/
  1770. Xint
  1771. Xzbuf_build(buf,count)
  1772. Xregister char *buf;
  1773. Xint count;
  1774. X{
  1775. X    register c,m;
  1776. X
  1777. X    m=count;
  1778. X    while((c=fgetc(in))!=EOF)
  1779. X    {
  1780. X        *buf++ =c;
  1781. X        if(--m == 0)
  1782. X            break;
  1783. X    }
  1784. X    return(count - m);
  1785. X}    /* end of zbuf_build */
  1786. X
  1787. X/*+-------------------------------------------------------------------------
  1788. X    SIGALRM_handler(sig)
  1789. X--------------------------------------------------------------------------*/
  1790. XSIGTYPE
  1791. XSIGALRM_handler(sig)
  1792. Xint sig;
  1793. X{
  1794. X    report_rx_ind(0);
  1795. X    report_tx_ind(0);
  1796. X    longjmp(tohere,-1);
  1797. X}    /* end of SIGALRM_handler */
  1798. X
  1799. X/*+-------------------------------------------------------------------------
  1800. X    readock(timeout,count)
  1801. Xtimeout is in tenths of seconds reads character(s) from file
  1802. Xdescriptor 'fd' read 'count' characters, (1 <= count <= 3) if more than
  1803. Xone received, return ERROR unless all are CAN normal response is NAK,
  1804. XACK, CAN, G or C
  1805. X--------------------------------------------------------------------------*/
  1806. Xint
  1807. Xreadock(timeout,count)
  1808. Xint timeout;
  1809. Xint count;
  1810. X{
  1811. X    VOLATILE int c;
  1812. X    static char byt[5];
  1813. X
  1814. X    if(setjmp(tohere))
  1815. X    {
  1816. X        report_str("TIMEOUT",1);
  1817. X        return(TIMEOUT);
  1818. X    }
  1819. X    c = timeout / 10;
  1820. X    if(c < 2)
  1821. X        c = 2;
  1822. X    signal(SIGALRM,SIGALRM_handler);
  1823. X    alarm(c);
  1824. X    c = read(iofd,byt,count);
  1825. X    alarm(0);
  1826. X    if(c < 1)
  1827. X        return(TIMEOUT);
  1828. X    rx_char_count += c;
  1829. X    if(c == 1)
  1830. X        return(byt[0] & 0xFF);
  1831. X    while(c)
  1832. X    {
  1833. X        if(byt[--c] != CAN)
  1834. X            return(ERROR);
  1835. X    }
  1836. X
  1837. X    return(CAN);
  1838. X}    /* end of readock */
  1839. X
  1840. X
  1841. X/*+-------------------------------------------------------------------------
  1842. X    readline(n)
  1843. X--------------------------------------------------------------------------*/
  1844. Xint
  1845. Xreadline(n)
  1846. Xint n;
  1847. X{
  1848. X    return(readock(n,1));
  1849. X}    /* end of readline */
  1850. X
  1851. X/*+-------------------------------------------------------------------------
  1852. X    purgeline()
  1853. X--------------------------------------------------------------------------*/
  1854. Xvoid
  1855. Xpurgeline()
  1856. X{
  1857. X    ioctl(iofd,TCFLSH,0);
  1858. X}    /* end of purgeline */
  1859. X
  1860. X
  1861. X/*+-------------------------------------------------------------------------
  1862. X    send_cancel(error) - send cancel to remote
  1863. X--------------------------------------------------------------------------*/
  1864. Xvoid
  1865. Xsend_cancel(error)
  1866. Xint error;
  1867. X{
  1868. X    static char canistr[] = {
  1869. X        24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
  1870. X    };
  1871. X    register char *cptr = canistr;
  1872. X
  1873. X    report_last_txhdr("^X CAN",!!error);
  1874. X    while(*cptr)
  1875. X        sendline(*cptr++);
  1876. X    flushline();
  1877. X}    /* end of send_cancel */
  1878. X
  1879. X
  1880. X/*+-------------------------------------------------------------------------
  1881. X    substr(str,str2) - searches for str2 in string str
  1882. X--------------------------------------------------------------------------*/
  1883. Xchar *
  1884. Xsubstr(str,str2)
  1885. Xregister char *str;
  1886. Xregister char *str2;
  1887. X{
  1888. X    register char *sptr;
  1889. X    register char *ssptr;
  1890. X
  1891. X    for(sptr = str; *str; str++)
  1892. X    {
  1893. X        if(*str == *str2)
  1894. X        {
  1895. X            sptr = str;
  1896. X            ssptr = str2;
  1897. X            while(1)
  1898. X            {
  1899. X                if(*ssptr == 0)
  1900. X                    return(str);
  1901. X                if(*sptr++ != *ssptr++)
  1902. X                    break;
  1903. X            }
  1904. X        }
  1905. X    }
  1906. X    return(NULL);
  1907. X}    /* end of substr */
  1908. X
  1909. X/*+-------------------------------------------------------------------------
  1910. X    usage()
  1911. X--------------------------------------------------------------------------*/
  1912. Xvoid
  1913. Xusage()
  1914. X{
  1915. X    exit(255);
  1916. X}    /* end of usage */
  1917. X
  1918. X/*+-------------------------------------------------------------------------
  1919. X    getzrxinit() - Get the receiver's init parameters
  1920. X--------------------------------------------------------------------------*/
  1921. Xint
  1922. Xgetzrxinit()
  1923. X{
  1924. X    register n;
  1925. X    struct stat f;
  1926. X
  1927. X    for(n=10; --n>=0; )
  1928. X    {
  1929. X        switch(zgethdr(Rxhdr,1))
  1930. X        {
  1931. X        case ZCHALLENGE:    /* Echo receiver's challenge numbr */
  1932. X            stohdr(Rxpos);
  1933. X            zshhdr(ZACK,Txhdr);
  1934. X            continue;
  1935. X        case ZCOMMAND:        /* They didn't see out ZRQINIT */
  1936. X            stohdr(0L);
  1937. X            zshhdr(ZRQINIT,Txhdr);
  1938. X            continue;
  1939. X        case ZRINIT:
  1940. X            Rxflags = 0377 & Rxhdr[ZF0];
  1941. X            Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32));
  1942. X            report_protocol_type("ZMODEM");
  1943. X            report_protocol_crc_type((Txfcs32) ? "/CRC32" : "/CRC16");
  1944. X            Zctlesc |= Rxflags & TESCCTL;
  1945. X            Rxbuflen = (0377 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8);
  1946. X            if( !(Rxflags & CANFDX))
  1947. X                Txwindow = 0;
  1948. X#if defined(MODE2OK)
  1949. X            mode(2);    /* Set cbreak,XON/XOFF,etc. */
  1950. X#endif
  1951. X#if !defined(READCHECK)
  1952. X            /* Use 1024 byte frames if no sample/interrupt */
  1953. X            if(Rxbuflen < 32 || Rxbuflen > 1024)
  1954. X            {
  1955. X                Rxbuflen = 1024;
  1956. X            }
  1957. X#endif
  1958. X            /* Override to force shorter frame length */
  1959. X            if(Rxbuflen && (Rxbuflen>Tframlen) && (Tframlen>=32))
  1960. X                Rxbuflen = Tframlen;
  1961. X            if( !Rxbuflen && (Tframlen>=32) && (Tframlen<=1024))
  1962. X                Rxbuflen = Tframlen;
  1963. X
  1964. X            /* If using a pipe for testing set lower buf len */
  1965. X            fstat(iofd,&f);
  1966. X            if((f.st_mode & S_IFMT) != S_IFCHR
  1967. X                && (Rxbuflen == 0 || Rxbuflen > 4096))
  1968. X                Rxbuflen = 4096;
  1969. X            sprintf(s128,"Remote: CRC32 %c  duplex %c",
  1970. X                (Rxflags & CANFC32) ? 'y' : 'n',
  1971. X                (Rxflags & CANFDX)  ? 'y' : 'n');
  1972. X            if(Rxbuflen)
  1973. X                sprintf(&s128[strlen(s128)],"  buflen %u",Rxbuflen);
  1974. X            else
  1975. X                strcat(s128,"  continuous stream y");
  1976. X            report_str(s128,2);
  1977. X            /*
  1978. X             * If input is not a regular file,force ACK's each 1024
  1979. X             *  (A smarter strategey could be used here ...)
  1980. X             */
  1981. X            if( !Command)
  1982. X            {
  1983. X                fstat(fileno(in),&f);
  1984. X                if(((f.st_mode & S_IFMT) != S_IFREG)
  1985. X                    && (Rxbuflen == 0 || Rxbuflen > 1024))
  1986. X                    Rxbuflen = 1024;
  1987. X            }
  1988. X
  1989. X            if(Baudrate > 300)    /* Set initial subpacket len */
  1990. X                blklen = 256;
  1991. X            if(Baudrate > 1200)
  1992. X                blklen = 512;
  1993. X            if(Baudrate >= 2400)    /* original code had > 2400 here ****/
  1994. X                blklen = 1024;
  1995. X            if(Rxbuflen && blklen>Rxbuflen)
  1996. X                blklen = Rxbuflen;
  1997. X            if(blkopt && blklen > blkopt)
  1998. X                blklen = blkopt;
  1999. X            blklen_original = blklen;
  2000. X            report_txblklen(blklen);
  2001. X            return(sendzsinit());
  2002. X        case ZCAN:
  2003. X        case TIMEOUT:
  2004. X            return(ERROR);
  2005. X        case ZRQINIT:
  2006. X            if(Rxhdr[ZF0] == ZCOMMAND)
  2007. X                continue;
  2008. X        default:
  2009. X            zshhdr(ZNAK,Txhdr);
  2010. X            continue;
  2011. X        }
  2012. X    }
  2013. X    return(ERROR);
  2014. X}    /* end of getzrxinit */
  2015. X
  2016. X
  2017. X/*+-------------------------------------------------------------------------
  2018. X    sendzsinit() - send send-init information
  2019. X--------------------------------------------------------------------------*/
  2020. Xsendzsinit()
  2021. X{
  2022. X    register c;
  2023. X
  2024. X    if(Myattn[0] == '\0' && (!Zctlesc || (Rxflags & TESCCTL)))
  2025. X        return(OK);
  2026. X    errors = 0;
  2027. X    for(;;)
  2028. X    {
  2029. X        stohdr(0L);
  2030. X        if(Zctlesc)
  2031. X        {
  2032. X            Txhdr[ZF0] |= TESCCTL;
  2033. X            zshhdr(ZSINIT,Txhdr);
  2034. X        }
  2035. X        else
  2036. X            zsbhdr(ZSINIT,Txhdr);
  2037. X        zsdata(Myattn,1+strlen(Myattn),ZCRCW);
  2038. X        c = zgethdr(Rxhdr,1);
  2039. X        switch(c)
  2040. X        {
  2041. X        case ZCAN:
  2042. X            return(ERROR);
  2043. X        case ZACK:
  2044. X            return(OK);
  2045. X        default:
  2046. X            if(++errors > 19)
  2047. X                return(ERROR);
  2048. X            continue;
  2049. X        }
  2050. X    }
  2051. X}    /* end of sendzsinit */
  2052. X
  2053. X/*+-------------------------------------------------------------------------
  2054. X    zsendfile(buf,blen) - send file name & info
  2055. X--------------------------------------------------------------------------*/
  2056. Xzsendfile(buf,blen)
  2057. Xchar *buf;
  2058. Xint blen;
  2059. X{
  2060. X    register c;
  2061. X
  2062. X    for(;;)
  2063. X    {
  2064. X        blklen = blklen_original;
  2065. X        report_txblklen(blklen);
  2066. X        Txhdr[ZF0] = Lzconv;    /* file conversion request */
  2067. X        Txhdr[ZF1] = Lzmanag;    /* file management request */
  2068. X        Txhdr[ZF2] = Lztrans;    /* file transport request */
  2069. X        Txhdr[ZF3] = 0;
  2070. X        zsbhdr(ZFILE,Txhdr);
  2071. X        zsdata(buf,blen,ZCRCW);
  2072. Xagain:
  2073. X        c = zgethdr(Rxhdr,1);
  2074. X        switch(c)
  2075. X        {
  2076. X        case ZRINIT:
  2077. X            while((c = readline(50)) > 0)
  2078. X                if(c == ZPAD)
  2079. X                {
  2080. X                    goto again;
  2081. X                }
  2082. X            /* **** FALL THRU TO **** */
  2083. X        default:
  2084. X            continue;
  2085. X        case ZCAN:
  2086. X        case TIMEOUT:
  2087. X        case ZABORT:
  2088. X        case ZFIN:
  2089. X            return(ERROR);
  2090. X        case ZSKIP:
  2091. X            report_file_close(3);
  2092. X            fclose(in);
  2093. X            return(c);
  2094. X        case ZRPOS:
  2095. X            if(!seen_zrpos)
  2096. X                initial_filepos = Rxpos;
  2097. X            seen_zrpos = 1;
  2098. X            /*
  2099. X             * Suppress zcrcw request otherwise triggered by
  2100. X             * lastyunc==bytcnt
  2101. X             */
  2102. X            Lastsync = (bytcnt = Txpos = Rxpos) -1;
  2103. X            fseek(in,Rxpos,0);
  2104. X            Dontread = FALSE;
  2105. X            report_send_progress(Txpos);
  2106. X            return(zsendfdata());
  2107. X        }
  2108. X    }
  2109. X}    /* end of zsendfile */
  2110. X
  2111. X/*+-------------------------------------------------------------------------
  2112. X    zsendfdata() - send data in the file
  2113. X--------------------------------------------------------------------------*/
  2114. Xzsendfdata()
  2115. X{
  2116. X    VOLATILE int c = 0,e,n;
  2117. X    VOLATILE int newcnt;
  2118. X    VOLATILE int long tcount = 0;
  2119. X    VOLATILE int junkcount;        /* Counts garbage chars received by TX */
  2120. X    VOLATILE int err;
  2121. X
  2122. X    Lrxpos = 0;
  2123. X    junkcount = 0;
  2124. X    SameZrposAgain = FALSE;        /* variable was named Beenhereb4 (wht) */
  2125. X    this_file_frame_count = 0;    /* we've sent no frames (wht) */
  2126. Xsomemore:
  2127. X    if(setjmp(intrjmp))
  2128. X    {
  2129. Xwaitack:
  2130. X        junkcount = 0;
  2131. X        c = getinsync(0);
  2132. Xgotack:
  2133. X        switch(c)
  2134. X        {
  2135. X        default:
  2136. X        case ZCAN:
  2137. X            report_rcvr_cancelled("zfdata-1");
  2138. X            report_file_close(4);
  2139. X            fclose(in);
  2140. X            return(ERROR);
  2141. X        case ZSKIP:
  2142. X            report_file_close(5);
  2143. X            fclose(in);
  2144. X            return(c);
  2145. X        case ZACK:
  2146. X        case ZRPOS:
  2147. X            if(!seen_zrpos)
  2148. X                initial_filepos = Rxpos;
  2149. X            seen_zrpos = 1;
  2150. X            break;
  2151. X        case ZRINIT:
  2152. X            return(OK);
  2153. X        }
  2154. X#if defined(READCHECK)
  2155. X        /*
  2156. X         * If the reverse channel can be tested for data,
  2157. X         *  this logic may be used to detect error packets
  2158. X         *  sent by the receiver, in place of setjmp/longjmp
  2159. X         *  rdchk(fdes) returns non 0 if a character is available
  2160. X         */
  2161. X        while(rdchk(iofd))
  2162. X        {
  2163. X            switch(readline(1))
  2164. X            {
  2165. X            case CAN:
  2166. X            case ZPAD:
  2167. X                c = getinsync(1);
  2168. X                goto gotack;
  2169. X            case XOFF:        /* Wait a while for an XON */
  2170. X            case XOFF|0200:
  2171. X                readline(100);
  2172. X            }
  2173. X        }
  2174. X#endif
  2175. X    }
  2176. X
  2177. X    newcnt = Rxbuflen;
  2178. X    Txwcnt = 0;
  2179. X    stohdr(Txpos);
  2180. X    zsbhdr(ZDATA,Txhdr);
  2181. X
  2182. X    do
  2183. X    {
  2184. X        if(Dontread)
  2185. X        {
  2186. X            n = Lastn;
  2187. X        } else
  2188. X        {
  2189. X            n = zbuf_build(txbuf,blklen);
  2190. X            Lastread = Txpos;
  2191. X            Lastn = n;
  2192. X        }
  2193. X        Dontread = FALSE;
  2194. X        if(n < blklen)
  2195. X            e = ZCRCE;
  2196. X        else if(junkcount > 3)
  2197. X            e = ZCRCW;
  2198. X        else if(bytcnt == Lastsync)
  2199. X            e = ZCRCW;
  2200. X        else if(Rxbuflen && (newcnt -= n) <= 0)
  2201. X            e = ZCRCW;
  2202. X        else if(Txwindow && (Txwcnt += n) >= Txwspac)
  2203. X        {
  2204. X            Txwcnt = 0;
  2205. X            e = ZCRCQ;
  2206. X        }
  2207. X        else
  2208. X            e = ZCRCG;
  2209. X        zsdata(txbuf,n,e);
  2210. X        this_file_frame_count++;        /* wht */
  2211. X        if(bad_condx_blklen)            /* wht */
  2212. X        {
  2213. X            /* if we have sent four frames since last ZRPOS to same pos (wht)*/
  2214. X            if((this_file_frame_count - bad_condx_frame_count) > 4) /*wht*/
  2215. X            {
  2216. X                if(blklen == bad_condx_blklen)
  2217. X                    bad_condx_blklen = 0;
  2218. X                else
  2219. X                {
  2220. X                    blklen *= 2;
  2221. X                    report_txblklen(blklen);
  2222. X                }
  2223. X                SameZrposAgain = 0;
  2224. X            }
  2225. X        }
  2226. X        bytcnt = Txpos += n;
  2227. X        report_send_progress(Txpos);
  2228. X        if(e == ZCRCW)
  2229. X            goto waitack;
  2230. X#if defined(READCHECK)
  2231. X        /*
  2232. X         * If the reverse channel can be tested for data,
  2233. X         *  this logic may be used to detect error packets
  2234. X         *  sent by the receiver,in place of setjmp/longjmp
  2235. X         *  rdchk(fdes) returns non 0 if a character is available
  2236. X         */
  2237. X        while(rdchk(iofd))
  2238. X        {
  2239. X            switch(readline(1))
  2240. X            {
  2241. X            case CAN:
  2242. X            case ZPAD:
  2243. X                c = getinsync(1);
  2244. X                if(c == ZACK)
  2245. X                    break;
  2246. X#if defined(TCFLSH)
  2247. X                ioctl(iofd,TCFLSH,1);
  2248. X#endif
  2249. X                /* zcrce - dinna wanna starta ping-pong game */
  2250. X                zsdata(txbuf,0,ZCRCE);
  2251. X                goto gotack;
  2252. X
  2253. X            case XOFF:        /* Wait a while for an XON */
  2254. X            case XOFF|0200:
  2255. X                readline(100);
  2256. X
  2257. X            default:
  2258. X                ++junkcount;
  2259. X            }
  2260. X        }
  2261. X#endif    /* READCHECK */
  2262. X        if(Txwindow)
  2263. X        {
  2264. X            while((tcount = Txpos - Lrxpos) >= Txwindow)
  2265. X            {
  2266. X                if(e != ZCRCQ)
  2267. X                    zsdata(txbuf,0,e = ZCRCQ);
  2268. X                c = getinsync(1);
  2269. X                if(c != ZACK)
  2270. X                {
  2271. X#if defined(TCFLSH)
  2272. X                    ioctl(iofd,TCFLSH,1);
  2273. X#endif
  2274. X                    zsdata(txbuf,0,ZCRCE);
  2275. X                    goto gotack;
  2276. X                }
  2277. X            }
  2278. X        }
  2279. X    } while(n == blklen);
  2280. X
  2281. X    for(;;)
  2282. X    {
  2283. X        stohdr(Txpos);
  2284. X        zsbhdr(ZEOF,Txhdr);
  2285. X        switch(err = getinsync(0))
  2286. X        {
  2287. X        case ZACK:
  2288. X            continue;
  2289. X        case ZRPOS:
  2290. X            if(!seen_zrpos)
  2291. X                initial_filepos = Rxpos;
  2292. X            seen_zrpos = 1;
  2293. X            goto somemore;
  2294. X        case ZRINIT:
  2295. X            return(OK);
  2296. X        case ZSKIP:
  2297. X            report_file_close(6);
  2298. X            fclose(in);
  2299. X            return(c);
  2300. X        default:
  2301. X            sprintf(s128,"SEND protocol sync error 0x%04x: %s",err,Pathname);
  2302. X            ecu_log_event(getppid(),s128);    /* always log this */
  2303. X            report_str(s128 + 5,1);
  2304. X            skip_count++;
  2305. X            report_error_count();
  2306. X            report_file_byte_io(this_file_length - initial_filepos);
  2307. X            report_file_close(7);
  2308. X            fclose(in);
  2309. X            return(ERROR);
  2310. X        }
  2311. X    }
  2312. X}    /* end of zsendfdata */
  2313. X
  2314. X/*+-------------------------------------------------------------------------
  2315. X    getinsync(flag) - get back in sync with receiver
  2316. X--------------------------------------------------------------------------*/
  2317. Xint
  2318. Xgetinsync(flag)
  2319. Xint flag;
  2320. X{
  2321. X    register c;
  2322. X
  2323. X    for(;;)
  2324. X    {
  2325. X        switch(c = zgethdr(Rxhdr,0))
  2326. X        {
  2327. X        case ZCAN:
  2328. X        case ZABORT:
  2329. X        case ZFIN:
  2330. X        case TIMEOUT:
  2331. X            sprintf(s128,"Receiver %s",frametypes[c+FTOFFSET]);
  2332. X            report_str(s128,1);
  2333. X            return(ERROR);
  2334. X        case ZRPOS:
  2335. X            report_str("Receiver ZRPOS",1);
  2336. X            if(!seen_zrpos)
  2337. X                initial_filepos = Rxpos;
  2338. X            seen_zrpos = 1;
  2339. X            /* ************************************* */
  2340. X            /*  If sending to a modem buffer,you     */
  2341. X            /*   might send a break at this point to */
  2342. X            /*   dump the modem's buffer.            */
  2343. X            /* ************************************* */
  2344. X            if(Lastn >= 0 && Lastread == Rxpos)
  2345. X            {
  2346. X                Dontread = TRUE;
  2347. X            } else
  2348. X            {
  2349. X                clearerr(in);    /* In case file EOF seen */
  2350. X                fseek(in,Rxpos,0);
  2351. X            }
  2352. X            bytcnt = Lrxpos = Txpos = Rxpos;
  2353. X            if(Lastsync == Rxpos)                    /* wht - original code */
  2354. X            {                                        /* wht - original code */
  2355. X                /* save frame count at time of each occurrence (wht) */
  2356. X                bad_condx_frame_count = this_file_frame_count;    /* wht */
  2357. X                /* save block length at time of error (wht) */
  2358. X                if(++SameZrposAgain > 4)            /* wht - original code */
  2359. X                {                                    /* wht */
  2360. X                    if(bad_condx_blklen == 0)        /* wht */
  2361. X                        bad_condx_blklen = blklen;    /* wht */
  2362. X                    if(blklen > 256)                /* wht - 32->256 */
  2363. X                    {
  2364. X                        blklen /= 2;                /* wht - original code */
  2365. X                        report_txblklen(blklen);
  2366. X                    }
  2367. X                }                                    /* wht */
  2368. X            }                                        /* wht - original code */
  2369. X            Lastsync = Rxpos;
  2370. X            report_send_progress(Txpos);
  2371. X            return(c);
  2372. X        case ZACK:
  2373. X            report_str("",-1);
  2374. X            Lrxpos = Rxpos;
  2375. X            if(flag || Txpos == Rxpos)
  2376. X                return(ZACK);
  2377. X            continue;
  2378. X
  2379. X        case ZRINIT:
  2380. X            report_str("",-1);
  2381. X#if defined(LOG_XFER)
  2382. X            sprintf(s128,"SEND success: %s",Pathname);
  2383. X            ecu_log_event(getppid(),s128);
  2384. X#endif
  2385. X        case ZSKIP:
  2386. X            report_file_byte_io(this_file_length);
  2387. X            report_file_close(0);
  2388. X            fclose(in);
  2389. X            return(c);
  2390. X        case ERROR:
  2391. X        default:
  2392. X            report_str("Sending ZNAK",0);
  2393. X            zsbhdr(ZNAK,Txhdr);
  2394. X            continue;
  2395. X        }
  2396. X    }
  2397. X}    /* end of getinsync */
  2398. X
  2399. X/*+-------------------------------------------------------------------------
  2400. X    saybibi() - Say "bibi" to the receiver, try to do it cleanly
  2401. X--------------------------------------------------------------------------*/
  2402. Xvoid
  2403. Xsaybibi()
  2404. X{
  2405. X    for(;;)
  2406. X    {
  2407. X        stohdr(0L);        /* CAF Was zsbhdr - minor change */
  2408. X        zshhdr(ZFIN,Txhdr);    /*  to make debugging easier */
  2409. X        switch(zgethdr(Rxhdr,0))
  2410. X        {
  2411. X        case ZFIN:
  2412. X            sendline('O');
  2413. X            sendline('O');
  2414. X            flushline();
  2415. X        case ZCAN:
  2416. X        case TIMEOUT:
  2417. X            return;
  2418. X        }
  2419. X    }
  2420. X}    /* end of saybibi */
  2421. X
  2422. X/*+-------------------------------------------------------------------------
  2423. X    determine_transaction_time()
  2424. X--------------------------------------------------------------------------*/
  2425. Xvoid
  2426. Xdetermine_transaction_time()
  2427. X{
  2428. Xregister c;
  2429. Xstruct stat f;
  2430. Xchar *name;
  2431. X
  2432. X    rewind_file_list();
  2433. X    TotalLeft = 0;
  2434. X    Filesleft = 0;
  2435. X    while(get_file_list_name(&name))
  2436. X    {
  2437. X        f.st_size = -1;
  2438. X        if((access(name,04) >= 0) && (stat(name,&f) >= 0))
  2439. X        {
  2440. X            c = f.st_mode & S_IFMT;
  2441. X            if(c != S_IFDIR && c != S_IFBLK)
  2442. X            {
  2443. X                ++Filesleft;
  2444. X                TotalLeft += f.st_size;
  2445. X            }
  2446. X        }
  2447. X    }
  2448. X    FilesTotal = Filesleft;
  2449. X    rewind_file_list();
  2450. X}    /* end of determine_transaction_time */
  2451. X
  2452. X/* vi: set tabstop=4 shiftwidth=4: */
  2453. X/* end of ecusz.c */
  2454. SHAR_EOF
  2455. chmod 0644 z/ecusz.c ||
  2456. echo 'restore of z/ecusz.c failed'
  2457. Wc_c="`wc -c < 'z/ecusz.c'`"
  2458. test 45023 -eq "$Wc_c" ||
  2459.     echo 'z/ecusz.c: original size 45023, current size' "$Wc_c"
  2460. rm -f _shar_wnt_.tmp
  2461. fi
  2462. # ============= z/zcommon.c ==============
  2463. if test -f 'z/zcommon.c' -a X"$1" != X"-c"; then
  2464.     echo 'x - skipping z/zcommon.c (File already exists)'
  2465.     rm -f _shar_wnt_.tmp
  2466. else
  2467. > _shar_wnt_.tmp
  2468. echo 'x - extracting z/zcommon.c (Text)'
  2469. sed 's/^X//' << 'SHAR_EOF' > 'z/zcommon.c' &&
  2470. X/*+-------------------------------------------------------------------------
  2471. X    zcommon.c -  ecurz/ecusz common code
  2472. X    derived from public domain code by Chuck Forsberg
  2473. X    ecu adaptation wht@n4hgf.Mt-Park.GA.US
  2474. X
  2475. X  Defined functions:
  2476. X    Nap(msec)
  2477. X    get_curr_dir(currdir,currdir_max)
  2478. X    get_home_dir(home_dir)
  2479. X    getspeed(code)
  2480. X    mode(new_mode)
  2481. X    rdchk(f)
  2482. X    sendbrk()
  2483. X    zmputs(str)
  2484. X
  2485. X--------------------------------------------------------------------------*/
  2486. X/*+:EDITS:*/
  2487. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  2488. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  2489. X/*:07-17-1992-18:28-wht@n4hgf-remove Nap() and use common ../nap.o */
  2490. SHAR_EOF
  2491. true || echo 'restore of z/zcommon.c failed'
  2492. fi
  2493. echo 'End of ecu320 part 24'
  2494. echo 'File z/zcommon.c is continued in part 25'
  2495. echo 25 > _shar_seq_.tmp
  2496. exit 0
  2497.  
  2498. exit 0 # Just in case...
  2499.