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

  1.  
  2. /***********************************************************************/
  3.  
  4. /*  File KSEND.C  -  Send procedures for RML Kermit;
  5.         Chris Kennington,    RML.    1st July 1985    */
  6.  
  7. #define  DEFS2    1
  8. #define     DEFS4    1
  9.  
  10. #include  "stdio.h"
  11. #include  "b:kext.h"
  12.  
  13.  
  14. /* static externals for this file only            */
  15. static char  cannot[]  = "Cannot open <%s>; ";
  16. static char  mainhas[] = "Mainframe has ";
  17. static char  unable[]  = "Nothing from mainframe. ";
  18. static int   num, len;        /* Packet number & length    */
  19.  
  20.  
  21.  
  22.  
  23. gnxtfl()
  24. /*  Get next file in a file group; if wildcard, expand it into
  25.       cmdline.  Return TRUE or FALSE.                */
  26. {
  27.     char    ret;
  28.  
  29.     if (filecount-- == 0) {
  30.     filnam = 0;
  31.     return(FALSE);            /* If no more, fail    */
  32.     }
  33.     else {
  34.     vtline(LOCFILE,filblank);
  35.     vtline(LOCFILE,(filnam = *(filelist++)));
  36.     printmsg(null);
  37.     if ( ( (ret = fileok(filnam))&(char)0x07 ) != 0 ) {
  38.         txtout("not sent.");    /* no file    */
  39.         return(gnxtfl());        /* recursive call    */
  40.     }
  41.     else if ( (ret&(char)0x40) != 0 ) {    /* wildcards    */
  42.         printf("Expanding wildcards ...");
  43.         ret = wildex(filnam,cmdline);
  44.         printmsg("Will send: %s",cmdline);
  45.         if (ret > (char)8)
  46.         txtout(" (more on disk)");
  47.         filecount = decol8(cmdline,cmdparm,8);
  48.         filelist = cmdparm;
  49.         return(gnxtfl());        /* recursive call    */
  50.     }
  51.     else {
  52.         return(TRUE);
  53. }   }    }        /* end of gnxtfl()        */
  54.  
  55.  
  56.  
  57.  
  58. char sbreak()        /*  Send Break (EOT)        */
  59. {
  60.     if (numtry++ > MAXTRY) return('A');    /* If too many tries "abort"    */
  61.  
  62.     spack('B',n,0,0);        /* Send a B packet    */
  63.     switch (rpack(&len,&num,recpkt))    /* What was the reply?    */
  64.     {
  65.     case 'N':            /* NAK, just stay in this state,    */
  66.         num = (--num<0 ? 63:num);    /* unless NAK for previous packet,    */
  67.  
  68.     case 'Y':            /* ACK    */
  69.         if (n != num) return(state); /* If wrong ACK, fail    */
  70.         inctry();            /* ++n%64 & ++tries    */
  71.         printmsg("** All files sent OK. ");
  72.         return('C');        /* Switch state to Complete    */
  73.  
  74.     case 'E':            /* Error packet received    */
  75.         prerrpkt(recpkt);        /* Print it out and    */
  76.         return('A');        /* abort    */
  77.  
  78.     case FALSE: return(state);    /* Receive failure, stay in B    */
  79.  
  80.     default:            /* Other, "abort"    */
  81.         printmsg(badmsg,'Y',type);
  82.         return('A');
  83.    }
  84. }            /* end of sbreak()            */
  85.  
  86.  
  87.  
  88.  
  89. char sdata()        /*  Send File Data    */
  90. {
  91.     if (numtry++ > MAXTRY) return('A');    /* If too many tries, give up    */
  92.  
  93.     spack('D',n,size,packet);        /* Send a D packet    */
  94.     if (abtflag != 0) {
  95.     sendfail();
  96.     return('A');
  97.     }
  98.     switch(rpack(&len,&num,recpkt))    /* What was the reply?    */
  99.     {        
  100.     case 'N':            /* NAK, just stay in this state,    */
  101.         if (list > 2)
  102.         printf("\rDbg: NAK for packet %c.", tochar(num));
  103.         num = (--num<0 ? 63:num);    /* unless it's NAK for next packet, */
  104.   /* which is just like an ACK for this packet so fall thru to...    */
  105.  
  106.     case 'Y':            /* ACK                */
  107.         if (n != num)
  108.         return(state);        /* If wrong ACK, repeat    */
  109.         inctry();            /* ++n%64 & ++tries        */
  110.         if (len != 0) switch (*recpkt) {    /* truncation        */
  111.           case 'X':                /*  single file        */
  112.         printmsg("%struncated file",mainhas);
  113.         return('Z');
  114.           case 'Z':                /*  file group        */
  115.         printmsg("%scancelled transfer",mainhas);
  116.         seclose();
  117.         return('B');
  118.           default:
  119.         if (list > 2)
  120.             printf("\rDbg: Bad ACK <%s>",recpkt);
  121.         break;
  122.         }
  123.         if ((size = bufill(packet)) == EOF)    /* Get data from file    */
  124.         if (errno == 0)
  125.             return('Z');    /* If EOF set state to that    */
  126.         else {            /* error            */
  127.             error(diskfail,errno);
  128.             return('A');
  129.         }
  130.         else
  131.         return('D');        /* Got data, stay in state D    */
  132.  
  133.     case 'E':            /* Error packet received    */
  134.         prerrpkt(recpkt);        /* Print it out and    */
  135.         seclose();
  136.         return('A');        /* abort    */
  137.  
  138.     case FALSE:
  139.         return(state);        /* Receive failure, stay in D    */
  140.  
  141.     case 'A':            /* User abort        */
  142.         sendfail();
  143.         return('A');
  144.  
  145.     default:            /* Anything else, just "abort"    */
  146.         printmsg(badmsg,'Y',type);
  147.         return('A');
  148.     }
  149. }            /* end of sdata()            */
  150.  
  151.  
  152.  
  153. seclose()        /* close send-file            */
  154. {
  155.     if (fp != 0) {
  156.     kclose(fp);
  157.     fp = 0;
  158.     filnam = 0;
  159.     }
  160.     return;
  161. }            /* end of seclose()            */
  162.  
  163.  
  164.  
  165. sendfail()        /* process user abort            */
  166. {
  167.     abtflag = 0;
  168.     rpack(&len,&num,recpkt);    /* ignore next packet        */
  169.     error(errmsg);        /*  then abort            */
  170.     seclose();
  171.     return;
  172. }                /* end of sendfail()        */
  173.  
  174.  
  175.  
  176.  
  177. sendsw(ist)        /* Send files            */
  178. int    ist;            /* initial state    */
  179. {
  180.     state = ist;
  181.     n = 0;
  182.     numtry = 0;
  183.     while(TRUE) {
  184.     if (list > 2) {
  185.         outc(CR);
  186.         printf("Dbg: sendsw() state: %c, ",state);
  187.     }
  188.     errdisp();            /* update error display    */
  189.     switch(state) {
  190.         case 'S':
  191.             txtout(dots);
  192.             state = sinit();  
  193.             break;        /* Send-Init        */
  194.         case 'F':   state = sfile();  
  195.             break;        /* Send file-init    */
  196.         case 'D':   state = sdata();  
  197.             break;        /* Send-Data        */
  198.         case 'Z':   state = seof();   
  199.             break;        /* Send-End-of-File    */
  200.         case 'B':   state = sbreak();
  201.             break;        /* Send-Break        */
  202.         case 'C':
  203.         seclose();
  204.         return (TRUE);                /* Complete    */
  205.         case 'A':                    /* "Abort"    */
  206.         default:                    /* Unknown, fail */
  207.         seclose();
  208.         return (FALSE);
  209.     }    }
  210. }            /* end sendsw()                */
  211.  
  212.  
  213.  
  214.  
  215. char seof()        /*  Send End-Of-File.        */
  216. {
  217.     if (numtry++ > MAXTRY) return('A');    /* If too many tries, "abort"    */
  218.  
  219.     spack('Z',n,0,0);            /* Send a 'Z' packet    */
  220.     if (fp != 0)
  221.     printmsg("** File %s sent OK. ",filnam);
  222.     seclose();                /* close file        */
  223.     switch(rpack(&len,&num,recpkt)) {
  224.  
  225.     case 'N':            /* NAK, just stay in this state,    */
  226.         num = (--num<0 ? 63:num);    /* unless it's NAK for next packet,    */
  227.  
  228.     case 'Y':            /* ACK    */
  229.         if (n != num) return(state); /* If wrong ACK, hold out    */
  230.         inctry();            /* ++n%64 & ++tries    */
  231.         fp = NULL;            /* Set flag indicating no file open    */ 
  232.         if (gnxtfl() == FALSE)    /* No more files go?    */
  233.         return('B');        /* if not, break, EOT, all done    */
  234.         return('F');        /* More files, switch state to F    */
  235.  
  236.     case 'E':            /* Error packet received    */
  237.         prerrpkt(recpkt);        /* Print it out and    */
  238.         return('A');        /* abort    */
  239.  
  240.     case FALSE:
  241.         return(state);        /* Receive failure, stay in Z    */
  242.  
  243.     case 'A':            /* User abort        */
  244.         sendfail();
  245.         return('A');
  246.  
  247.     default:            /* Anything else, just "abort"    */
  248.         printmsg(badmsg,'Y',type);
  249.         return('A');
  250.     }
  251. }        /* End of seof()                */
  252.  
  253.  
  254.  
  255.  
  256. char sfile()            /*  Send File Header.        */
  257. {
  258.     char   wk[14], *newfilnam,    /* Pointer to file name to send    */
  259.        c, *cp;            /* char, pointer    */
  260.  
  261.     if (numtry++ > MAXTRY) {
  262.     txtout(unable);
  263.     return('A');
  264.     }
  265.     if ( (fp == NULL) && ( (fp = kropen(filnam)) == NULL) ) {
  266.   /* trouble opening file                    */
  267.     if (filecount != 0) {        /* if more to go    */
  268.         printf(cannot,filnam);
  269.         gnxtfl();
  270.         numtry = 0;            /* permit name message    */
  271.         return('F');        /*  send next one    */
  272.     }
  273.     else {
  274.         error(cannot,filnam);
  275.         return('A');
  276.     }    }
  277.  
  278.     strcpy(wk, filnam);            /* Copy file name    */
  279.     newfilnam = &wk;
  280.     if (newfilnam[1] == ':')
  281.     newfilnam += 2;            /* strip CP/M disk-letter    */
  282.  
  283.   /* Filenames are always u.c. under CP/M             */
  284.     len = strlen(newfilnam);
  285.     if (numtry == 1)            /* once per file only    */
  286.     printf("Sending <%s> as <%s>\r",filnam,newfilnam);
  287.     if (abtflag != 0) {
  288.     sendfail();
  289.     return('A');
  290.     }
  291.     spack('F',n,len,newfilnam);        /* Send an F packet    */
  292.  
  293.     switch(rpack(&len,&num,recpkt)) {           
  294.  
  295.     case 'N':            /* NAK, just stay in this state,    */
  296.         num = (--num<0 ? 63:num);
  297.         printmsg("Trouble exchanging params");
  298. /* unless it's NAK for next packet which is just like an ACK for this packet so fall thru to...    */
  299.  
  300.     case 'Y':            /* ACK    */
  301.         if (n != num) return(state); /* If wrong ACK, stay in F state    */
  302.         inctry();            /* ++n%64 & ++tries    */
  303.         softeof = FALSE;
  304.         if ( (size = bufill(packet)) == EOF ) { /* null file */
  305.         if (errno == 0) {
  306.             printmsg("File empty.");
  307.             return('Z');    /* on to next        */
  308.         }
  309.         else {            /* error            */
  310.             error(diskfail,errno);
  311.             return('A');
  312.         }    }
  313.         else
  314.         return('D');        /* Switch state to D    */
  315.  
  316.     case 'E':            /* Error packet received    */
  317.         prerrpkt(recpkt);        /* Print it out and    */
  318.         seclose();
  319.         return('A');        /* abort    */
  320.  
  321.     case FALSE:
  322.         if (list != 1)
  323.         txtout(trying);
  324.         return(state);        /* Receive failure, stay in F state */
  325.  
  326.     case 'A':            /* User abort            */
  327.         sendfail();
  328.         return('A');
  329.  
  330.     default:            /* Anything else, just "abort"    */
  331.         printmsg(badmsg,'Y',type);
  332.         return('A');
  333.     }
  334. }            /* end of sfile()            */
  335.  
  336.  
  337.  
  338.  
  339. char sinit()        /*  Send Initiate        */
  340. /* send this host's parameters and get other side's back.*/
  341. {
  342.     if (numtry++ > MAXTRY) {        /* If too many tries, give up    */
  343.     txtout(unable);
  344.     return('A');
  345.     }
  346.     len = spar(packet);            /* Fill up init info packet    */
  347.     flushinput();            /* Flush pending input    */
  348.     spack('S',n,len,packet);        /* Send an S packet    */
  349.     if (abtflag != 0) {
  350.     sendfail();
  351.     return('A');
  352.     }
  353.     switch(rpack(&len,&num,recpkt))    /* What was the reply?    */
  354.     {
  355.  
  356.     case 'Y':            /* ACK    */
  357.         if (n != num)        /* If wrong ACK, stay in S state    */
  358.         return(state);        /* and try again    */
  359.         rpar(recpkt,len);        /* Get other side's init info    */
  360.         compmode();            /* tell user        */
  361.         if (eol == 0) eol = '\n';    /* Check and set defaults    */
  362.         if (quote == 0) quote = '#';
  363.         inctry();            /* ++n%64 & ++tries    */
  364.         return('F');        /* OK, switch state to F    */
  365.  
  366.     case 'I':            /* Info-exchange        */
  367.         rpar(recpkt,len);
  368.         len = spar(packet);
  369.         compmode();
  370.         spack('Y',n,len,packet);
  371.         rpack(&len,&num,recpkt);    /* ignore response    */
  372.         return('S');
  373.  
  374.     case 'R':            /* Get-packet        */
  375.         txtout("R-packet from remote Kermit ");
  376.         rpar(recpkt,len);
  377.         return(state);        /* causes retransmission of 'S' */
  378.  
  379.     case 'E':            /* Error packet received    */
  380.         prerrpkt(recpkt);        /* Print it out and    */
  381.         return('A');        /* abort    */
  382.  
  383.     case FALSE:            /* Receive failure    */
  384.         if (list != 1)
  385.         txtout(trying);
  386.     case 'N':            /* NAK, try it again    */
  387.         return(state);
  388.  
  389.     case 'A':            /* User abort        */
  390.         sendfail();
  391.         return('A');
  392.  
  393.     default:        /* Anything else, just "abort"    */
  394.         printmsg(badmsg,'Y',type);
  395.         return('A');
  396.     }
  397.  }        /* end of sinit()                */
  398.  
  399.  
  400.  
  401. /*********************  END of KSEND.C  ****************************/
  402.  
  403.  
  404.