home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume13 / tipx / part03 < prev    next >
Encoding:
Text File  |  1990-05-29  |  58.7 KB  |  2,369 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v13i015: tipx (extended tip) part 03/04
  3. From: wht@gatech.edu@tridom.UUCP (Warren H. Tucker)
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 13, Issue 15
  7. Submitted-by: wht@gatech.edu@tridom.UUCP (Warren H. Tucker)
  8. Archive-name: tipx/part03
  9.  
  10. #!/bin/sh
  11. # This is part 03 of tipx
  12. if touch 2>&1 | fgrep 'mmdd' > /dev/null
  13.  then TOUCH=touch
  14.  else TOUCH=true
  15. fi
  16. # ============= xfer/tipsz.c ==============
  17. echo "x - extracting xfer/tipsz.c (Text)"
  18. sed 's/^X//' << 'SHAR_EOF' > xfer/tipsz.c &&
  19. Xchar *numeric_revision = "tipsz 1.00";
  20. X#define BUFFERED_WRITE
  21. X/*+-------------------------------------------------------------------------
  22. X    tipsz.c - X/Y/ZMODEM send program
  23. X  Derived from public domain source by Chuck Forsberg, Omen Technologies
  24. X  wht%n4hgf@emory.mathcs.emory.edu
  25. X
  26. X    Usage:    tipsz [-X -Y -Z] [-12+abdefkLlNnquvwy] [-] file ...
  27. X        (Y) = Option applies to YMODEM only
  28. X        (Z) = Option applies to ZMODEM only
  29. X        a (ASCII) change NL to CR/LF
  30. X        b Binary file transfer override
  31. X        f send Full pathname (Y/Z)
  32. X        k Send 1024 byte packets (Y)
  33. X        L N Limit subpacket length to N bytes (Z)
  34. X        l N Limit frame length to N bytes (l>=L) (Z)
  35. X        n send file if source newer (Z)
  36. X        N send file if source newer or longer (Z)
  37. X        o Use 16 bit CRC instead of 32 bit CRC (Z)
  38. X        p Protect existing destination file (Z)
  39. X        r Resume/Recover interrupted file transfer (Z)
  40. X        q Quiet (no progress reports)
  41. X        u Unlink file after transmission
  42. X        w N Window is N bytes (Z)
  43. X        y Yes,overwrite existing file (Z)
  44. X        @file reads a list of filenames from 'file'
  45. X
  46. X  Defined functions:
  47. X    SIGALRM_handler()
  48. X    bye_bye(sig)
  49. X    cancel_transaction(sig)
  50. X    determine_transaction_time()
  51. X    flushline()
  52. X    get_file_list_name(namep)
  53. X    getinsync(flag)
  54. X    getnak()
  55. X    getzrxinit()
  56. X    log_packet_buffer(buf,len)
  57. X    main(argc,argv)
  58. X    onintr()
  59. X    purgeline()
  60. X    readline(n)
  61. X    readock(timeout,count)
  62. X    report_rcvr_cancelled(place_happened)
  63. X    report_rcvr_skipped()
  64. X    report_send_stats(filepos)
  65. X    report_send_transaction()
  66. X    rewind_file_list()
  67. X    saybibi()
  68. X    send_cancel()
  69. X    sendline(ch)
  70. X    sendzsinit()
  71. X    set_file_list(pathc,pathv)
  72. X    substr(s,t)
  73. X    usage()
  74. X    wcputsec(buf,sectnum,cseclen)
  75. X    wcs(oname)
  76. X    wcsend()
  77. X    wctx(flen)
  78. X    wctxpn(name)
  79. X    xbuf_build(buf,count)
  80. X    xsendline(ch)
  81. X    zbuf_build(buf,count)
  82. X    zsendfdata()
  83. X    zsendfile(buf,blen)
  84. X
  85. X--------------------------------------------------------------------------*/
  86. X/*+:EDITS:*/
  87. X/*:05-21-1990-16:00-wht@tridom-adapt ecu xfer protocols for tipwht */
  88. X
  89. X/*
  90. X  Error return conditions
  91. X    255:     usage
  92. X    254:     protocol failed (bad line conditions,brain dead remote)
  93. X    253:     could not open any files
  94. X    128-192: process terminated with signal==code-128 (64 signals allowed for)
  95. X             signal 0 == program logic error (see cancel_transaction)
  96. X    127:     127 or more files not transmitted (see ~/.tip/log)
  97. X    1-126:   count of files not transmitted (see ~/.tip/log)
  98. X    0:       file transfer completely successful
  99. X*/
  100. X
  101. Xchar *substr(),*getenv();
  102. X
  103. X#include <stdio.h>
  104. X#include <signal.h>
  105. X#include <setjmp.h>
  106. X#include <ctype.h>
  107. X#include <fcntl.h>
  108. X#include "zmodem.h"
  109. X#include "zlint.h"
  110. X
  111. Xextern char *sys_errlist[];
  112. Xextern unsigned short crctab[];    /* wht */
  113. Xextern unsigned long total_data_chars_xfered; /* zcurses.c */
  114. Xextern int errno;
  115. Xextern int show_window;
  116. Xextern int Rxtimeout;    /* Tenths of seconds to wait for something */
  117. Xextern char Rxhdr[4];    /* Received header */
  118. Xextern char Txhdr[4];    /* Transmitted header */
  119. Xextern int Txfcs32;        /* TURE means send binary frames with 32 bit FCS */
  120. Xextern long Rxpos;    /* Received file position */
  121. Xextern long Txpos;    /* Transmitted file position */
  122. Xextern char *frametypes[];
  123. Xextern char Attn[];        /* Attention string rx sends to tx on err */
  124. Xextern char s256[];
  125. X
  126. X#define RETRYMAX 10        /* non-zmodem retry count on block send */
  127. X#define VMIN_COUNT 2    /* must not exceed 255 */
  128. Xunsigned char vmin_count = VMIN_COUNT;
  129. Xint iofd = 0;        /* line io fd */
  130. X#ifdef BUFFERED_WRITE
  131. XFILE *iofp;
  132. Xchar iofpbuf[256];
  133. X#endif
  134. X
  135. X
  136. X/*
  137. X * Attention string to be extipted by receiver to interrupt streaming data
  138. X *  when an error is detected.  A pause (0336) may be needed before the
  139. X *  ^C (03) or after it.
  140. X */
  141. X#if defined(READCHECK)
  142. Xchar Myattn[] = { 0 };
  143. X#else
  144. X#if defined(M_SYS5)
  145. Xchar Myattn[] = { 03,0336,0 };
  146. X#else
  147. Xchar Myattn[] = { 0 };
  148. X#endif
  149. X#endif
  150. X
  151. XFILE *in;
  152. X
  153. Xchar *Cmdstr;        /* Pointer to the command string */
  154. Xchar *bottom_label = (char *)0;
  155. Xchar Crcflg;
  156. Xchar Lastrx;
  157. Xchar Lzconv;        /* Local ZMODEM file conversion request */
  158. Xchar Lzmanag;        /* Local ZMODEM file management request */
  159. Xchar Lztrans;
  160. Xchar Pathname[PATHLEN];
  161. Xchar curr_dir[256];
  162. Xchar s128[128];
  163. Xchar txbuf[1024];
  164. Xchar zconv;                /* ZMODEM file conversion request */
  165. Xchar zmanag;            /* ZMODEM file management request */
  166. Xchar ztrans;            /* ZMODEM file transport request */
  167. Xint Ascii=0;            /* Add CR's for brain damaged programs */
  168. Xint Cmdack1;            /* Rx ACKs command,then do it */
  169. Xint Cmdtries = 11;
  170. Xint Command = 0;        /* Send a command,then exit. */
  171. Xint Dontread;            /* Don't read the buffer,it's still there */
  172. Xint Dottoslash=0;        /* Change foo.bar.baz to foo/bar/baz */
  173. Xint Exitcode = 0;
  174. Xint Filcnt=0;            /* count of number of files opened */
  175. Xint FilesTotal;
  176. Xint Filesleft;
  177. Xint Fullname=0;            /* transmit full pathname */
  178. Xint Lastn;                /* Count of last buffer read or -1 */
  179. Xint Lfseen=0;
  180. Xint Noeofseen;
  181. Xint Nozmodem = 0;
  182. Xint Optiong;            /* no wait for block ACK's */
  183. Xint Quiet=0;            /* overrides logic that would otherwise set verbose */
  184. Xint Rxflags = 0;
  185. Xint SameZrposAgain=0;    /* How many times we've been ZRPOS'd same place (wht) */
  186. Xint Tframlen = 0;        /* Override for tx frame length */
  187. Xint Totsecs;            /* total number of blocks this file */
  188. Xint Twostop = 0;        /* use two stop bits */
  189. Xint Unlinkafter=0;        /* Unlink file after it is sent */
  190. Xint Wantfcs32 = TRUE;    /* want to send 32 bit FCS */
  191. Xint Xmodem=0;            /* XMODEM Protocol - don't send pathnames */
  192. Xint Zctlesc;            /* Encode control characters */
  193. Xint Zmodem=0;            /* ZMODEM protocol requested by receiver */
  194. Xint Zrwindow = 1400;    /* RX window size (controls garbage count) */
  195. Xint blklen=128;            /* length of transmitted records */
  196. Xint blklen_original;
  197. Xint blkopt=0;            /* Override value for zmodem blklen */
  198. Xint tipsz_flag = 1;
  199. Xint skip_count = 0;        /* skipped files */
  200. Xint errors;
  201. Xint firstsec;
  202. Xint log_packets = 0;
  203. Xint no_files = 0;
  204. Xint npats = 0;
  205. Xlong Lastread;        /* Beginning offset of last buffer read */
  206. Xlong Lastsync;        /* Last offset to which we got a ZRPOS */
  207. Xlong Lrxpos;            /* Receiver's last reported offset */
  208. Xlong TotalLeft;
  209. Xlong TotalToSend;
  210. Xlong bytcnt;
  211. Xlong rx_char_count = 0L;
  212. Xlong this_file_length;
  213. Xlong tx_char_count = 0L;
  214. Xunsigned Baudrate;
  215. Xunsigned Rxbuflen = 16384;    /* Receiver's max buffer length */
  216. Xunsigned Txwcnt;        /* Counter used to space ack requests */
  217. Xunsigned Txwindow;        /* Control the size of the transmitted window */
  218. Xunsigned Txwspac;        /* Spacing between zcrcq requests */
  219. Xunsigned int bad_condx_blklen = 0;    /* if <>0,blklen has been reduced (wht) */
  220. Xunsigned int bad_condx_frame_count = 0;    /* frame # last SameZrposAgain (wht) */
  221. Xunsigned int this_file_frame_count;    /* count of frames sent this file (wht) */
  222. X
  223. X#define MAX_PATHS 512
  224. Xchar *paths[MAX_PATHS];
  225. X
  226. Xjmp_buf tohere;        /* For the interrupt on RX timeout */
  227. Xjmp_buf intrjmp;    /* For the interrupt on RX CAN */
  228. X
  229. Xint file_list_pathc;
  230. Xint file_list_path_current;
  231. Xchar **file_list_pathv;
  232. Xint required_type = 0;
  233. XFILE *fpflst = (FILE *)0;
  234. X
  235. X/*+-------------------------------------------------------------------------
  236. X    log_packet_buffer(buf,len)
  237. X--------------------------------------------------------------------------*/
  238. Xvoid
  239. Xlog_packet_buffer(buf,len)
  240. Xregister unsigned char *buf;
  241. Xregister int len;
  242. X{
  243. Xchar xbuf[32];
  244. X
  245. X    while(len--)
  246. X    {
  247. X        sprintf(xbuf,"%02x ",*buf++);
  248. X        write(log_packets,xbuf,strlen(xbuf));
  249. X    }
  250. X    write(log_packets,"\n",1);
  251. X
  252. X}    /* end of log_packet_buffer */
  253. X
  254. X/*+-------------------------------------------------------------------------
  255. X    rewind_file_list()
  256. X--------------------------------------------------------------------------*/
  257. Xvoid
  258. Xrewind_file_list()
  259. X{
  260. X    file_list_path_current = 0;
  261. X    if(fpflst)
  262. X    {
  263. X        fclose(fpflst);
  264. X        fpflst = (FILE *)0;
  265. X    }
  266. X}    /* end of rewind_file_list */
  267. X
  268. X/*+-------------------------------------------------------------------------
  269. X    set_file_list(pathc,pathv)
  270. X--------------------------------------------------------------------------*/
  271. Xvoid
  272. Xset_file_list(pathc,pathv)
  273. Xint pathc;
  274. Xchar **pathv;
  275. X{
  276. X
  277. X    file_list_pathc = pathc;
  278. X    file_list_pathv = pathv;
  279. X    rewind_file_list();
  280. X}    /* end of set_file_list */
  281. X
  282. X/*+-------------------------------------------------------------------------
  283. X    get_file_list_name(namep)
  284. X--------------------------------------------------------------------------*/
  285. Xget_file_list_name(namep)
  286. Xchar **namep;
  287. X{
  288. Xregister char *cptr;
  289. Xstatic char name[256];
  290. X
  291. Xtry_fpflst:
  292. X    if(fpflst)
  293. X    {
  294. X        if(fgets(name,sizeof(name),fpflst) != NULL)
  295. X        {
  296. X            name[strlen(name) - 1] = 0;
  297. X            *namep = name;
  298. X            return(1);
  299. X        }
  300. X        fclose(fpflst);
  301. X        fpflst = (FILE *)0;
  302. X    }
  303. X
  304. Xnext_arg:
  305. X    if(file_list_path_current == file_list_pathc)
  306. X        return(0);
  307. X    cptr = file_list_pathv[file_list_path_current++];
  308. X    if(*cptr != '@')
  309. X    {
  310. X        *namep = cptr;
  311. X        return(1);
  312. X    }
  313. X    cptr++;
  314. X    if((fpflst = fopen(cptr,"r")) == NULL)
  315. X        goto next_arg;
  316. X    goto try_fpflst;
  317. X
  318. X}    /* end of get_file_list_name */
  319. X
  320. X/*+-------------------------------------------------------------------------
  321. X    bye_bye(sig)
  322. X--------------------------------------------------------------------------*/
  323. Xvoid
  324. Xbye_bye(sig)
  325. Xint sig;
  326. X{
  327. X    exit(sig+128);
  328. X}    /* end of bye_bye */
  329. X
  330. X/*+-------------------------------------------------------------------------
  331. X    cancel_transaction(sig)
  332. Xcalled by signal interrupt or terminate to clean things up
  333. X--------------------------------------------------------------------------*/
  334. Xvoid
  335. Xcancel_transaction(sig)
  336. X{
  337. X    if(Zmodem)
  338. X        zmputs(Attn);
  339. X    send_cancel();
  340. X    mode(0);
  341. X    if(sig >= 0)
  342. X    {
  343. X        sprintf(s128,"tipsz aborted (signal %d)",sig);
  344. X        report_str(s128,0);
  345. X    }
  346. X    report_tx_ind(0);
  347. X    report_rx_ind(0);
  348. X    report_uninit(0);
  349. X    bye_bye(sig);
  350. X}    /* end of cancel_transaction */
  351. X
  352. X/* Called when ZMODEM gets an interrupt (^X) */
  353. Xonintr()
  354. X{
  355. X    signal(SIGINT,SIG_IGN);
  356. X#if defined(M_SYS5)
  357. X    report_rx_ind(0);
  358. X    report_tx_ind(0);
  359. X#endif
  360. X    longjmp(intrjmp,-1);
  361. X}
  362. X
  363. X
  364. X/*+-------------------------------------------------------------------------
  365. X    report_send_transaction()
  366. X--------------------------------------------------------------------------*/
  367. Xvoid
  368. Xreport_send_transaction()
  369. X{
  370. X    if(Xmodem)
  371. X    {
  372. X        long blocks = (TotalToSend >> 7) + ((TotalToSend % 128) != 0);
  373. X        long secs = 7        /* slightly worse than average first nak delay */
  374. X            + (blocks / 5L)                /* assume .2 sec ack time */
  375. X            + ((blocks * (128L + 16L)) / (Baudrate / 10));
  376. X        if(!secs)
  377. X            secs = 10L;
  378. X        sprintf(s128,"Sending %ld blocks time ~= %ld:%02ld",
  379. X            blocks,secs/60,secs % 60);
  380. X    }
  381. X    else
  382. X    {
  383. X        long min_100 =
  384. X            (FilesTotal * 2L) + (((TotalToSend * 11L)) * 10L) / (Baudrate * 6L);
  385. X        if(!min_100)
  386. X            min_100 = 4L;
  387. X#if defined(M_I286)    /* slower */
  388. X        else if(Baudrate > 4800)
  389. X        {
  390. X            min_100 *= 13;
  391. X            min_100 /= 9;    /* yech ... empirical */
  392. X        }
  393. X#endif
  394. X        sprintf(s128,"Sending %ld bytes  total time ~= %2lu:%02lu",
  395. X            TotalToSend,min_100 / 100,((min_100 % 100) * 60L) / 100L);
  396. X    }
  397. X    report_transaction(s128);
  398. X
  399. X}    /* end of report_send_transaction */
  400. X
  401. X/*+-------------------------------------------------------------------------
  402. X    report_send_stats(filepos)
  403. X--------------------------------------------------------------------------*/
  404. Xvoid
  405. Xreport_send_stats(filepos)
  406. Xlong filepos;
  407. X{
  408. X
  409. X    if(Xmodem)
  410. X        sprintf(s128,"File %d%% complete",
  411. X            (this_file_length == 0) ? (int)100 :
  412. X            (int)((filepos * 100L) / this_file_length));
  413. X    else
  414. X        sprintf(s128,"This file %d%%, transaction %d%% complete",
  415. X            (this_file_length == 0) ? (int)100 :
  416. X                    (int)((filepos * 100L)/this_file_length),
  417. X            (TotalToSend == 0) ? (int)100 :
  418. X                    (int)(((total_data_chars_xfered + filepos) * 100L)
  419. X                        / TotalToSend));
  420. X    report_str(s128,0);
  421. X    report_txpos(filepos);
  422. X
  423. X}    /* end of report_send_stats */
  424. X
  425. X/*+-------------------------------------------------------------------------
  426. X    report_rcvr_cancelled(place_happened)
  427. X--------------------------------------------------------------------------*/
  428. Xvoid
  429. Xreport_rcvr_cancelled(place_happened)
  430. Xchar *place_happened;
  431. X{
  432. X    strcpy(s128,"SEND CANCELLED");
  433. X    report_str(s128 + 5,1);
  434. X    skip_count++;
  435. X    report_error_count();
  436. X}    /* end of report_rcvr_cancelled */
  437. X
  438. X/*+-------------------------------------------------------------------------
  439. X    report_rcvr_skipped()
  440. X--------------------------------------------------------------------------*/
  441. Xvoid
  442. Xreport_rcvr_skipped()
  443. X{
  444. X    sprintf(s128,"SEND skipped: %s",Pathname);
  445. X    report_str(s128 + 5,-1);
  446. X    skip_count++;
  447. X    report_error_count();
  448. X    TotalToSend -= this_file_length;
  449. X    report_send_transaction();
  450. X}    /* end of report_rcvr_skipped */
  451. X
  452. X
  453. X/*+-------------------------------------------------------------------------
  454. X    xsendline(ch)
  455. X--------------------------------------------------------------------------*/
  456. Xxsendline(ch)
  457. Xchar ch;
  458. X{
  459. X#ifdef BUFFERED_WRITE
  460. X    fputc(ch,iofp);
  461. X#else
  462. X    write(iofd,&ch,1);
  463. X#endif
  464. X    ++tx_char_count;
  465. X}    /* end of xsendline */
  466. X
  467. X/*+-------------------------------------------------------------------------
  468. X    sendline(ch)
  469. X--------------------------------------------------------------------------*/
  470. Xsendline(ch)
  471. Xchar ch;
  472. X{
  473. X    xsendline(ch);
  474. X}    /* end of sendline */
  475. X
  476. Xflushline()
  477. X{
  478. X#ifdef BUFFERED_WRITE
  479. X    fflush(iofp);
  480. X#endif
  481. X}
  482. X
  483. Xmain(argc,argv)
  484. Xchar *argv[];
  485. X{
  486. Xregister char *cp;
  487. Xlong min_100;
  488. Xchar **patts = paths;
  489. Xchar **gargv = argv;
  490. Xint gargc = argc;
  491. X
  492. X    signal(SIGINT,bye_bye);
  493. X    signal(SIGTERM,bye_bye);
  494. X
  495. X    get_curr_dir(curr_dir,sizeof(curr_dir));
  496. X
  497. X    Rxtimeout = 600;
  498. X    npats=0;
  499. X    if(argc<2)
  500. X        usage();
  501. X    while(--argc)
  502. X    {
  503. X        cp = *++argv;
  504. X        if(*cp == '-')
  505. X        {
  506. X            cp++;
  507. X            switch(*cp++)
  508. X            {
  509. X            case 'X':
  510. X                required_type = 1;
  511. X                Xmodem = TRUE;
  512. X                break;
  513. X            case 'Y':
  514. X                required_type = 1;
  515. X                Nozmodem = TRUE;
  516. X                blklen=1024;
  517. X                break;
  518. X            case 'Z':
  519. X                show_window = 1;
  520. X                required_type = 1;
  521. X                break;
  522. X
  523. X            case '+':
  524. X                Lzmanag = ZMAPND;
  525. X                break;
  526. X            case 'a':
  527. X                Lzconv = ZCNL;
  528. X                Ascii = TRUE;
  529. X                break;
  530. X            case 'b':
  531. X                Lzconv = ZCBIN;
  532. X                break;
  533. X            case 'd':
  534. X                ++Dottoslash;
  535. X                /* **** FALL THROUGH TO **** */
  536. X            case 'f':
  537. X                Fullname=TRUE;
  538. X                break;
  539. X            case ',':
  540. X                log_packets = 1;
  541. X                break;
  542. X            case '/':
  543. X                if(--argc < 1)
  544. X                    usage();
  545. X                strcpy(curr_dir,*++argv);
  546. X                break;
  547. X            case '.':
  548. X                if(--argc < 1)
  549. X                    usage();
  550. X                iofd = atoi(*++argv);
  551. X                break;
  552. X            case 'C':
  553. X                if(--argc < 1)
  554. X                    usage("no label after -C");
  555. X                bottom_label = *++argv;
  556. X                break;
  557. X            case 'e':
  558. X                Zctlesc = 1;
  559. X                break;
  560. X            case 'k':
  561. X                blklen=1024;
  562. X                break;
  563. X            case 'L':
  564. X                if(--argc < 1)
  565. X                {
  566. X                    usage();
  567. X                }
  568. X                blkopt = atoi(*++argv);
  569. X                if(blkopt<24 || blkopt>1024)
  570. X                        usage();
  571. X                break;
  572. X            case 'l':
  573. X                if(--argc < 1)
  574. X                {
  575. X                    usage();
  576. X                }
  577. X                Tframlen = atoi(*++argv);
  578. X                if(Tframlen<32 || Tframlen>1024)
  579. X                    usage();
  580. X                break;
  581. X            case 'N':
  582. X                Lzmanag = ZMNEWL;
  583. X                break;
  584. X            case 'n':
  585. X                Lzmanag = ZMNEW;
  586. X                break;
  587. X            case 'o':
  588. X                Wantfcs32 = FALSE;
  589. X                break;
  590. X            case 'p':
  591. X                    Lzmanag = ZMPROT;
  592. X                    break;
  593. X            case 'r':
  594. X                Lzconv = ZCRESUM;
  595. X            case 't':
  596. X                if(--argc < 1)
  597. X                {
  598. X                    usage();
  599. X                }
  600. X                Rxtimeout = atoi(*++argv);
  601. X                if(Rxtimeout<10 || Rxtimeout>1000)
  602. X                    usage();
  603. X                break;
  604. X            case 'u':
  605. X                ++Unlinkafter;
  606. X                break;
  607. X            case 'w':
  608. X                if(--argc < 1)
  609. X                {
  610. X                    usage();
  611. X                }
  612. X                Txwindow = atoi(*++argv);
  613. X                if(Txwindow < 256)
  614. X                    Txwindow = 256;
  615. X                Txwindow = (Txwindow/64) * 64;
  616. X                Txwspac = Txwindow/4;
  617. X                if(blkopt > Txwspac || (!blkopt && Txwspac < 1024))
  618. X                    blkopt = Txwspac;
  619. X                break;
  620. X            case 'y':
  621. X                Lzmanag = ZMCLOB;
  622. X                break;
  623. X            default:
  624. X                usage();
  625. X            }
  626. X        }
  627. X        else if(argc > 0)
  628. X        {
  629. X            if(npats < MAX_PATHS)
  630. X            {
  631. X                npats++;
  632. X                *patts++ = cp;
  633. X            }
  634. X            else
  635. X            {
  636. X                printf("too many filenames to send\n");
  637. X                exit(255);
  638. X            }
  639. X        }
  640. X    }
  641. X    if(!required_type || !iofd)
  642. X    {
  643. X        printf("can only be run by tip\n");
  644. X        exit(255);
  645. X    }
  646. X
  647. X    if(npats < 1 && !Command)
  648. X        usage();
  649. X
  650. X    set_file_list(npats,paths);
  651. X    sprintf(s128,"%s",numeric_revision);
  652. X
  653. X    if(log_packets)
  654. X    {
  655. X    char log_packets_name[64];
  656. X    FILE *ftmp;
  657. X    int iargv;
  658. X        sprintf(log_packets_name,"/tmp/sz%05d.plog",getpid());
  659. X        unlink(log_packets_name);
  660. X        ftmp = fopen(log_packets_name,"w");
  661. X        fclose(ftmp);
  662. X        log_packets = open(log_packets_name,O_WRONLY,0644);
  663. X        if(log_packets < 0)
  664. X            log_packets = 0;
  665. X        else
  666. X        {
  667. X            write(log_packets,"exec: ",6);
  668. X            for(iargv = 0; iargv < gargc; iargv++)
  669. X            {
  670. X                write(log_packets,gargv[iargv],strlen(gargv[iargv]));
  671. X                write(log_packets," ",1);
  672. X            }
  673. X            write(log_packets,"\n",1);
  674. X        }
  675. X    }
  676. X
  677. X    report_init(s128);
  678. X    mode(1);
  679. X
  680. X    if(signal(SIGINT,cancel_transaction) == SIG_IGN)
  681. X        signal(SIGINT,SIG_IGN);
  682. X    else
  683. X        signal(SIGINT,cancel_transaction);
  684. X    signal(SIGTERM,cancel_transaction);
  685. X
  686. X    report_str("calculating transaction time",-1);
  687. X    determine_transaction_time();
  688. X#ifdef BUFFERED_WRITE
  689. X    iofp = fdopen(iofd,"w");
  690. X    setbuffer(iofp,iofpbuf,sizeof(iofpbuf));
  691. X#endif
  692. X    if(!Xmodem)
  693. X    {
  694. X        TotalToSend = TotalLeft;
  695. X        report_send_transaction();
  696. X        report_str("starting remote receiver",-1);
  697. X        if(!Nozmodem)
  698. X            write(iofd,"rz\r",3);
  699. X        else    /* wht -- why not? */
  700. X            write(iofd,"rb\r",3);        /* wht */
  701. X        sleep(2);
  702. X        report_str("beginning transfer",-1);
  703. X        if(!Nozmodem)
  704. X        {
  705. X            stohdr(0L);
  706. X            zshhdr(ZRQINIT,Txhdr);
  707. X        }
  708. X    }
  709. X    else
  710. X        report_str("beginning transfer",-1);
  711. X
  712. X    if(wcsend()==ERROR)
  713. X    {
  714. X        Exitcode=254;        /*wht was 0200 */
  715. X        send_cancel();
  716. X    }
  717. X    mode(0);
  718. X    report_uninit(0);
  719. X    if(no_files)
  720. X        Exitcode = 253;
  721. X    exit(Exitcode ? Exitcode : (skip_count > 127) ? 127 : skip_count);
  722. X    /*NOTREACHED*/
  723. X}
  724. X
  725. X/*+-------------------------------------------------------------------------
  726. X    wcsend(argc,argp) -- send group of files
  727. X--------------------------------------------------------------------------*/
  728. Xwcsend()
  729. X{
  730. X    register n;
  731. X    char *name;
  732. X
  733. X    Crcflg=FALSE;
  734. X    firstsec=TRUE;
  735. X    bytcnt = -1;
  736. X    rewind_file_list();
  737. X    while(get_file_list_name(&name))
  738. X    {
  739. X        Totsecs = 0;
  740. X        if(wcs(name)==ERROR)
  741. X            return(ERROR);
  742. X    }
  743. X    Totsecs = 0;
  744. X    if(Filcnt==0)
  745. X    {    /* bitch if we couldn't open ANY files */
  746. X        send_cancel();
  747. X        strcpy(s128,"SEND cannot open any requested files");
  748. X        report_str(s128 + 5,1);
  749. X        sleep(2);        /* allow time for other rz to get ready */
  750. X        no_files = 1;
  751. X        return(ERROR);    /* ... then cancel */
  752. X    }
  753. X    if(Zmodem)
  754. X        saybibi();
  755. X    else if(!Xmodem)
  756. X        wctxpn("");
  757. X    return(OK);
  758. X}
  759. X
  760. X/*+-------------------------------------------------------------------------
  761. X    wcs(oname) -- send a file
  762. X--------------------------------------------------------------------------*/
  763. Xwcs(oname)
  764. Xchar *oname;
  765. X{
  766. Xregister c;
  767. Xregister char *p;
  768. Xstruct stat f;
  769. X
  770. X    strcpy(Pathname,oname);    /* global copy of name */
  771. X
  772. X    if((in=fopen(oname,"r"))==NULL)
  773. X    {
  774. X        sprintf(s128,"SEND %s: %s",sys_errlist[errno],oname);
  775. X        report_str(s128 + 5,1);
  776. X        skip_count++;
  777. X        report_error_count();
  778. X        return(OK);    /* pass over it,there may be others */
  779. X    }
  780. X    ++Noeofseen;
  781. X    Lastread = 0;
  782. X    Lastn = -1;
  783. X    Dontread = FALSE;
  784. X    /* Check for directory or block special files */
  785. X    fstat(fileno(in),&f);
  786. X    c = f.st_mode & S_IFMT;
  787. X    if(c == S_IFDIR || c == S_IFBLK)
  788. X    {
  789. X        sprintf(s128,"SEND %s: %s",
  790. X            (c == S_IFDIR) ? "directory" : "block device",oname);
  791. X        report_str(s128 + 5,1);
  792. X        skip_count++;
  793. X        report_error_count();
  794. X        fclose(in);
  795. X        return(OK);
  796. X    }
  797. X    f.st_mode &= ~(S_ISUID | S_ISGID);
  798. X    Filcnt++;
  799. X    report_file_send_open(oname,&f);
  800. X    this_file_length = f.st_size;
  801. X    report_send_stats(0L);
  802. X    switch(wctxpn(Pathname))
  803. X    {
  804. X    case ERROR:
  805. X        sprintf(s128,"SEND protocol failure: %s",oname);
  806. X        report_str(s128 + 5,1);
  807. X        skip_count++;
  808. X        report_error_count();
  809. X        report_file_close();
  810. X        fclose(in);
  811. X        return(ERROR);
  812. X    case ZSKIP:
  813. X        report_rcvr_skipped();
  814. X        return(OK);
  815. X    }
  816. X    if(!Zmodem && wctx(f.st_size)==ERROR)
  817. X        return(ERROR);
  818. X    if(Unlinkafter)
  819. X        unlink(oname);
  820. X    return(0);
  821. X}
  822. X
  823. X/*
  824. X * generate and transmit pathname block consisting of
  825. X *  pathname (null terminated),
  826. X *  file length,mode time and file mode in octal
  827. X *  as provided by the Unix fstat call.
  828. X *  N.B.: modifies the passed name,may extend it!
  829. X */
  830. Xwctxpn(name)
  831. Xchar *name;
  832. X{
  833. X    register char *p,*q;
  834. X    char name2[PATHLEN];
  835. X    struct stat f;
  836. X
  837. X    if(Xmodem)
  838. X    {
  839. X        if((in!=stdin) && *name && fstat(fileno(in),&f)!= -1)
  840. X        {
  841. X            TotalToSend = f.st_size;
  842. X            report_protocol_type("XMODEM");
  843. X            report_send_transaction();
  844. X            report_xfer_mode((Ascii) ? "ASCII" : "BINARY");
  845. X            report_last_txhdr("Waiting on NAK",0);
  846. X        }
  847. X        return(OK);
  848. X    }
  849. X    if(!Zmodem)
  850. X    {
  851. X        report_last_txhdr("START PENDING",0);
  852. X        if(getnak())
  853. X        {
  854. X            report_str("Timeout on pathname nak",1);
  855. X            return(ERROR);
  856. X        }
  857. X    }
  858. X
  859. X    q = (char *) 0;
  860. X    if(Dottoslash)
  861. X    {        /* change . to . */
  862. X        for(p=name; *p; ++p)
  863. X        {
  864. X            if(*p == '/')
  865. X                q = p;
  866. X            else if(*p == '.')
  867. X                *(q=p) = '/';
  868. X        }
  869. X        if(q && strlen(++q) > 8)
  870. X        {    /* If name>8 chars */
  871. X            q += 8;            /*   make it .ext */
  872. X            strcpy(name2,q);    /* save excess of name */
  873. X            *q = '.';
  874. X            strcpy(++q,name2);    /* add it back */
  875. X        }
  876. X    }
  877. X
  878. X    for(p=name,q=txbuf ; *p; )
  879. X        if((*q++ = *p++) == '/' && !Fullname)
  880. X            q = txbuf;
  881. X    *q++ = 0;
  882. X    p=q;
  883. X    while(q < (txbuf + 1024))
  884. X        *q++ = 0;
  885. X    if(!Ascii && (in != stdin) && *name && !fstat(fileno(in),&f))
  886. X        sprintf(p,"%lu %lo %o 0 %d %ld",f.st_size,f.st_mtime,
  887. X            f.st_mode &= ~(S_ISUID | S_ISGID),
  888. X            Filesleft,TotalLeft);
  889. X    report_xfer_mode((Lzconv == ZCNL) ? "ASCII" : "BINARY");
  890. X    TotalLeft -= f.st_size;
  891. X    if(--Filesleft <= 0)
  892. X        TotalLeft = 0;
  893. X    if(TotalLeft < 0)
  894. X        TotalLeft = 0;
  895. X
  896. X    /* force 1k blocks if name won't fit in 128 byte block */
  897. X    if(txbuf[125])
  898. X        blklen=1024;
  899. X    else
  900. X    {        /* A little goodie for IMP/KMD */
  901. X        txbuf[127] = (f.st_size + 127) >>7;
  902. X        txbuf[126] = (f.st_size + 127) >>15;
  903. X    }
  904. X    if(Zmodem)
  905. X        return(zsendfile(txbuf,1+strlen(p)+(p-txbuf)));
  906. X    report_protocol_type("YMODEM");
  907. X    if(wcputsec(txbuf,0,128)==ERROR)
  908. X        return(ERROR);
  909. X    return(OK);
  910. X}
  911. X
  912. Xgetnak()
  913. X{
  914. X    register firstch;
  915. X
  916. X    Lastrx = 0;
  917. X    for(;;)
  918. X    {
  919. X        switch(firstch = readock(50,1))        /* 50 was 800 (80 secs!!) wht */
  920. X        {
  921. X        case ZPAD:
  922. X            if(getzrxinit())
  923. X                return(ERROR);
  924. X            Ascii = 0;    /* Receiver does the conversion */
  925. X            return(FALSE);
  926. X        case TIMEOUT:
  927. X            report_str("Timeout",1);
  928. X            return(TRUE);
  929. X        case WANTG:
  930. X#if defined(MODE2OK)
  931. X            mode(2);    /* Set cbreak,XON/XOFF,etc. */
  932. X#endif
  933. X            Optiong = TRUE;
  934. X            blklen=1024;
  935. X        case WANTCRC:
  936. X            Crcflg = TRUE;
  937. X        case NAK:
  938. X            return(FALSE);
  939. X        case CAN:
  940. X            if((firstch = readock(20,1)) == CAN && Lastrx == CAN)
  941. X                return(TRUE);
  942. X        default:
  943. X            break;
  944. X        }
  945. X        Lastrx = firstch;
  946. X    }
  947. X}
  948. X
  949. X/*+-------------------------------------------------------------------------
  950. X    wctx(flen)
  951. X--------------------------------------------------------------------------*/
  952. Xwctx(flen)
  953. Xlong flen;
  954. X{
  955. Xregister int thisblklen;
  956. Xregister int firstch;
  957. Xregister int sectnum;
  958. Xregister int attempts;
  959. Xlong charssent;
  960. X
  961. X    charssent = 0;
  962. X    firstsec=TRUE;
  963. X    thisblklen = blklen;
  964. X    report_txblklen(blklen);
  965. X
  966. X    attempts = 8;
  967. X    while(((firstch = readock(Rxtimeout,2)) != NAK) &&
  968. X        (firstch  !=  WANTCRC) && (firstch  !=  WANTG) &&
  969. X        (firstch != TIMEOUT) && (firstch != CAN))
  970. X    {
  971. X        if(!--attempts)
  972. X        {
  973. X            report_str("bad start stimulus",1);
  974. X            send_cancel();
  975. X            return(ERROR);
  976. X        }
  977. X    }
  978. X
  979. X    if(firstch==CAN)
  980. X    {
  981. X        report_str("receiver CAN",1);
  982. X        return(ERROR);
  983. X    }
  984. X
  985. X    if((firstch==WANTCRC) || (firstch==WANTG))
  986. X        Crcflg=TRUE;
  987. X
  988. X    report_protocol_crc_type((Crcflg)
  989. X            ? ((firstch== WANTG) ? "/CRC-g" : "/CRC")
  990. X            : "/CHK");
  991. X
  992. X    sectnum=0;
  993. X    for(;;)
  994. X    {
  995. X        if(flen <= (charssent + 896L))
  996. X        {
  997. X            thisblklen = 128;
  998. X            report_txblklen(thisblklen);
  999. X        }
  1000. X        if(!xbuf_build(txbuf,thisblklen))
  1001. X            break;
  1002. X        if(wcputsec(txbuf,++sectnum,thisblklen)==ERROR)
  1003. X            return(ERROR);
  1004. X        charssent += thisblklen;
  1005. X    }
  1006. X
  1007. X    /* file transfer completed */
  1008. X    report_file_byte_io(this_file_length);
  1009. X    report_file_close();
  1010. X    fclose(in);
  1011. X
  1012. X    attempts=0;
  1013. X    do
  1014. X    {
  1015. X        purgeline();
  1016. X        sendline(EOT);
  1017. X        flushline();
  1018. X        report_last_txhdr("EOT",0);
  1019. X        ++attempts;
  1020. X    }    while((firstch=(readock(Rxtimeout,1)) != ACK) && attempts < RETRYMAX);
  1021. X    if(attempts == RETRYMAX)
  1022. X    {
  1023. X        report_str("No ACK on EOT",1);
  1024. X        return(ERROR);
  1025. X    }
  1026. X    else
  1027. X        return(OK);
  1028. X}
  1029. X
  1030. Xwcputsec(buf,sectnum,cseclen)
  1031. Xunsigned char *buf;
  1032. Xint sectnum;
  1033. Xint cseclen;    /* data length of this block to send */
  1034. X{
  1035. X    register int checksum;
  1036. X    register int wcj;
  1037. X    register unsigned char *cp;
  1038. X    unsigned short oldcrc;
  1039. X    int firstch;
  1040. X    int attempts;
  1041. X
  1042. X    firstch=0;    /* part of logic to detect CAN CAN */
  1043. X
  1044. X    sprintf(s128,"Sending block %d",sectnum);
  1045. X    report_last_txhdr(s128,0);
  1046. X    if(log_packets)
  1047. X    {
  1048. X        log_packet_buffer(buf,cseclen);
  1049. X    }
  1050. X
  1051. X    for(attempts=0; attempts <= RETRYMAX; attempts++)
  1052. X    {
  1053. X        Lastrx= firstch;
  1054. X        sendline(cseclen == 1024 ? STX : SOH);
  1055. X        sendline(sectnum);
  1056. X        sendline(-sectnum - 1);
  1057. X        oldcrc=checksum=0;
  1058. X
  1059. X        for(wcj = cseclen,cp = buf; --wcj >= 0; )
  1060. X        {
  1061. X            sendline(*cp);
  1062. X            oldcrc=updcrc(*cp,oldcrc);
  1063. X            checksum += *cp++;
  1064. X        }
  1065. X        if(Crcflg)
  1066. X        {
  1067. X            oldcrc=updcrc(0,updcrc(0,oldcrc));
  1068. X            sendline((int)(oldcrc >> 8));
  1069. X            sendline((int)(oldcrc & 0xFF));
  1070. X        }
  1071. X        else
  1072. X            sendline(checksum);
  1073. X        flushline();
  1074. X
  1075. X        if(Optiong)
  1076. X        {
  1077. X            firstsec = FALSE;
  1078. X            return(OK);
  1079. X        }
  1080. X        firstch = readock(Rxtimeout,(Noeofseen&§num) ? 2:1);
  1081. Xgotnak:
  1082. X        switch(firstch)
  1083. X        {
  1084. X        case CAN:
  1085. X            if(Lastrx == CAN)
  1086. X            {
  1087. Xcancan:
  1088. X                report_last_rxhdr("CAN",1);
  1089. X                return(ERROR);
  1090. X            }
  1091. X            break;
  1092. X        case TIMEOUT:
  1093. X            report_last_rxhdr("Timeout",1);
  1094. X            continue;
  1095. X        case WANTCRC:
  1096. X            if(firstsec)
  1097. X                Crcflg = TRUE;
  1098. X        case NAK:
  1099. X            report_last_rxhdr("NAK",1);
  1100. X            continue;
  1101. X        case ACK:
  1102. X            report_last_rxhdr("ACK",0);
  1103. X            firstsec=FALSE;
  1104. X            Totsecs += (cseclen>>7);
  1105. X            return(OK);
  1106. X        case ERROR:
  1107. X            report_last_rxhdr("Noise",0);
  1108. X            break;
  1109. X        default:
  1110. X            sprintf(s128,"0x%02x ???",firstch);
  1111. X            report_last_rxhdr(s128,1);
  1112. X            break;
  1113. X        }
  1114. X        for(;;)
  1115. X        {
  1116. X            Lastrx = firstch;
  1117. X            if((firstch = readock(Rxtimeout,2)) == TIMEOUT)
  1118. X                break;
  1119. X            if(firstch == NAK || firstch == WANTCRC)
  1120. X                goto gotnak;
  1121. X            if(firstch == CAN && Lastrx == CAN)
  1122. X                goto cancan;
  1123. X        }
  1124. X    }
  1125. X    report_str("retry count exceeded",1);
  1126. X    return(ERROR);
  1127. X}
  1128. X
  1129. X/* fill buf with count chars padding with ^Z for CPM */
  1130. Xxbuf_build(buf,count)
  1131. Xregister char *buf;
  1132. X{
  1133. Xregister c,m;
  1134. Xlong lseek();
  1135. Xlong X_txpos = lseek(fileno(in),0L,1);
  1136. Xchar diag_str[64];
  1137. X
  1138. X    report_send_stats(X_txpos);
  1139. X    if( !Ascii)
  1140. X    {
  1141. X        m = read(fileno(in),buf,count);
  1142. X        if(log_packets)
  1143. X        {
  1144. X            sprintf(diag_str,"read rtnd %d of %d",m,count);
  1145. X            report_str(diag_str,1);
  1146. X        }
  1147. X        if(m <= 0)
  1148. X            return(0);
  1149. X        while(m < count)
  1150. X            buf[m++] = 032;
  1151. X        return(count);
  1152. X    }
  1153. X    m=count;
  1154. X    if(Lfseen)
  1155. X    {
  1156. X        *buf++ = 012;
  1157. X        --m;
  1158. X        Lfseen = 0;
  1159. X    }
  1160. X    while((c=getc(in))!=EOF)
  1161. X    {
  1162. X        if(c == 012)
  1163. X        {
  1164. X            *buf++ = 015;
  1165. X            if(--m == 0)
  1166. X            {
  1167. X                Lfseen = TRUE;
  1168. X                break;
  1169. X            }
  1170. X        }
  1171. X        *buf++ =c;
  1172. X        if(--m == 0)
  1173. X            break;
  1174. X    }
  1175. X    if(m==count)
  1176. X        return(0);
  1177. X    else
  1178. X        while(--m>=0)
  1179. X            *buf++ = CPMEOF;
  1180. X    return(count);
  1181. X}
  1182. X
  1183. X/*+-------------------------------------------------------------------------
  1184. X    zbuf_build(buf,count) - fill buf with count chars 
  1185. X--------------------------------------------------------------------------*/
  1186. Xzbuf_build(buf,count)
  1187. Xregister char *buf;
  1188. Xint count;
  1189. X{
  1190. Xregister c,m;
  1191. X
  1192. X    m=count;
  1193. X    while((c=getc(in))!=EOF)
  1194. X    {
  1195. X        *buf++ =c;
  1196. X        if(--m == 0)
  1197. X            break;
  1198. X    }
  1199. X    return(count - m);
  1200. X}    /* end of zbuf_build */
  1201. X
  1202. X/*+-------------------------------------------------------------------------
  1203. X    SIGALRM_handler()
  1204. X--------------------------------------------------------------------------*/
  1205. XSIGALRM_handler()
  1206. X{
  1207. X#if defined(M_SYS5)
  1208. X    report_rx_ind(0);
  1209. X    report_tx_ind(0);
  1210. X#endif
  1211. X    longjmp(tohere,-1);
  1212. X}    /* end of SIGALRM_handler */
  1213. X
  1214. X/*+-------------------------------------------------------------------------
  1215. X    readock(timeout,count)
  1216. Xtimeout is in tenths of seconds reads character(s) from file
  1217. Xdescriptor 'fd' read 'count' characters, (1 <= count <= 3) if more than
  1218. Xone received, return ERROR unless all are CAN normal response is NAK,
  1219. XACK, CAN, G or C
  1220. X--------------------------------------------------------------------------*/
  1221. Xreadock(timeout,count)
  1222. Xint timeout;
  1223. Xint count;
  1224. X{
  1225. X    register int c;
  1226. X    static char byt[5];
  1227. X
  1228. X    if(setjmp(tohere))
  1229. X    {
  1230. X        report_str("TIMEOUT",1);
  1231. X        return(TIMEOUT);
  1232. X    }
  1233. X    c = timeout/10;
  1234. X    if(c<2)
  1235. X        c = 2;
  1236. X    signal(SIGALRM,SIGALRM_handler);
  1237. X    alarm(c);
  1238. X#if defined(ONEREAD)
  1239. X    c=read(iofd,byt,1);        /* regulus raw read is unique */
  1240. X#else
  1241. X    c=read(iofd,byt,count);
  1242. X#endif
  1243. X    rx_char_count += c;
  1244. X    alarm(0);
  1245. X    if(c<1)
  1246. X        return(TIMEOUT);
  1247. X    if(c==1)
  1248. X        return(byt[0]&0377);
  1249. X    else
  1250. X        while(c)
  1251. X            if(byt[--c] != CAN)
  1252. X                return(ERROR);
  1253. X    return(CAN);
  1254. X}    /* end of readock */
  1255. X
  1256. X
  1257. X/*+-------------------------------------------------------------------------
  1258. X    readline(n)
  1259. X--------------------------------------------------------------------------*/
  1260. Xreadline(n)
  1261. Xint n;
  1262. X{
  1263. X    return(readock(n,1));
  1264. X}    /* end of readline */
  1265. X
  1266. X
  1267. X
  1268. X/*+-------------------------------------------------------------------------
  1269. X    purgeline()
  1270. X--------------------------------------------------------------------------*/
  1271. Xpurgeline()
  1272. X{
  1273. X#if defined(M_SYS5)
  1274. X    ioctl(iofd,TCFLSH,0);
  1275. X#else
  1276. X    lseek(iofd,0L,2);
  1277. X#endif
  1278. X}    /* end of purgeline */
  1279. X
  1280. X
  1281. X/*+-------------------------------------------------------------------------
  1282. X    send_cancel() - send cancel to remote
  1283. X--------------------------------------------------------------------------*/
  1284. Xsend_cancel()
  1285. X{
  1286. X    static char canistr[] =
  1287. X    {
  1288. X        24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
  1289. X    };
  1290. X    register char *cptr = canistr;
  1291. X
  1292. X    report_last_txhdr("^X CAN",1);
  1293. X    while(*cptr)
  1294. X        sendline(*cptr++);
  1295. X    flushline();
  1296. X}    /* end of send_cancel */
  1297. X
  1298. X
  1299. X/*+-------------------------------------------------------------------------
  1300. X    substr(str,substr) - searches for substr in string str
  1301. X--------------------------------------------------------------------------*/
  1302. Xchar *
  1303. Xsubstr(str,substr)
  1304. Xregister char *str,*substr;
  1305. X{
  1306. Xregister char *sptr;
  1307. Xregister char *ssptr;
  1308. X
  1309. X    for(sptr = str; *str; str++)
  1310. X    {
  1311. X        if(*str == *substr)
  1312. X        {
  1313. X            sptr = str;
  1314. X            ssptr = substr;
  1315. X            while(1)
  1316. X            {
  1317. X                if(*ssptr == 0)
  1318. X                    return(str);
  1319. X                if(*sptr++ != *ssptr++)
  1320. X                    break;
  1321. X            }
  1322. X        }
  1323. X    }
  1324. X    return(NULL);
  1325. X}    /* end of substr */
  1326. X
  1327. X/*+-------------------------------------------------------------------------
  1328. X    usage()
  1329. X--------------------------------------------------------------------------*/
  1330. Xusage()
  1331. X{
  1332. X    exit(255);
  1333. X}    /* end of usage */
  1334. X
  1335. X/*+-------------------------------------------------------------------------
  1336. X    getzrxinit() - Get the receiver's init parameters
  1337. X--------------------------------------------------------------------------*/
  1338. Xgetzrxinit()
  1339. X{
  1340. X    register n;
  1341. X    struct stat f;
  1342. X
  1343. X    for(n=10; --n>=0; )
  1344. X    {
  1345. X        switch(zgethdr(Rxhdr,1))
  1346. X        {
  1347. X        case ZCHALLENGE:    /* Echo receiver's challenge numbr */
  1348. X            stohdr(Rxpos);
  1349. X            zshhdr(ZACK,Txhdr);
  1350. X            continue;
  1351. X        case ZCOMMAND:        /* They didn't see out ZRQINIT */
  1352. X            stohdr(0L);
  1353. X            zshhdr(ZRQINIT,Txhdr);
  1354. X            continue;
  1355. X        case ZRINIT:
  1356. X            Rxflags = 0377 & Rxhdr[ZF0];
  1357. X            Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32));
  1358. X            report_protocol_type("ZMODEM");
  1359. X            report_protocol_crc_type((Txfcs32) ? "/CRC32" : "/CRC16");
  1360. X            Zctlesc |= Rxflags & TESCCTL;
  1361. X            Rxbuflen = (0377 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8);
  1362. X            if( !(Rxflags & CANFDX))
  1363. X                Txwindow = 0;
  1364. X#if defined(MODE2OK)
  1365. X            mode(2);    /* Set cbreak,XON/XOFF,etc. */
  1366. X#endif
  1367. X#if !defined(READCHECK)
  1368. X#if !defined(M_SYS5)
  1369. X            /* Use 1024 byte frames if no sample/interrupt */
  1370. X            if(Rxbuflen < 32 || Rxbuflen > 1024)
  1371. X            {
  1372. X                Rxbuflen = 1024;
  1373. X            }
  1374. X#endif
  1375. X#endif
  1376. X            /* Override to force shorter frame length */
  1377. X            if(Rxbuflen && (Rxbuflen>Tframlen) && (Tframlen>=32))
  1378. X                Rxbuflen = Tframlen;
  1379. X            if( !Rxbuflen && (Tframlen>=32) && (Tframlen<=1024))
  1380. X                Rxbuflen = Tframlen;
  1381. X
  1382. X            /* If using a pipe for testing set lower buf len */
  1383. X            fstat(iofd,&f);
  1384. X            if((f.st_mode & S_IFMT) != S_IFCHR
  1385. X                && (Rxbuflen == 0 || Rxbuflen > 4096))
  1386. X                Rxbuflen = 4096;
  1387. X            sprintf(s128,"Remote: CRC32 %c  duplex %c",
  1388. X                (Rxflags & CANFC32) ? 'y' : 'n',
  1389. X                (Rxflags & CANFDX)  ? 'y' : 'n');
  1390. X            if(Rxbuflen)
  1391. X                sprintf(&s128[strlen(s128)],"  buflen %u",Rxbuflen);
  1392. X            else
  1393. X                strcat(s128,"  continuous stream y");
  1394. X            report_str(s128,2);
  1395. X            /*
  1396. X             * If input is not a regular file,force ACK's each 1024
  1397. X             *  (A smarter strategey could be used here ...)
  1398. X             */
  1399. X            if( !Command)
  1400. X            {
  1401. X                fstat(fileno(in),&f);
  1402. X                if(((f.st_mode & S_IFMT) != S_IFREG)
  1403. X                    && (Rxbuflen == 0 || Rxbuflen > 1024))
  1404. X                    Rxbuflen = 1024;
  1405. X            }
  1406. X
  1407. X            if(Baudrate > 300)    /* Set initial subpacket len */
  1408. X                blklen = 256;
  1409. X            if(Baudrate > 1200)
  1410. X                blklen = 512;
  1411. X            if(Baudrate >= 2400)    /* original code had > 2400 here ****/
  1412. X                blklen = 1024;
  1413. X            if(Rxbuflen && blklen>Rxbuflen)
  1414. X                blklen = Rxbuflen;
  1415. X            if(blkopt && blklen > blkopt)
  1416. X                blklen = blkopt;
  1417. X            blklen_original = blklen;
  1418. X            report_txblklen(blklen);
  1419. X            return(sendzsinit());
  1420. X        case ZCAN:
  1421. X        case TIMEOUT:
  1422. X            return(ERROR);
  1423. X        case ZRQINIT:
  1424. X            if(Rxhdr[ZF0] == ZCOMMAND)
  1425. X                continue;
  1426. X        default:
  1427. X            zshhdr(ZNAK,Txhdr);
  1428. X            continue;
  1429. X        }
  1430. X    }
  1431. X    return(ERROR);
  1432. X}    /* end of getzrxinit */
  1433. X
  1434. X
  1435. X/*+-------------------------------------------------------------------------
  1436. X    sendzsinit() - send send-init information
  1437. X--------------------------------------------------------------------------*/
  1438. Xsendzsinit()
  1439. X{
  1440. X    register c;
  1441. X
  1442. X    if(Myattn[0] == '\0' && (!Zctlesc || (Rxflags & TESCCTL)))
  1443. X        return(OK);
  1444. X    errors = 0;
  1445. X    for(;;)
  1446. X    {
  1447. X        stohdr(0L);
  1448. X        if(Zctlesc)
  1449. X        {
  1450. X            Txhdr[ZF0] |= TESCCTL;
  1451. X            zshhdr(ZSINIT,Txhdr);
  1452. X        }
  1453. X        else
  1454. X            zsbhdr(ZSINIT,Txhdr);
  1455. X        zsdata(Myattn,1+strlen(Myattn),ZCRCW);
  1456. X        c = zgethdr(Rxhdr,1);
  1457. X        switch(c)
  1458. X        {
  1459. X        case ZCAN:
  1460. X            return(ERROR);
  1461. X        case ZACK:
  1462. X            return(OK);
  1463. X        default:
  1464. X            if(++errors > 19)
  1465. X                return(ERROR);
  1466. X            continue;
  1467. X        }
  1468. X    }
  1469. X}    /* end of sendzsinit */
  1470. X
  1471. X/*+-------------------------------------------------------------------------
  1472. X    zsendfile(buf,blen) - send file name & info
  1473. X--------------------------------------------------------------------------*/
  1474. Xzsendfile(buf,blen)
  1475. Xchar *buf;
  1476. Xint blen;
  1477. X{
  1478. X    register c;
  1479. X
  1480. X    for(;;)
  1481. X    {
  1482. X        blklen = blklen_original;
  1483. X        report_txblklen(blklen);
  1484. X        Txhdr[ZF0] = Lzconv;    /* file conversion request */
  1485. X        Txhdr[ZF1] = Lzmanag;    /* file management request */
  1486. X        Txhdr[ZF2] = Lztrans;    /* file transport request */
  1487. X        Txhdr[ZF3] = 0;
  1488. X        zsbhdr(ZFILE,Txhdr);
  1489. X        zsdata(buf,blen,ZCRCW);
  1490. Xagain:
  1491. X        c = zgethdr(Rxhdr,1);
  1492. X        switch(c)
  1493. X        {
  1494. X        case ZRINIT:
  1495. X            while((c = readline(50)) > 0)
  1496. X                if(c == ZPAD)
  1497. X                {
  1498. X                    goto again;
  1499. X                }
  1500. X            /* **** FALL THRU TO **** */
  1501. X        default:
  1502. X            continue;
  1503. X        case ZCAN:
  1504. X        case TIMEOUT:
  1505. X        case ZABORT:
  1506. X        case ZFIN:
  1507. X            return(ERROR);
  1508. X        case ZSKIP:
  1509. X            report_file_close();
  1510. X            fclose(in);
  1511. X            return(c);
  1512. X        case ZRPOS:
  1513. X            /*
  1514. X             * Suppress zcrcw request otherwise triggered by
  1515. X             * lastyunc==bytcnt
  1516. X             */
  1517. X            Lastsync = (bytcnt = Txpos = Rxpos) -1;
  1518. X            fseek(in,Rxpos,0);
  1519. X            Dontread = FALSE;
  1520. X            report_send_stats(Txpos);
  1521. X            return(zsendfdata());
  1522. X        }
  1523. X    }
  1524. X}    /* end of zsendfile */
  1525. X
  1526. X/*+-------------------------------------------------------------------------
  1527. X    zsendfdata() - send data in the file
  1528. X--------------------------------------------------------------------------*/
  1529. Xzsendfdata()
  1530. X{
  1531. Xregister c,e,n;
  1532. Xregister newcnt;
  1533. Xregister long tcount = 0;
  1534. Xint junkcount;        /* Counts garbage chars received by TX */
  1535. Xstatic int tleft = 6;    /* Counter for test mode */
  1536. Xint err;
  1537. X
  1538. X    Lrxpos = 0;
  1539. X    junkcount = 0;
  1540. X    SameZrposAgain = FALSE;        /* variable was named Beenhereb4 (wht) */
  1541. X    this_file_frame_count = 0;    /* we've sent no frames (wht) */
  1542. Xsomemore:
  1543. X    if(setjmp(intrjmp))
  1544. X    {
  1545. Xwaitack:
  1546. X        junkcount = 0;
  1547. X        c = getinsync(0);
  1548. Xgotack:
  1549. X        switch(c)
  1550. X        {
  1551. X        default:
  1552. X        case ZCAN:
  1553. X            report_rcvr_cancelled("zfdata-1");
  1554. X            report_file_close();
  1555. X            fclose(in);
  1556. X            return(ERROR);
  1557. X        case ZSKIP:
  1558. X            report_file_close();
  1559. X            fclose(in);
  1560. X            return(c);
  1561. X        case ZACK:
  1562. X        case ZRPOS:
  1563. X            break;
  1564. X        case ZRINIT:
  1565. X            return(OK);
  1566. X        }
  1567. X#if defined(READCHECK)
  1568. X        /*
  1569. X         * If the reverse channel can be tested for data,
  1570. X         *  this logic may be used to detect error packets
  1571. X         *  sent by the receiver,in place of setjmp/longjmp
  1572. X         *  rdchk(fdes) returns non 0 if a character is available
  1573. X         */
  1574. X        while(rdchk(iofd))
  1575. X        {
  1576. X            switch(readline(1))
  1577. X            {
  1578. X            case CAN:
  1579. X            case ZPAD:
  1580. X                c = getinsync(1);
  1581. X                goto gotack;
  1582. X            case XOFF:        /* Wait a while for an XON */
  1583. X            case XOFF|0200:
  1584. X                readline(100);
  1585. X            }
  1586. X        }
  1587. X#endif
  1588. X    }
  1589. X
  1590. X    newcnt = Rxbuflen;
  1591. X    Txwcnt = 0;
  1592. X    stohdr(Txpos);
  1593. X    zsbhdr(ZDATA,Txhdr);
  1594. X
  1595. X    do
  1596. X    {
  1597. X        if(Dontread)
  1598. X        {
  1599. X            n = Lastn;
  1600. X        } else
  1601. X        {
  1602. X            n = zbuf_build(txbuf,blklen);
  1603. X            Lastread = Txpos;
  1604. X            Lastn = n;
  1605. X        }
  1606. X        Dontread = FALSE;
  1607. X        if(n < blklen)
  1608. X            e = ZCRCE;
  1609. X        else if(junkcount > 3)
  1610. X            e = ZCRCW;
  1611. X        else if(bytcnt == Lastsync)
  1612. X            e = ZCRCW;
  1613. X        else if(Rxbuflen && (newcnt -= n) <= 0)
  1614. X            e = ZCRCW;
  1615. X        else if(Txwindow && (Txwcnt += n) >= Txwspac)
  1616. X        {
  1617. X            Txwcnt = 0;
  1618. X            e = ZCRCQ;
  1619. X        }
  1620. X        else
  1621. X            e = ZCRCG;
  1622. X        zsdata(txbuf,n,e);
  1623. X        this_file_frame_count++;        /* wht */
  1624. X        if(bad_condx_blklen)            /* wht */
  1625. X        {
  1626. X            /* if we have sent four frames since last ZRPOS to same pos (wht)*/
  1627. X            if((this_file_frame_count - bad_condx_frame_count) > 4) /*wht*/
  1628. X            {
  1629. X                if(blklen == bad_condx_blklen)
  1630. X                    bad_condx_blklen = 0;
  1631. X                else
  1632. X                {
  1633. X                    blklen *= 2;
  1634. X                    report_txblklen(blklen);
  1635. X                }
  1636. X                SameZrposAgain = 0;
  1637. X            }
  1638. X        }
  1639. X        bytcnt = Txpos += n;
  1640. X        report_send_stats(Txpos);
  1641. X        if(e == ZCRCW)
  1642. X            goto waitack;
  1643. X#if defined(READCHECK)
  1644. X        /*
  1645. X         * If the reverse channel can be tested for data,
  1646. X         *  this logic may be used to detect error packets
  1647. X         *  sent by the receiver,in place of setjmp/longjmp
  1648. X         *  rdchk(fdes) returns non 0 if a character is available
  1649. X         */
  1650. X        while(rdchk(iofd))
  1651. X        {
  1652. X            switch(readline(1))
  1653. X            {
  1654. X            case CAN:
  1655. X            case ZPAD:
  1656. X                c = getinsync(1);
  1657. X                if(c == ZACK)
  1658. X                    break;
  1659. X#if defined(TCFLSH)
  1660. X                ioctl(iofd,TCFLSH,1);
  1661. X#endif
  1662. X                /* zcrce - dinna wanna starta ping-pong game */
  1663. X                zsdata(txbuf,0,ZCRCE);
  1664. X                goto gotack;
  1665. X
  1666. X            case XOFF:        /* Wait a while for an XON */
  1667. X            case XOFF|0200:
  1668. X                readline(100);
  1669. X
  1670. X            default:
  1671. X                ++junkcount;
  1672. X            }
  1673. X        }
  1674. X#endif    /* READCHECK */
  1675. X        if(Txwindow)
  1676. X        {
  1677. X            while((tcount = Txpos - Lrxpos) >= Txwindow)
  1678. X            {
  1679. X                if(e != ZCRCQ)
  1680. X                    zsdata(txbuf,0,e = ZCRCQ);
  1681. X                c = getinsync(1);
  1682. X                if(c != ZACK)
  1683. X                {
  1684. X#if defined(TCFLSH)
  1685. X                    ioctl(iofd,TCFLSH,1);
  1686. X#endif
  1687. X                    zsdata(txbuf,0,ZCRCE);
  1688. X                    goto gotack;
  1689. X                }
  1690. X            }
  1691. X        }
  1692. X    } while(n == blklen);
  1693. X
  1694. X    for(;;)
  1695. X    {
  1696. X        stohdr(Txpos);
  1697. X        zsbhdr(ZEOF,Txhdr);
  1698. X        switch(err = getinsync(0))
  1699. X        {
  1700. X        case ZACK:
  1701. X            continue;
  1702. X        case ZRPOS:
  1703. X            goto somemore;
  1704. X        case ZRINIT:
  1705. X            return(OK);
  1706. X        case ZSKIP:
  1707. X            report_file_close();
  1708. X            fclose(in);
  1709. X            return(c);
  1710. X        default:
  1711. X            sprintf(s128,"SEND protocol sync error 0x%04x: %s",err,Pathname);
  1712. X            report_str(s128 + 5,1);
  1713. X            skip_count++;
  1714. X            report_error_count();
  1715. X            report_file_byte_io(this_file_length);
  1716. X            report_file_close();
  1717. X            fclose(in);
  1718. X            return(ERROR);
  1719. X        }
  1720. X    }
  1721. X}    /* end of zsendfdata */
  1722. X
  1723. X/*+-------------------------------------------------------------------------
  1724. X    getinsync(flag) - get back in sync with receiver
  1725. X--------------------------------------------------------------------------*/
  1726. Xgetinsync(flag)
  1727. X{
  1728. X    register c;
  1729. X
  1730. X    for(;;)
  1731. X    {
  1732. X        switch(c = zgethdr(Rxhdr,0))
  1733. X        {
  1734. X        case ZCAN:
  1735. X        case ZABORT:
  1736. X        case ZFIN:
  1737. X        case TIMEOUT:
  1738. X            sprintf(s128,"Receiver %s",frametypes[c+FTOFFSET]);
  1739. X            report_str(s128,1);
  1740. X            return(ERROR);
  1741. X        case ZRPOS:
  1742. X            report_str("Receiver ZRPOS",1);
  1743. X            /* ************************************* */
  1744. X            /*  If sending to a modem buffer,you    */
  1745. X            /*   might send a break at this point to */
  1746. X            /*   dump the modem's buffer.            */
  1747. X            /* ************************************* */
  1748. X            if(Lastn >= 0 && Lastread == Rxpos)
  1749. X            {
  1750. X                Dontread = TRUE;
  1751. X            } else
  1752. X            {
  1753. X                clearerr(in);    /* In case file EOF seen */
  1754. X                fseek(in,Rxpos,0);
  1755. X            }
  1756. X            bytcnt = Lrxpos = Txpos = Rxpos;
  1757. X            if(Lastsync == Rxpos)                    /* wht - original code */
  1758. X            {                                        /* wht - original code */
  1759. X                /* save frame count at time of each occurrence (wht) */
  1760. X                bad_condx_frame_count = this_file_frame_count;    /* wht */
  1761. X                /* save block length at time of error (wht) */
  1762. X                if(++SameZrposAgain > 4)            /* wht - original code */
  1763. X                {                                    /* wht */
  1764. X                    if(bad_condx_blklen == 0)        /* wht */
  1765. X                        bad_condx_blklen = blklen;    /* wht */
  1766. X                    if(blklen > 256)                /* wht - 32->256 */
  1767. X                    {
  1768. X                        blklen /= 2;                /* wht - original code */
  1769. X                        report_txblklen(blklen);
  1770. X                    }
  1771. X                }                                    /* wht */
  1772. X            }                                        /* wht - original code */
  1773. X            Lastsync = Rxpos;
  1774. X            report_send_stats(Txpos);
  1775. X            return(c);
  1776. X        case ZACK:
  1777. X            Lrxpos = Rxpos;
  1778. X            if(flag || Txpos == Rxpos)
  1779. X                return(ZACK);
  1780. X            continue;
  1781. X
  1782. X        case ZRINIT:
  1783. X        case ZSKIP:
  1784. X            report_file_byte_io(this_file_length);
  1785. X            report_file_close();
  1786. X            fclose(in);
  1787. X            return(c);
  1788. X        case ERROR:
  1789. X        default:
  1790. X            report_str("Sending ZNAK",1);
  1791. X            zsbhdr(ZNAK,Txhdr);
  1792. X            continue;
  1793. X        }
  1794. X    }
  1795. X}    /* end of getinsync */
  1796. X
  1797. X/*+-------------------------------------------------------------------------
  1798. X    saybibi() - Say "bibi" to the receiver, try to do it cleanly
  1799. X--------------------------------------------------------------------------*/
  1800. Xsaybibi()
  1801. X{
  1802. X    for(;;)
  1803. X    {
  1804. X        stohdr(0L);        /* CAF Was zsbhdr - minor change */
  1805. X        zshhdr(ZFIN,Txhdr);    /*  to make debugging easier */
  1806. X        switch(zgethdr(Rxhdr,0))
  1807. X        {
  1808. X        case ZFIN:
  1809. X            sendline('O');
  1810. X            sendline('O');
  1811. X            flushline();
  1812. X        case ZCAN:
  1813. X        case TIMEOUT:
  1814. X            return;
  1815. X        }
  1816. X    }
  1817. X}    /* end of saybibi */
  1818. X
  1819. X/*+-------------------------------------------------------------------------
  1820. X    determine_transaction_time()
  1821. X--------------------------------------------------------------------------*/
  1822. Xdetermine_transaction_time()
  1823. X{
  1824. Xregister c;
  1825. Xstruct stat f;
  1826. Xchar *name;
  1827. X
  1828. X    rewind_file_list();
  1829. X    TotalLeft = 0;
  1830. X    Filesleft = 0;
  1831. X    while(get_file_list_name(&name))
  1832. X    {
  1833. X        f.st_size = -1;
  1834. X        if((access(name,04) >= 0) && (stat(name,&f) >= 0))
  1835. X        {
  1836. X            c = f.st_mode & S_IFMT;
  1837. X            if(c != S_IFDIR && c != S_IFBLK)
  1838. X            {
  1839. X                ++Filesleft;
  1840. X                TotalLeft += f.st_size;
  1841. X            }
  1842. X        }
  1843. X    }
  1844. X    FilesTotal = Filesleft;
  1845. X    rewind_file_list();
  1846. X}    /* end of determine_transaction_time */
  1847. X
  1848. X/* vi: set tabstop=4 shiftwidth=4: */
  1849. X/* end of tipsz.c */
  1850. SHAR_EOF
  1851. $TOUCH -am 0521192790 xfer/tipsz.c &&
  1852. chmod 0644 xfer/tipsz.c ||
  1853. echo "restore of xfer/tipsz.c failed"
  1854. set `wc -c xfer/tipsz.c`;Wc_c=$1
  1855. if test "$Wc_c" != "40783"; then
  1856.     echo original size 40783, current size $Wc_c
  1857. fi
  1858. # ============= xfer/zcommon.c ==============
  1859. echo "x - extracting xfer/zcommon.c (Text)"
  1860. sed 's/^X//' << 'SHAR_EOF' > xfer/zcommon.c &&
  1861. X/*+-------------------------------------------------------------------------
  1862. X    zcommon.c -  tiprz/tipsz common code
  1863. X    derived from public domain code by Chuck Forsberg
  1864. X    tip adaptation by wht%n4hgf@emory.mathcs.emory.edu
  1865. X
  1866. X  Defined functions:
  1867. X    cancel_transaction(0)
  1868. X    get_curr_dir(currdir,currdir_max)
  1869. X    get_home_dir(home_dir)
  1870. X    getspeed(code)
  1871. X    mode(new_mode)
  1872. X    rdchk(f)
  1873. X    rdchk(f)
  1874. X    sendbrk()
  1875. X    zmputs(str)
  1876. X
  1877. X--------------------------------------------------------------------------*/
  1878. X/*+:EDITS:*/
  1879. X/*:05-21-1990-16:00-wht@tridom-adapt ecu xfer protocols for tipwht */
  1880. X
  1881. X#include <stdio.h>
  1882. X#include <signal.h>
  1883. X#include <setjmp.h>
  1884. X#include <ctype.h>
  1885. X#include <pwd.h>
  1886. X#include "zmodem.h"
  1887. X
  1888. Xextern unsigned char vmin_count;
  1889. Xextern int Zmodem;
  1890. Xextern unsigned Baudrate;
  1891. Xextern int Twostop;        /* Use two stop bits */
  1892. X
  1893. X#if defined(LLITOUT)
  1894. Xlong Locmode;        /* Saved "local mode" for 4.x BSD "new driver" */
  1895. Xlong Locbit = LLITOUT;    /* Bit SUPPOSED to disable output translations */
  1896. X#endif
  1897. X
  1898. Xstruct 
  1899. X{
  1900. X    unsigned baudr;
  1901. X    int speedcode;
  1902. X} speeds[] = 
  1903. X{
  1904. X    110,    B110,
  1905. X    300,    B300,
  1906. X    600,    B600,
  1907. X    1200,    B1200,
  1908. X    2400,    B2400,
  1909. X    4800,    B4800,
  1910. X    9600,    B9600,
  1911. X    19200,    EXTA,
  1912. X    38400,    EXTB,
  1913. X    0,
  1914. X};
  1915. X
  1916. X/* crctab calculated by Mark G. Mendel,Network Systems Corporation */
  1917. Xunsigned short crctab[256] = 
  1918. X{
  1919. X    0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
  1920. X    0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
  1921. X    0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
  1922. X    0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
  1923. X    0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
  1924. X    0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
  1925. X    0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
  1926. X    0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
  1927. X    0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
  1928. X    0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
  1929. X    0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
  1930. X    0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
  1931. X    0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
  1932. X    0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
  1933. X    0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
  1934. X    0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
  1935. X    0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
  1936. X    0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
  1937. X    0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
  1938. X    0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
  1939. X    0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
  1940. X    0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
  1941. X    0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
  1942. X    0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
  1943. X    0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
  1944. X    0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
  1945. X    0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
  1946. X    0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
  1947. X    0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
  1948. X    0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
  1949. X    0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
  1950. X    0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
  1951. X};
  1952. X
  1953. X#if defined(WANT_UPDCRC_HERE)    /* wht -- moved to zmodem.h */
  1954. X/*
  1955. X * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. 
  1956. X *  NOTE: First srgument must be in range 0 to 255.
  1957. X *        Second argument is referenced twice.
  1958. X * 
  1959. X * Programmers may incorporate any or all code into their programs,
  1960. X * giving proper credit within the source. Publication of the 
  1961. X * source routines is permitted so long as proper credit is given 
  1962. X * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
  1963. X * Omen Technology.
  1964. X */
  1965. X
  1966. X#define updcrc(cp,crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
  1967. X#endif
  1968. X
  1969. X/*
  1970. X  First,the polynomial itself and its table of feedback terms.  The
  1971. X  polynomial is:
  1972. X
  1973. X  X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
  1974. X
  1975. X  Note that we take it "backwards" and put the highest-order term in the
  1976. X  lowest-order bit.  The X^32 term is "implied"; the LSB is the X^31
  1977. X  term,etc.  The X^0 term (usually shown as "+1") results in the MSB being
  1978. X  1.  Note that the usual hardware shift register implementation,which is
  1979. X  what we're using (we're merely optimizing it by doing eight-bit chunks at
  1980. X  a time) shifts bits into the lowest-order term.  In our
  1981. X  implementation,that means shifting towards the right.  Why do we do it
  1982. X  this way?  Because the calculated CRC must be transmitted in order from
  1983. X  highest-order term to lowest-order term.  UARTs transmit characters in
  1984. X  order from LSB to MSB.  By storing the CRC this way, we hand it to the
  1985. X  UART in the order low-byte to high-byte; the UART sends each low-bit to
  1986. X  hight-bit; and the result is transmission bit by bit from highest- to
  1987. X  lowest-order term without requiring any bit shuffling on our part.
  1988. X  Reception works similarly.
  1989. X
  1990. X  The feedback terms table consists of 256 32-bit entries.  Notes:   
  1991. X
  1992. X     The macro for using the table is UPDC32 is located in zmodem.h
  1993. X                                                                     
  1994. X     It might not be obvious,but the feedback terms simply represent the
  1995. X     results of eight shift/xor opera- tions for all combinations of data
  1996. X     and CRC register values.
  1997. X                                                                     
  1998. X     The values must be right-shifted by eight bits by the "UPDC32" logic;
  1999. X     the shift must be unsigned (bring in zeroes).  On some hardware you
  2000. X     could probably optimize the shift in assembler by using byte-swap
  2001. X     instructions.
  2002. X*/
  2003. X
  2004. Xlong cr3tab[] =        /* CRC polynomial 0xedb88320 */
  2005. X{
  2006. X    0x00000000,0x77073096,0xee0e612c,0x990951ba,0x076dc419,0x706af48f,0xe963a535,0x9e6495a3,
  2007. X    0x0edb8832,0x79dcb8a4,0xe0d5e91e,0x97d2d988,0x09b64c2b,0x7eb17cbd,0xe7b82d07,0x90bf1d91,
  2008. X    0x1db71064,0x6ab020f2,0xf3b97148,0x84be41de,0x1adad47d,0x6ddde4eb,0xf4d4b551,0x83d385c7,
  2009. X    0x136c9856,0x646ba8c0,0xfd62f97a,0x8a65c9ec,0x14015c4f,0x63066cd9,0xfa0f3d63,0x8d080df5,
  2010. X    0x3b6e20c8,0x4c69105e,0xd56041e4,0xa2677172,0x3c03e4d1,0x4b04d447,0xd20d85fd,0xa50ab56b,
  2011. X    0x35b5a8fa,0x42b2986c,0xdbbbc9d6,0xacbcf940,0x32d86ce3,0x45df5c75,0xdcd60dcf,0xabd13d59,
  2012. X    0x26d930ac,0x51de003a,0xc8d75180,0xbfd06116,0x21b4f4b5,0x56b3c423,0xcfba9599,0xb8bda50f,
  2013. X    0x2802b89e,0x5f058808,0xc60cd9b2,0xb10be924,0x2f6f7c87,0x58684c11,0xc1611dab,0xb6662d3d,
  2014. X    0x76dc4190,0x01db7106,0x98d220bc,0xefd5102a,0x71b18589,0x06b6b51f,0x9fbfe4a5,0xe8b8d433,
  2015. X    0x7807c9a2,0x0f00f934,0x9609a88e,0xe10e9818,0x7f6a0dbb,0x086d3d2d,0x91646c97,0xe6635c01,
  2016. X    0x6b6b51f4,0x1c6c6162,0x856530d8,0xf262004e,0x6c0695ed,0x1b01a57b,0x8208f4c1,0xf50fc457,
  2017. X    0x65b0d9c6,0x12b7e950,0x8bbeb8ea,0xfcb9887c,0x62dd1ddf,0x15da2d49,0x8cd37cf3,0xfbd44c65,
  2018. X    0x4db26158,0x3ab551ce,0xa3bc0074,0xd4bb30e2,0x4adfa541,0x3dd895d7,0xa4d1c46d,0xd3d6f4fb,
  2019. X    0x4369e96a,0x346ed9fc,0xad678846,0xda60b8d0,0x44042d73,0x33031de5,0xaa0a4c5f,0xdd0d7cc9,
  2020. X    0x5005713c,0x270241aa,0xbe0b1010,0xc90c2086,0x5768b525,0x206f85b3,0xb966d409,0xce61e49f,
  2021. X    0x5edef90e,0x29d9c998,0xb0d09822,0xc7d7a8b4,0x59b33d17,0x2eb40d81,0xb7bd5c3b,0xc0ba6cad,
  2022. X    0xedb88320,0x9abfb3b6,0x03b6e20c,0x74b1d29a,0xead54739,0x9dd277af,0x04db2615,0x73dc1683,
  2023. X    0xe3630b12,0x94643b84,0x0d6d6a3e,0x7a6a5aa8,0xe40ecf0b,0x9309ff9d,0x0a00ae27,0x7d079eb1,
  2024. X    0xf00f9344,0x8708a3d2,0x1e01f268,0x6906c2fe,0xf762575d,0x806567cb,0x196c3671,0x6e6b06e7,
  2025. X    0xfed41b76,0x89d32be0,0x10da7a5a,0x67dd4acc,0xf9b9df6f,0x8ebeeff9,0x17b7be43,0x60b08ed5,
  2026. X    0xd6d6a3e8,0xa1d1937e,0x38d8c2c4,0x4fdff252,0xd1bb67f1,0xa6bc5767,0x3fb506dd,0x48b2364b,
  2027. X    0xd80d2bda,0xaf0a1b4c,0x36034af6,0x41047a60,0xdf60efc3,0xa867df55,0x316e8eef,0x4669be79,
  2028. X    0xcb61b38c,0xbc66831a,0x256fd2a0,0x5268e236,0xcc0c7795,0xbb0b4703,0x220216b9,0x5505262f,
  2029. X    0xc5ba3bbe,0xb2bd0b28,0x2bb45a92,0x5cb36a04,0xc2d7ffa7,0xb5d0cf31,0x2cd99e8b,0x5bdeae1d,
  2030. X    0x9b64c2b0,0xec63f226,0x756aa39c,0x026d930a,0x9c0906a9,0xeb0e363f,0x72076785,0x05005713,
  2031. X    0x95bf4a82,0xe2b87a14,0x7bb12bae,0x0cb61b38,0x92d28e9b,0xe5d5be0d,0x7cdcefb7,0x0bdbdf21,
  2032. X    0x86d3d2d4,0xf1d4e242,0x68ddb3f8,0x1fda836e,0x81be16cd,0xf6b9265b,0x6fb077e1,0x18b74777,
  2033. X    0x88085ae6,0xff0f6a70,0x66063bca,0x11010b5c,0x8f659eff,0xf862ae69,0x616bffd3,0x166ccf45,
  2034. X    0xa00ae278,0xd70dd2ee,0x4e048354,0x3903b3c2,0xa7672661,0xd06016f7,0x4969474d,0x3e6e77db,
  2035. X    0xaed16a4a,0xd9d65adc,0x40df0b66,0x37d83bf0,0xa9bcae53,0xdebb9ec5,0x47b2cf7f,0x30b5ffe9,
  2036. X    0xbdbdf21c,0xcabac28a,0x53b39330,0x24b4a3a6,0xbad03605,0xcdd70693,0x54de5729,0x23d967bf,
  2037. X    0xb3667a2e,0xc4614ab8,0x5d681b02,0x2a6f2b94,0xb40bbe37,0xc30c8ea1,0x5a05df1b,0x2d02ef8d
  2038. X};
  2039. X
  2040. X#if defined(FIONREAD)
  2041. X/*
  2042. X *  Return non 0 iff something to read from io descriptor f
  2043. X */
  2044. Xrdchk(f)
  2045. X{
  2046. X    static long lf;
  2047. X
  2048. X    ioctl(f,FIONREAD,&lf);
  2049. X    return((int) lf);
  2050. X}
  2051. X#endif
  2052. X
  2053. X#if defined(SV)
  2054. X#include <fcntl.h>
  2055. X
  2056. Xchar checked = '\0' ;
  2057. X/*
  2058. X * Nonblocking I/O is a bit different in System V,Release 2
  2059. X */
  2060. Xrdchk(f)
  2061. X{
  2062. X    int lf,savestat;
  2063. X
  2064. X    savestat = fcntl(f,F_GETFL) ;
  2065. X    fcntl(f,F_SETFL,savestat | O_NDELAY) ;
  2066. X    lf = read(f,&checked,1) ;
  2067. X    fcntl(f,F_SETFL,savestat) ;
  2068. X    return(lf) ;
  2069. X}
  2070. X#endif
  2071. X
  2072. X
  2073. Xstatic unsigned
  2074. Xgetspeed(code)
  2075. X{
  2076. X    register n;
  2077. X
  2078. X    for(n=0; speeds[n].baudr; ++n)
  2079. X        if(speeds[n].speedcode == code)
  2080. X            return(speeds[n].baudr);
  2081. X    return(38400);    /* Assume fifo if ioctl failed */
  2082. X}
  2083. X
  2084. X
  2085. X
  2086. X#if defined(ICANON)
  2087. Xstruct termio oldtty,tty;
  2088. X#else
  2089. Xstruct sgttyb oldtty,tty;
  2090. Xstruct tchars oldtch,tch;
  2091. X#endif
  2092. X
  2093. Xextern int iofd;        /* File descriptor for ioctls & reads */
  2094. X
  2095. X/*
  2096. X * mode(n)
  2097. X *  3: save old tty stat, set raw mode with flow control
  2098. X *  2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g
  2099. X *  1: save old tty stat, set raw mode 
  2100. X *  0: restore original tty mode
  2101. X */
  2102. Xmode(new_mode)
  2103. X{
  2104. X    static did0 = FALSE;
  2105. X    report_mode(new_mode);
  2106. X    switch(new_mode)
  2107. X    {
  2108. X#if defined(M_SYS5)
  2109. X    case 2:        /* Un-raw mode used by sz,sb when -g detected */
  2110. X        if(!did0)
  2111. X            (void) ioctl(iofd,TCGETA,&oldtty);
  2112. X        tty = oldtty;
  2113. X        tty.c_iflag &= ~(IXON | IXOFF | IXANY);
  2114. X
  2115. X#if defined(RTSFLOW)
  2116. X        if(tty.c_cflag & (RTSFLOW | CTSFLOW))
  2117. X            tty.c_iflag = BRKINT;
  2118. X        else
  2119. X            tty.c_iflag = BRKINT|IXON;
  2120. X#else
  2121. X        tty.c_iflag = BRKINT|IXON;
  2122. X#endif
  2123. X
  2124. X        tty.c_oflag = 0;    /* Transparent output */
  2125. X
  2126. X        tty.c_cflag &= ~PARENB;    /* Disable parity */
  2127. X        tty.c_cflag |= CS8;    /* Set character size = 8 */
  2128. X        if(Twostop)
  2129. X            tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  2130. X
  2131. X
  2132. X#if defined(READCHECK)
  2133. X        tty.c_lflag = Zmodem ? 0 : ISIG;
  2134. X        tty.c_cc[VINTR] = Zmodem ? -1:030;    /* Interrupt char */
  2135. X#else
  2136. X        tty.c_lflag = ISIG;
  2137. X        tty.c_cc[VINTR] = Zmodem ? 03:030;    /* Interrupt char */
  2138. X#endif
  2139. X        tty.c_cc[VQUIT] = -1;            /* Quit char */
  2140. X#if defined(NFGVMIN)
  2141. X        tty.c_cc[VMIN] = 1;
  2142. X#else
  2143. X        tty.c_cc[VMIN] = 3;     /* This many chars satisfies reads */
  2144. X#endif
  2145. X        tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
  2146. X
  2147. X        (void) ioctl(iofd,TCSETAW,&tty);
  2148. X        did0 = TRUE;
  2149. X        return(OK);
  2150. X    case 1:
  2151. X    case 3:
  2152. X        if(!did0)
  2153. X            (void) ioctl(iofd,TCGETA,&oldtty);
  2154. X        tty = oldtty;
  2155. X        tty.c_iflag &= ~(IXON | IXOFF | IXANY);
  2156. X
  2157. X#if defined(RTSFLOW)
  2158. X        tty.c_iflag = new_mode == 3 ? (IGNBRK | RTSFLOW) : IGNBRK;
  2159. X#else
  2160. X        tty.c_iflag = new_mode == 3 ? (IGNBRK | IXOFF) : IGNBRK;
  2161. X#endif
  2162. X
  2163. X        /* No echo,crlf mapping,INTR,QUIT,delays,no erase/kill */
  2164. X        tty.c_lflag &= ~(ECHO | ICANON | ISIG);
  2165. X
  2166. X        tty.c_oflag = 0;    /* Transparent output */
  2167. X
  2168. X        tty.c_cflag &= ~PARENB;    /* Same baud rate,disable parity */
  2169. X        tty.c_cflag |= CS8;    /* Set character size = 8 */
  2170. X        if(Twostop)
  2171. X            tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  2172. X#if defined(NFGVMIN)
  2173. X        tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
  2174. X#else
  2175. X        tty.c_cc[VMIN] = vmin_count; /* This many chars satisfies reads */
  2176. X#endif
  2177. X        tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
  2178. X        (void) ioctl(iofd,TCSETAW,&tty);
  2179. X        did0 = TRUE;
  2180. X        Baudrate = getspeed(tty.c_cflag & CBAUD);
  2181. X        report_comm_baud_rate(Baudrate);
  2182. X        return(OK);
  2183. X#endif
  2184. X#if defined(pyr)
  2185. X        /*
  2186. X     *  NOTE: this should transmit all 8 bits and at the same time
  2187. X     *   respond to XOFF/XON flow control.  If no FIONREAD or other
  2188. X     *   READCHECK alternative,also must respond to INTRRUPT char
  2189. X     *   This doesn't work with BSD4.  It should work with LLITOUT,
  2190. X     *   but LLITOUT was broken on the machine I tried it on.
  2191. X     */
  2192. X    case 2:        /* Un-raw mode used by sz,sb when -g detected */
  2193. X        if(!did0)
  2194. X        {
  2195. X            ioctl(iofd,TIOCEXCL,0);
  2196. X            ioctl(iofd,TIOCGETP,&oldtty);
  2197. X            ioctl(iofd,TIOCGETC,&oldtch);
  2198. X#if defined(LLITOUT)
  2199. X            ioctl(TIOCLGET,&Locmode);    /* Get "local mode" */
  2200. X#endif
  2201. X        }
  2202. X        tty = oldtty;
  2203. X        tch = oldtch;
  2204. X#if defined(READCHECK)
  2205. X        tch.t_intrc = Zmodem ? -1:030;    /* Interrupt char */
  2206. X#else
  2207. X        tch.t_intrc = Zmodem ? 03:030;    /* Interrupt char */
  2208. X#endif
  2209. X        tty.sg_flags |= (ODDP|EVENP|CBREAK);
  2210. X        tty.sg_flags &= ~(ALLDELAY|CRMOD|ECHO|LCASE);
  2211. X        ioctl(iofd,TIOCSETP,&tty);
  2212. X        ioctl(iofd,TIOCSETC,&tch);
  2213. X#if defined(LLITOUT)
  2214. X        ioctl(TIOCLBIS,&Locbit);
  2215. X#endif
  2216. X/* un-raw doesn't work w/o lit out *//*wht code was 99 */
  2217. X        cancel_transaction(0);
  2218. X        did0 = TRUE;
  2219. X        return(OK);
  2220. X    case 1:
  2221. X    case 3:
  2222. X        if(!did0)
  2223. X        {
  2224. X            ioctl(iofd,TIOCEXCL,0);
  2225. X            ioctl(iofd,TIOCGETP,&oldtty);
  2226. X            ioctl(iofd,TIOCGETC,&oldtch);
  2227. X#if defined(LLITOUT)
  2228. X            ioctl(TIOCLGET,&Locmode);    /* Get "local mode" */
  2229. X#endif
  2230. X        }
  2231. X        tty = oldtty;
  2232. X        tty.sg_flags |= RAW;
  2233. X        tty.sg_flags &= ~ECHO;
  2234. X        ioctl(iofd,TIOCSETP,&tty);
  2235. X        did0 = TRUE;
  2236. X        Baudrate = getspeed(tty.sg_ospeed);
  2237. X        report_comm_baud_rate(Baudrate);
  2238. X        return(OK);
  2239. X#endif
  2240. X    case 0:
  2241. X        if(!did0)
  2242. X            return(ERROR);
  2243. X#if defined(M_SYS5)
  2244. X        (void) ioctl(iofd,TCSBRK,1);    /* Wait for output to drain */
  2245. X        (void) ioctl(iofd,TCFLSH,1);    /* Flush input queue */
  2246. X        (void) ioctl(iofd,TCSETAW,&oldtty);    /* Restore modes */
  2247. X        (void) ioctl(iofd,TCXONC,1);    /* Restart output */
  2248. X#endif
  2249. X#if defined(pyr)
  2250. X        ioctl(iofd,TIOCSETP,&oldtty);
  2251. X        ioctl(iofd,TIOCSETC,&oldtch);
  2252. X        ioctl(iofd,TIOCNXCL,0);
  2253. X#if defined(LLITOUT)
  2254. X        ioctl(TIOCLSET,&Locmode);    /* Restore "local mode" */
  2255. X#endif
  2256. X#endif
  2257. X
  2258. X        return(OK);
  2259. X    default:
  2260. X        return(ERROR);
  2261. X    }
  2262. X}
  2263. X
  2264. X/*+-------------------------------------------------------------------------
  2265. X    sendbrk()
  2266. X--------------------------------------------------------------------------*/
  2267. Xsendbrk()
  2268. X{
  2269. X#if defined(pyr)
  2270. X    sleep(1);
  2271. X    ioctl(iofd,TIOCSBRK,0);
  2272. X    sleep(1);
  2273. X    ioctl(iofd,TIOCCBRK,0);
  2274. X#endif
  2275. X#if defined(M_SYS5)
  2276. X    ioctl(iofd,TCSBRK,0);
  2277. X#endif
  2278. X}    /* end of sendbrk */
  2279. X
  2280. X/*+-------------------------------------------------------------------------
  2281. X    get_curr_dir(currdir,currdir_max)
  2282. X--------------------------------------------------------------------------*/
  2283. Xvoid
  2284. Xget_curr_dir(currdir,currdir_max)
  2285. Xchar *currdir;
  2286. Xint currdir_max;
  2287. X{
  2288. X#if defined(pyr)
  2289. X    getwd(currdir);
  2290. X#endif
  2291. X
  2292. X#if defined(M_SYS5)
  2293. X    getcwd(currdir,currdir_max);
  2294. X#endif
  2295. X
  2296. X}    /* end of get_curr_dir */
  2297. X
  2298. X/*+-------------------------------------------------------------------------
  2299. X    zmputs(str) - send a string to the modem
  2300. X
  2301. Xprocessing for \336 (sleep 1 sec) and \335 (break signal)
  2302. X--------------------------------------------------------------------------*/
  2303. Xzmputs(str)
  2304. Xregister char *str;
  2305. X{
  2306. Xregister char strch;
  2307. X
  2308. X    while(strch = *str++)
  2309. X    {
  2310. X        switch(strch)
  2311. X        {
  2312. X        case '\336':
  2313. X            sleep(1);
  2314. X            continue;
  2315. X        case '\335':
  2316. X            sendbrk();
  2317. X            continue;
  2318. X        default:
  2319. X            sendline(strch);
  2320. X        }
  2321. X    }
  2322. X}    /* end of zmputs */
  2323. X
  2324. X/*+-----------------------------------------------------------------------
  2325. X    get_home_dir(home_dir):  leave plenty of room for result!
  2326. X------------------------------------------------------------------------*/
  2327. Xget_home_dir(home_dir)
  2328. Xchar *home_dir;
  2329. X{
  2330. Xstatic char home_directory[256] = "";
  2331. Xstruct passwd *pwent;
  2332. Xstruct passwd *getpwuid();
  2333. X
  2334. X    if(home_directory[0])
  2335. X    {
  2336. X        strcpy(home_dir,home_directory);
  2337. X        return(0);
  2338. X    }
  2339. X
  2340. X    if(!(pwent = getpwuid(getuid())))
  2341. X    {
  2342. X        perror("cannot get pwent for you!!");
  2343. X        exit(1);
  2344. X    }
  2345. X    strcpy(home_directory,pwent->pw_dir);
  2346. X    strcpy(home_dir,pwent->pw_dir);
  2347. X    endpwent();
  2348. X    return(0);
  2349. X
  2350. X}    /* end of get_home_dir */
  2351. X
  2352. X/* end of zcommon.c */
  2353. X/* vi: set tabstop=4 shiftwidth=4: */
  2354. SHAR_EOF
  2355. $TOUCH -am 0521180090 xfer/zcommon.c &&
  2356. chmod 0644 xfer/zcommon.c ||
  2357. echo "restore of xfer/zcommon.c failed"
  2358. set `wc -c xfer/zcommon.c`;Wc_c=$1
  2359. if test "$Wc_c" != "15622"; then
  2360.     echo original size 15622, current size $Wc_c
  2361. fi
  2362. echo "End of part 3, continue with part 4"
  2363. exit 0
  2364.  
  2365. ------------------------------------------------------------------
  2366. Warren Tucker, Tridom Corporation      ...!gatech!emory!tridom!wht
  2367. home address:                                 ...!gatech!n4hgf!wht
  2368.  
  2369.