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

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