home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 110_01 / yam2.c < prev    next >
Text File  |  1984-03-03  |  7KB  |  347 lines

  1. /*
  2. >>:yam2.c 8-30-81
  3.  * Ward Christensen Protocol handler for sending and receiving
  4.  * ascii and binary files.
  5.  */
  6.  
  7. #include "yam.h"
  8. #define WCEOT (-2)
  9.  
  10.  
  11.  
  12. wcsend(argc, argp)
  13. char **argp;
  14. {
  15.     int wcs();
  16.  
  17.     if(Batch) {
  18. #ifdef XMODEM
  19.         printf("Sending in Batch Mode\n");
  20. #endif
  21.         if(expand(wcs, argc, argp)==ERROR)
  22.             goto fubar;
  23.         if(wctxpn("")==ERROR)
  24.             goto fubar;
  25.     }
  26.     else {
  27.         for(; --argc>=0;) {
  28. #ifdef XMODEM
  29.             printf("'%s' open for transmission\n", *argp);
  30. #endif
  31.             if(opentx(*argp++)==ERROR)
  32.                 goto fubar;
  33.             if(wctx()==ERROR)
  34.                 goto fubar;
  35.         }
  36.     }
  37.     return OK;
  38. fubar:
  39.     closetx();
  40.     sendline(CAN);sendline(CAN);sendline(CAN);
  41.     return ERROR;
  42. }
  43.  
  44. wcs(name)
  45. char *name;
  46. {
  47.     if(opentx(name)==ERROR)
  48.         return ERROR;
  49.     if(wctxpn(name)!= ERROR)
  50.         return wctx();
  51.     else {
  52.         return ERROR;
  53.     }
  54. }
  55.  
  56.  
  57. wcreceive(argc, argp)
  58. char **argp;
  59. {
  60.     char rpn[SECSIZ];        /* rx path name */
  61.     if(Batch || argc==0) {
  62.         printf("Receiving in Batch Mode\n");
  63.         for(;;) {
  64.             if(wcrxpn(rpn)== ERROR)
  65.                 goto fubar;
  66.             if(*rpn==0)
  67.                 return OK;
  68.             if(wcrx(rpn)==ERROR)
  69.                 goto fubar;
  70.         }
  71.     }
  72.     else
  73.         for(; --argc>=0;) {
  74. #ifdef XMODEM
  75.             printf("Receive:'%s'\n", *argp);
  76. #endif
  77.             if(wcrx(*argp++)==ERROR)
  78.                 goto fubar;
  79.         }
  80.     return OK;
  81. fubar:
  82.     sendline(CAN);sendline(CAN);sendline(CAN);
  83.     closerx(TRUE);
  84.     return ERROR;
  85. }
  86. /*
  87.  * Fetch a pathname from the other end as a C ctyle ASCIZ string.
  88.  * Length is indeterminate as long as less than SECSIZ
  89.  * a null string represents no more files
  90.  */
  91. wcrxpn(rpn)
  92. char *rpn;    /* receive a pathname */
  93. {
  94.     char rname[SECSIZ];
  95.  
  96.  
  97.     sendline(NAK);
  98.     if(wcgetsec(rname, 100)==ERROR) {
  99.         printf("Pathname fetch failed\n");
  100.         return ERROR;
  101.     }
  102.     strcpy(rpn, rname);
  103.     sendline(ACK);
  104.     return OK;
  105. }
  106.  
  107. wctxpn(name)
  108. char *name;
  109. {
  110.     char *p;
  111.  
  112.     lpstat("Awaiting initial pathname NAK");
  113.     if(readline(400)==ERROR)            /* wait for inital nak */
  114.         return ERROR;
  115.     /* don't send drive specification */
  116.     if(p=index(':', name))
  117.         name= ++p;
  118.     if(wcputsec(name, 0)==ERROR) {
  119.         printf("Can't send pathname %s\n", name);
  120.         return ERROR;
  121.     }
  122.     return OK;
  123. }
  124.  
  125. /*
  126.  * Adapted from CMODEM13.C, written by
  127.  * Jack M. Wierda and Roderick W. Hart
  128.  */
  129.  
  130. wcrx(name)
  131. char *name;
  132. {
  133.     int sectnum, sectcurr, sectcomp;
  134.     char rxbuf[128], sendchar;
  135.  
  136.     if(openrx(name)==ERROR)
  137.         return ERROR;
  138.     sectnum=0;
  139.     sendchar=NAK;
  140.  
  141.     for(;;) {
  142.         if(!Quiet
  143. #ifdef STATLINE
  144.         )
  145.             lpstat("Sector %3d", sectnum+1);
  146. #else
  147.         && !View)
  148.             lprintf("%s", (sectnum+1 &63)?"*":"*\n");
  149. #endif
  150.         sendline(sendchar);    /* send it now, we're ready! */
  151.         sectcurr=wcgetsec(rxbuf, (sectnum&0177)?50:130);
  152.         if(sectcurr==(sectnum+1 &0377)) {
  153.  
  154.             sectnum++;
  155.             for(cp=rxbuf,wcj=128; --wcj>=0; )
  156.                 if(putc(*cp++, fout)==ERROR) {
  157.                     printf("\nDisk Full\n");
  158.                     return ERROR;
  159.                 }
  160. #ifndef XMODEM
  161.             if(View)
  162.                 for(cp=rxbuf,wcj=128;--wcj>=0;)
  163.                     putchar(*cp++);
  164. #endif
  165.             sendchar=ACK;
  166.         }
  167.         else if(sectcurr==sectnum) {
  168.             pstat("Received dup Sector %d",sectcurr);
  169.             sendchar=ACK;
  170.         }
  171.         else if(sectcurr==WCEOT) {
  172.             sendline(ACK);
  173.             /* don't pad the file any more than it already is */
  174.             closerx(FALSE);
  175.             return OK;
  176.         }
  177.         else {
  178.             printf(" Sync Error\n");
  179.             return ERROR;
  180.         }
  181.     }
  182. }
  183.  
  184. /*
  185.  * wcgetsec fetches a Ward Christensen type sector.
  186.  * Returns sector number encountered or ERROR if valid sector not received,
  187.  * or CAN CAN received
  188.  * or WCEOT if eot sector
  189.  * time is timeout for first char, set to 4 seconds thereafter
  190.  ***************** NO ACK IS SENT IF SECTOR IS RECEIVED OK **************
  191.  *    (Caller must do that when he is good and ready to get next sector)
  192.  */
  193.  
  194. wcgetsec(rxbuf, time)
  195. char *rxbuf;
  196. int time;
  197. {
  198. /* BDSC
  199.     register checksum, wcj, firstch;
  200. */
  201.     int sectcurr,errors;
  202.  
  203.     for(Lastrx=errors=0; errors<RETRYMAX; errors++) {
  204.         do
  205.             firstch=readline(time);
  206.             while(firstch != SOH && firstch != TIMEOUT && firstch != EOT
  207.               && firstch != CAN);
  208.         if(firstch==SOH) {
  209.             sectcurr=readline(1);
  210.             if((sectcurr+readline(1))==255) {
  211.                 checksum=0;
  212.                 for(cp=rxbuf,wcj=128; --wcj>=0; ) {
  213.                     checksum += (*cp++ = readline(1));
  214.                 }
  215.                 if(((checksum-readline(1))&0377)==0)
  216.                     return sectcurr;
  217.                 else
  218.                     pstat("Checksum Error #%d", errors);
  219.             }
  220.             else
  221.                 pstat("Sector number garbled #%d", errors);
  222.         }
  223.         else if(firstch==EOT)
  224.             return WCEOT;
  225.         else if(firstch==CAN) {
  226.             if(Lastrx==CAN) {
  227.                 printf("Sender CANcelled\n");
  228.                 return ERROR;
  229.             } else {
  230.                 Lastrx=CAN;
  231.                 continue;
  232.             }
  233.         }
  234.         else if(firstch==TIMEOUT)
  235.             pstat("SOH Timeout #%d", errors);
  236.  
  237.         Lastrx=0;
  238.         while(readline(1)!=TIMEOUT)
  239.             ;
  240.         sendline(NAK);
  241.         time=40;
  242.     }
  243.     /* try to stop the bubble machine. */
  244.     sendline(CAN);sendline(CAN);sendline(CAN);
  245.     return ERROR;
  246. }
  247.  
  248. wctx()
  249. {
  250.     int sectnum, attempts;
  251.     char txbuf[SECSIZ];
  252.  
  253.     lpstat("Awaiting initial NAK");
  254.     while((firstch=readline(400))!=NAK && firstch!=TIMEOUT && firstch!=CAN)
  255.         lprintf("%c", firstch);    /* let user see it if strange char */
  256.     if(firstch==CAN)
  257.         return ERROR;
  258.  
  259.     sectnum=1;
  260.     while(filbuf(txbuf, SECSIZ)) {
  261.         if(!Quiet
  262. #ifdef STATLINE
  263.         )
  264.             lpstat("Sector %3d", sectnum);
  265. #else
  266.         && !View)
  267.             lprintf("%s", (sectnum&63)?"*":"*\n");
  268. #endif
  269.         if(wcputsec(txbuf, sectnum)==ERROR) {
  270.             return ERROR;
  271.         } else {
  272.             if(View)    /* View can't be set in xyam */
  273.                 for(cp=txbuf,wcj=128;--wcj>=0;)
  274.                     putchar(*cp++);
  275.             sectnum++;
  276.         }
  277.     }
  278.     closetx();
  279.     attempts=0;
  280.     do {
  281.         sendline(EOT);
  282.         purgeline();
  283.         attempts++;
  284.     }
  285.         while((firstch=(readline(100)) != ACK) && attempts < RETRYMAX);
  286.     if(attempts == RETRYMAX) {
  287.         printf("\nNo ACK on EOT; Aborting... ");
  288.         return ERROR;
  289.     }
  290.     else
  291.         return OK;
  292. }
  293.  
  294. wcputsec(txbuf, sectnum)
  295. char *txbuf;
  296. {
  297. /* BDSC
  298.     register checksum, wcj, firstch;
  299. */
  300.     int attempts;
  301.  
  302.     firstch=0;    /* part of logic to detect CAN CAN */
  303.  
  304.     for(attempts=0; attempts <= RETRYMAX; attempts++) {
  305.         Lastrx= firstch;
  306.         sendline(SOH);
  307.         sendline(sectnum);
  308.         sendline(-sectnum-1);
  309.         checksum=0;
  310.         for(wcj=SECSIZ,cp=txbuf; --wcj>=0; ) {
  311.             sendline(*cp);
  312.             checksum += *cp++;
  313.         }
  314.         sendline(checksum);
  315.         purgeline();
  316.  
  317.         firstch=readline(100);
  318.         if(firstch==CAN && Lastrx==CAN) {
  319. cancan:
  320.             printf("\nReceiver CANcelled transmission ");
  321.             return ERROR;
  322.         }
  323.         else if(firstch==ACK)
  324.             return OK;
  325.         else if(firstch==TIMEOUT)
  326.             pstat("Timeout on sector ack attempt %d", attempts);
  327.         else {
  328.             pstat("Got 0%o for sector ACK attempt %d", firstch, attempts);
  329.             for(;;) {
  330.                 Lastrx=firstch;
  331.                 lprintf("%c", firstch);    /* let user see it if strange char */
  332.                 if((firstch=readline(1))==TIMEOUT)
  333.                     break;
  334.                 if(firstch==CAN && Lastrx==CAN)
  335.                     goto cancan;
  336.             }
  337.         }
  338.     }
  339.     printf("No ACK on sector; Abort ");
  340.     return ERROR;
  341.  
  342. }
  343. ister checksum, wcj, firstch;
  344. */
  345.     int attempts;
  346.  
  347.     fir