home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / pub / researchmachines / rmlrec.c < prev    next >
Text File  |  2020-01-01  |  10KB  |  421 lines

  1.  
  2. /***********************************************************************/
  3.  
  4. /*  File KREC.C  -  Receive-procedures for RML Kermit;
  5.         Chris Kennington,    RML.    9th July 1985.    */
  6.  
  7. #define     DEFS1    1
  8. #define     DEFS2    1
  9. #define     DEFS4    1
  10.  
  11. #include  "stdio.h"
  12. #include  "b:kext.h"
  13.  
  14. static char *ptr2;    /* Pointer to converted file name    */
  15. static int  len;
  16.  
  17.  
  18.  
  19. char cpmunge(len,new,old)
  20. /*  Convert supplied name to a (similar) one which is legal
  21.  *    for CP/M; all alphabetics to upper case, all punctuation
  22.  *    deleted except for a single dot (the first if more than
  23.  *    one in input), colon taken as restarting the munge, all
  24.  *    controls deleted, length limited to 8.3, if input is
  25.  *    > 8 without a dot, dot inserted and next 3 chars used
  26.  *    as suffix.  Munge terminated by 0 as a C-string. 
  27.  *  Returns length of munged name (not including terminating 0). */
  28. char  *old, *new;
  29. int   len;
  30. {
  31.     char  c, i, j, p2, dotty;
  32.  
  33.     j = p2 = dotty = 0;
  34.     for (i=0; i<len; ++i) {        /* step thro' old    */
  35.   /* unwanted chars, continue the loop; wanted chars, store at end. */    
  36.     if (p2 > 3)
  37.         goto Exit;            /* suffix full        */
  38.     c = old[i] & 0x7f;
  39.     if (c > '@') {            /* ordinaries        */
  40.         c &= 0x5f;            /* upper case        */
  41.         if (c > 0x5a)
  42.         continue;        /* illegal chars    */
  43.     }
  44.     else if (c > SP) switch(c) { /* punctuation & numerals    */
  45.           case'0':        /* accept all numerals        */
  46.           case'1':
  47.           case'2':
  48.           case'3':
  49.           case'4':
  50.           case'5':
  51.           case'6':
  52.           case'7':
  53.           case'8':
  54.           case'9':
  55.           case'$':
  56.         break;
  57.  
  58.           case ':':            /* previous was disk-letter    */
  59.         j = 0;            /* start afresh        */
  60.         dotty = 0;
  61.         continue;
  62.           case '.':            /* CP/M divider        */
  63.         if (dotty != 0)
  64.             continue;        /* two dots illegal    */
  65.         if (j == 0)
  66.             continue;        /* leading dot illegal    */
  67.         ++dotty;
  68.         break;
  69.           default:            /* all others ignored    */
  70.         continue;
  71.     }            /* end else-if-switch        */
  72.     else            /* controls etc.        */
  73.         continue;
  74.   /* anything that reaches here must be stored            */
  75.     if (dotty == 0) {    /* in main name            */
  76.         if (j > 7) {    /*  but it's full        */
  77.         ++dotty;
  78.         new[j++] = '.'; /* rest as suffix        */
  79.         ++p2;
  80.     }   }
  81.     else            /* in suffix            */
  82.         ++p2;
  83.     new[j++] = c;
  84.     }                /* end for            */
  85.     if (j == 0) {        /* no valid chars in "old"    */
  86.     strcpy(new,DEFNAM);    /*  so replace with default    */
  87.     j = DEFLEN;        /*   length of default        */
  88.     }
  89. Exit:
  90.     new[j] = 0;            /* close as string        */
  91.     return(j);
  92. }            /* end of cpmunge()            */        
  93.  
  94.  
  95.  
  96. char rdata()        /*  Receive Data        */
  97. {
  98.     int        fail, num;
  99.     char    typ;
  100.  
  101.     if (numtry++ > MAXTRY)
  102.     return('A');        /* abort if too many tries */
  103.  
  104.     typ = rpack(&len,&num,recpkt);
  105.     switch(typ) {
  106.  
  107.     case 'D':            /* Data            */
  108.         if (num != n) {        /* not right packet    */
  109.         if (oldtry++ > MAXTRY)
  110.             return('A');
  111.         if (num == ((n==0) ? 63:n-1)) {
  112.             spack('Y',num,0,0);    /* re-ACK previous    */
  113.             numtry = 0;
  114.             if (list == 1)
  115.             outc('D');
  116.             if (list > 2)
  117.             printf("\rDbg: Duplicate (%c).",tochar(num));
  118.             return(state);      /* Don't write out data! */
  119.         }
  120.         else return('A');    /* sorry, wrong number */
  121.         }
  122.         if ( (fail = bufemp(recpkt,len)) != 0 ) {
  123.         error(diskfail,fail);
  124.         return('A');
  125.         }
  126.         spack('Y',n,0,0);
  127.         inctry();            /* ++n%64 & mod tries    */
  128.         return('D');        /* Remain in data state */
  129.  
  130.     case 'F':            /* Got a File Header    */
  131.     case 'X':            /*  or a text header    */
  132.         if (oldtry++ > MAXTRY)
  133.         return('A');        /* If too many tries, "abort" */
  134.         if (num == ((n==0) ? 63:n-1)) {
  135.         spack('Y',num,0,0);     /* ACK previous again    */
  136.         numtry = 0;
  137.         return(state);        /* Stay in Data state */
  138.         }
  139.         else return('A');        /* Not previous packet, "abort" */
  140.  
  141.     case 'Z':            /* End-Of-File */
  142.         if (num != n)
  143.         return('A');
  144.         if (fp != 0)
  145.         printmsg("** File <%s> received. ",ptr2);
  146.         kclose(fp);            /* Close the file */
  147.         spack('Y',n,0,0);
  148.         fp = 0;
  149.         n = (n+1)%64;
  150.         return('F');        /* Go back to Receive File state */
  151.  
  152.     case 'E':            /* Error packet received */
  153.         prerrpkt(recpkt);
  154.         reclose();
  155.         return('A');        /* abort */
  156.  
  157.     case 'A':            /* user aborted transfer    */
  158.         recfail();
  159.         reclose();
  160.         return('A');
  161.  
  162.     case FALSE:            /* Didn't get packet */
  163.         spack('N',n,0,0);
  164.         return(state);        /* Keep trying */
  165.  
  166.     default:            /* Some other; abort    */
  167.         error(badmsg,'D',typ);
  168.         return('A');
  169.     }
  170. }            /* end of rdata()        */
  171.  
  172.  
  173.  
  174. static recfail()    /* process user abort        */
  175. {
  176.     char  num;
  177.  
  178.     abtflag = 0;
  179.     rpack(&len,&num,recpkt);    /* wait for next packet    */
  180.     error(errmsg);        /*  then abort        */
  181.     return;
  182. }            /* end of recfail()        */
  183.  
  184.  
  185.  
  186. static reclose()    /* close file if open        */
  187. {
  188.     if (fp != 0) {
  189.     kclose(fp);
  190.     fp = 0;
  191.     printmsg("File <%s> partially received; last data was:",ptr2);
  192.     oldpkt[len] = 0;
  193.     printf("\r  \"%s\". ",oldpkt);
  194.     }
  195.     return;
  196. }            /* end of reclose()        */
  197.  
  198.  
  199.  
  200. recsw(ist,ipkt)            /* Receive files.        */
  201. int    ist;                /* initial state    */
  202. char    ipkt;                /* initial packet-type    */
  203. {
  204.     fp = 0;
  205.     numtry = 0;
  206.     state = ist;    
  207.  
  208.     forever {
  209.     if (list > 2) {
  210.         outc(CR);
  211.         printf("Dbg: recsw() state: %c",state);
  212.     }
  213.     errdisp();
  214.     if (abtflag != 0) {
  215.         recfail();
  216.         reclose();
  217.         return(FALSE);
  218.     }        /* catch user aborts during spack()    */
  219.     switch(state) {
  220.  
  221.   /* special initial states (message already in packet[]):-    */
  222.         case RMH:        /* send command and display    */
  223.         case RMSV:        /*  anything sent back        */
  224.         case GET:        /* get files            */
  225.         spack(ipkt,n,strlen(packet),packet);
  226.         state = rinit();
  227.         break;        
  228.  
  229.   /* normal staes during reception:-                */
  230.         case 'R':
  231.         state = rinit();
  232.         break;                /* Receive-Init */
  233.         case 'F':
  234.         state = rfile();
  235.         break;                /* Receive-File */
  236.         case 'D':
  237.         state = rdata();
  238.         break;                /* Receive-Data */
  239.         case 'C':
  240.         reclose();
  241.         return(TRUE);            /* Complete state */
  242.         case 'A':
  243.         reclose();
  244.         return(FALSE);            /* "Abort" state */
  245.     }    }
  246. }            /* end of recsw()            */
  247.  
  248.  
  249.  
  250. char rfile()        /*  Receive File Header            */
  251. {
  252.     char disk, *ptr1;
  253.     int  num;
  254.  
  255.     if (numtry++ > MAXTRY)
  256.     return('A');
  257.  
  258.     switch(rpack(&len,&num,recpkt)) {
  259.  
  260.     case 'S':            /* Send-Init, maybe our ACK lost */
  261.         if (oldtry++ > MAXTRY)
  262.         return('A');
  263.         if (num == ((n==0) ? 63:n-1)) {    /* Previous packet?    */
  264.         len = spar(packet);
  265.         spack('Y',num,len,packet);
  266.         numtry = 0;
  267.         return(state);
  268.         }
  269.         else return('A');        /* Not previous packet, "abort" */
  270.  
  271.     case 'Z':            /* End-Of-File            */
  272.         if (oldtry++ > MAXTRY) return('A');
  273.         if (num == ((n==0) ? 63:n-1)) {     /* Previous packet?    */
  274.         spack('Y',num,0,0);
  275.         numtry = 0;
  276.         return(state);
  277.         }
  278.         else return('A');        /* Not previous packet, "abort" */
  279.  
  280.     case 'F':            /* File Header        */
  281.         if (num != n)
  282.          return('A');
  283.         vtline(LOCFILE,filblank);
  284.         ptr2 = fname + 2;        /* leave room for disk-letter    */
  285.         cpmunge(len,ptr2,recpkt);    /* validate file name received    */
  286.         if (filecount) {        /* if override name or disk    */
  287.         disk = 0;
  288.         ptr1 = *filelist;
  289.         if (*(ptr1+1) == ':') {    /* if disk-letter present    */
  290.             disk = *ptr1;
  291.             ptr1 += 2;        /* up to start of filename    */
  292.         }
  293.         if (*ptr1 != 0) {    /* if filename present        */
  294.             cpmunge(strlen(ptr1),ptr2,ptr1);
  295.             --filecount;    /* substitute for name received    */
  296.             ++filelist;        /*  & advance parm-counters    */
  297.         }
  298.         if (disk != 0) {    /* if disk-letter specified    */
  299.             *(--ptr2) = ':';    /*  put it into fname        */
  300.             *(--ptr2) = disk;    /*   in front of filename    */
  301.         }    }        /* end if, if                */            
  302.   /* fname[] now contains correct validated name, including any disk-letter,
  303.     and ptr2 => either its beginning or third char.            */
  304.         vtline(LOCFILE,ptr2);
  305.         s4sleep();
  306.         if ( (ptr1 = avoid(ptr2)) != 0 ) {
  307.         error(ptr1,ptr2);
  308.         return('A');
  309.         }
  310.         if ((fp=kwopen(ptr2))==NULL) {
  311.         error("Cant create <%s> - cancelled",ptr2);
  312.         return('A');
  313.         }
  314.         else
  315.         printmsg("Receiving <%s> as <%s>\r",recpkt,ptr2);
  316.         spack('Y',n,0,0);
  317.         inctry();            /* ++n%64 & mod tries        */
  318.         return('D');        /* Switch to Data state     */
  319.  
  320.     case 'Y':            /* short reply            */
  321.         recpkt[*len] = 0;
  322.         printmsg("%s\r%s", mainsays,recpkt);
  323.         return('C');
  324.  
  325.     case 'X':            /* long reply            */
  326.         vtline(LOCFILE,mainsays);
  327.         printmsg("%s\r",mainsays);
  328.         spack('Y',n,0,0);
  329.         inctry();
  330.         return('D');
  331.  
  332.     case 'B':            /* Break transmission (EOT)     */
  333.         if (num != n)
  334.         return ('A');
  335.         spack('Y',n,0,0);
  336.         return('C');        /* Go to complete state     */
  337.  
  338.     case 'E':            /* Error packet received     */
  339.         prerrpkt(recpkt);
  340.         return('A');
  341.  
  342.     case 'A':            /* user aborted transfer    */
  343.         return('A');
  344.  
  345.     case FALSE:            /* Didn't get packet        */
  346.         if (list != 1)
  347.         txtout(trying);
  348.         spack('N',n,0,0);
  349.         return(state);
  350.  
  351.     default:            /* Some other type, abort    */
  352.         error(badmsg,'F',type);
  353.         return('A');
  354.     }
  355. }            /* end of rfile()                */
  356.  
  357.  
  358.  
  359.  
  360. char rinit()        /*  Receive Initialization    */
  361. {
  362.     int num;
  363.  
  364.   /* unlimited retries in this state            */
  365.     switch(rpack(&len,&num,recpkt))
  366.     {
  367.     case 'S':            /* Send-Init         */
  368.         n = num;            /* accept their number    */
  369.         rpar(recpkt,len);
  370.         len = spar(packet);
  371.         spack('Y',n,len,packet);
  372.         compmode();
  373.         inctry();            /* ++n%64 & mod tries    */
  374.         return('F');
  375.  
  376.     case 'I':            /* Info-exchange    */
  377.         rpar(recpkt,len);
  378.         len = spar(packet);
  379.         spack('Y',n,len,packet);
  380.         compmode();
  381.         return('R');
  382.  
  383.     case 'Y':            /* short reply        */
  384.         recpkt[*len] = 0;
  385.         printmsg("%s\r%s", mainsays,recpkt);
  386.         return('C');
  387.  
  388.     case 'X':            /* long reply        */
  389.         vtline(LOCFILE,mainsays);
  390.         printmsg("%s\r",mainsays);
  391.         n = num;
  392.         spack('Y',n,0,0);
  393.         inctry();
  394.         return('D');
  395.  
  396.     case 'E':            /* Error packet received */
  397.         prerrpkt(recpkt);
  398.     case 'N':            /* NAK            */
  399.         return('A');
  400.  
  401.     case 'A':            /* User abort        */
  402.         return('A');
  403.  
  404.     case FALSE:            /* Didn't get packet */
  405.         if (list != 1)
  406.         txtout(trying);
  407.         if (state == 'R')        /* normal receive    */
  408.         spack('N',n,0,0);
  409.         return(state);
  410.  
  411.     default:            /* Some other type, abort */
  412.         error(badmsg,'S',type);
  413.         return('A');
  414.     }
  415. }            /* end of rinit()        */
  416.  
  417.  
  418.  
  419. /************  END of file KREC.C  ***************************/
  420.  
  421.