home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / BEEHIVE / COMMS / YAM.ARC / YAM2.C < prev    next >
Text File  |  1990-09-20  |  8KB  |  453 lines

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