home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / uniflex / ufrecs.c < prev    next >
C/C++ Source or Header  |  1993-08-22  |  17KB  |  477 lines

  1. #include "ufk.h"
  2. #include <stat.h>
  3.  
  4. char stopflag;
  5.  
  6. recfile()
  7. {
  8.    if (numprm > 2)
  9.       prterr(ER_ONENAME);              /* Only one name allowed */
  10.    else
  11.    {
  12.       if (!open_port(TRUE,FALSE))      /* Setup communication port */
  13.          prterr(ER_POPNERR);
  14.       else
  15.       {
  16.          if (numprm == 2)
  17.             strcpy(rec_filnam,params[1]); /* Get filename to use */
  18.          else
  19.             rec_filnam[0] = '\0';      /* Use default name */
  20.          if (alloc_pkt(RECEIVE))       /* Allocate receive packet */
  21.          {
  22.             rflg = 1;                  /* Receive command */
  23.             n = 0;                     /* Init packet number */
  24.             set_frame();
  25.             purgeline(ttyfd);          /* Eat old input */
  26.             if (!recsw('R'))           /* Receive the file(s) */
  27.                disp(0,18,"Receive failed.\n");
  28.             beep();
  29.          }
  30.          close_port(rflg,FALSE);
  31.       }
  32.    }
  33. }
  34.  
  35. getfile()
  36. {
  37.    char status, i;
  38.  
  39.    if (numprm <= 1)                    /* check for parameter */
  40.       prterr(ER_FSPCREQ);
  41.    else
  42.    {
  43.       if (!open_port(TRUE,FALSE))      /* Setup communication port */
  44.          prterr(ER_POPNERR);
  45.       else
  46.       {
  47.          rec_filnam[0] = '\0';         /* Use default name */
  48.          if (alloc_pkt(RECEIVE))       /* Allocate receive packet */
  49.          {
  50.             rflg = 2;                  /* 'GET' command */
  51.             n = 0;                     /* Init packet number */
  52.             set_frame();
  53.             i = TRUE;
  54.             while (get_file_spec(i))   /* Get filespec */
  55.             {
  56.                i = FALSE;
  57.                if (!(status = get()))  /* Get the file */
  58.                   break;
  59.             }
  60.             while (get_file_spec(FALSE)); /* Flush filespec */
  61.             if (!status)
  62.                disp(0,18,"Get failed.\n");/* Report failure */
  63.             beep();
  64.          }
  65.          close_port(rflg,FALSE);
  66.       }
  67.    }
  68. }
  69.  
  70. /*
  71.  * get file from remote server
  72.  */
  73.  
  74. get()
  75. {
  76.    char num;
  77.    int len;
  78.  
  79.    n = 0;
  80.    numtry = 0;
  81.  
  82.    set_default_comm();                 /* Set default communication */
  83.    aborted = FALSE;
  84.    while(TRUE)
  85.    {
  86.       len = strlen(filnam);
  87.       strcpy(sndpkt,filnam);           /* Setup filename */
  88.  
  89.       if (debug)
  90.       {
  91.          prtdbgf("Receive state: ");
  92.          if (!screen)
  93.             fputs("Receive state: ",stdout);
  94.          disp_state(16,13,'R');
  95.       }
  96.       spack('R',n,len,sndpkt,0,1);     /* Receiver init */
  97.       switch(rpack(&len,&num,recpkt,1))
  98.       {
  99.          case 'S':
  100.                   rpar(recpkt,len);    /* Get the other side's init data */
  101.                   spar(sndpkt,&len);   /* Fill up packet with my init info */
  102.                   spack('Y',n,len,sndpkt,0,1); /* ACK with my parameters */
  103.                   oldtry = numtry;     /* Save old try count */
  104.                   numtry = 0;          /* Start a new counter */
  105.                   n = (n + 1) % 64;    /* Bump packet number, mod 64 */
  106.                   return(recsw('F'));  /* Enter File-Receive state */
  107.  
  108.          case 'E':
  109.                   prerrpkt(recpkt);    /* error return */
  110.                   return(FALSE);
  111.  
  112.          case 'T':
  113.                   if (aborted)         /* user abort */
  114.                      return(FALSE);
  115.  
  116.          default:
  117.                   if (numtry++ >= maxtry)
  118.                      return (FALSE);   /* max try's exceeded */
  119.       }
  120.    }
  121. }
  122.  
  123. /*
  124.  *  r e c s w
  125.  *
  126.  *  This is the state table switcher for receiving files.
  127.  */
  128.  
  129. recsw(istate)
  130. char istate;
  131. {
  132.    char  rinit(), rfile(), rdata();       /* Use these procedures */
  133.  
  134.    init_xfer();                           /* reset character counters */
  135.    if (istate != 'F')                     /* if not already done */
  136.       set_default_comm();                 /* Set default communication */
  137.    state = istate;                        /* set start state 'R' or 'F' */
  138.    numtry = 0;                            /* Say no tries yet */
  139.    stopflag = FALSE;                      /* Not stopped yet */
  140.    aborted = FALSE;                       /* Not aborted yet */
  141.  
  142.    while(TRUE)
  143.    {
  144.       if (debug)
  145.       {
  146.          prtdbgf("Receive state: ");
  147.          if (!screen)
  148.             fputs("Receive state: ",stdout);
  149.          disp_state(16,13,state);
  150.       }
  151.       switch(state)                       /* Do until done */
  152.       {
  153.          case 'R':                        /* Receive-Init */
  154.                state = rinit();
  155.                break;
  156.  
  157.          case 'F':                        /* Receive-File */
  158.                state = rfile();
  159.                break;
  160.  
  161.          case 'D':                        /* Receive-Data */
  162.                state = rdata();
  163.                break;
  164.  
  165.          case 'C':                        /* Complete state */
  166.                fin_xfer();
  167.                return(TRUE);
  168.  
  169.          case 'Q':
  170.          default:                         /* Unknown or abort */
  171.                fin_xfer();
  172.                return(FALSE);
  173.       }
  174.    }
  175. }
  176.  
  177.  
  178. /*
  179.  *  r i n i t
  180.  *
  181.  *  Receive Initialization
  182.  */
  183.  
  184. char rinit()
  185. {
  186.    char  num;                             /* Packet number */
  187.    int len;                               /* length */
  188.  
  189.    if (numtry++ >= maxtry)                /* If too many tries, "abort" */
  190.       return('Q');
  191.  
  192.    switch(rpack(&len,&num,recpkt,1))      /* Get a packet */
  193.    {
  194.       case 'S':                           /* Send-Init */
  195.             rpar(recpkt,len);             /* Get the other side's init data */
  196.             spar(sndpkt,&len);            /* Fill packet with my init info */
  197.             spack('Y',n,len,sndpkt,0,1);  /* ACK with my parameters */
  198.             oldtry = numtry;              /* Save old try count */
  199.             numtry = 0;                   /* Start a new counter */
  200.             n = (n + 1) % 64;             /* Bump packet number, mod 64 */
  201.             return('F');                  /* Enter File-Receive state */
  202.  
  203.       case 'E':                           /* Error packet received */
  204.             prerrpkt(recpkt);             /* Print it out and */
  205.             return('Q');                  /* abort */
  206.  
  207.       case 'T':                           /* Timeout */
  208.             if (aborted)
  209.                return('Q');               /* aborted by user */
  210.       case FALSE:                         /* Didn't get packet */
  211.             spack('N',n,0,0,0,1);         /* Return a NAK */
  212.             return(state);                /* Keep trying */
  213.  
  214.       default:                            /* Some other packet type, "abort" */
  215.             return('Q');
  216.    }
  217. }
  218.  
  219.  
  220. /*
  221.  *  r f i l e
  222.  *
  223.  *  Receive File Header
  224.  */
  225.  
  226. char rfile()
  227. {
  228.    char  num, *w;                         /* Packet number */
  229.    int len;                               /* length */
  230.    struct stat buf;
  231.  
  232.    if (numtry++ >= maxtry)                /* "abort" if too many tries */
  233.       return('Q');
  234.  
  235.    switch(rpack(&len,&num,recpkt,block_check_type)) /* Get a packet */
  236.    {
  237.       case 'S':                           /* Send-Init, maybe our ACK lost */
  238.             if (oldtry++ >= maxtry)       /* If too many tries "abort" */
  239.                return('Q');
  240.             if (num == ((n == 0) ? 63 : n-1)) /* Previous packet, mod 64? */
  241.             {                             /* Yes, ACK it again with  */
  242.                spar(sndpkt,&len);         /* our Send-Init parameters */
  243.                spack('Y',num,len,sndpkt,0,1);
  244.                numtry = 0;                /* Reset try counter */
  245.                return(state);             /* Stay in this state */
  246.             }
  247.             else                          /* Not previous packet, "abort" */
  248.                return('Q');
  249.  
  250.       case 'Z':                           /* End-Of-File */
  251.             if (oldtry++ >= maxtry)
  252.                return('Q');
  253.             if (num == ((n==0) ? 63 : n-1)) /* Previous packet, mod 64? */
  254.             {                             /* Yes, ACK it again. */
  255.                spack('Y',num,0,0,0,block_check_type);
  256.                numtry = 0;
  257.                return(state);             /* Stay in this state */
  258.             }
  259.             else                          /* Not previous packet, "abort" */
  260.                return('Q');
  261.  
  262.       case 'F':                           /* File Header (just what we want) */
  263.             if (num != n)                 /* The packet number must be right */
  264.                return('Q');
  265.             if (!rec_filnam[0])           /* Copy filename if not given */
  266.                bufemp(recpkt,len,rec_filnam);
  267.             map_case(rec_filnam,IN);      /* map to correct case */
  268.             tabsleft = TABSIZE;           /* Restore for real data */
  269.             transmit_chr_count = 0;       /* Counter for total data size */
  270.             w = "w";                      /* open text file   */
  271.  
  272.             if (warning && !stat(rec_filnam,&buf))
  273.             {                             /* File already there */
  274.                if (!remote && !nooutput)
  275.                {
  276.                   clreol(0,19);
  277.                printf("Warning: File %s already exists, creating new name",
  278.                       rec_filnam);
  279.                   beep();
  280.                   if (!screen)
  281.                      fputs("\n\l",stdout);
  282.                }
  283.                new_name(rec_filnam);    /* Create new filename */
  284.             }
  285.             if ((fp = fopen(rec_filnam,w)) == NULL)/* Try to open new file */
  286.             {
  287.                error(PER_CREATE,"%s",rec_filnam);  /* Give up if error */
  288.                return('Q');
  289.             }
  290.             else if (!nooutput)           /* OK, give message */
  291.             {
  292.                if (screen)
  293.                {
  294.                   disp(0,2,"Receiving: ");
  295.                   disp(20,2,rec_filnam);
  296.                   clreol(-1,-1);
  297.                }
  298.                else
  299.                   printf("\n\lReceiving: %s\n\l",rec_filnam);
  300.                prtdbgf("New file name: %s\n",rec_filnam);
  301.             }
  302.  
  303.             spack('Y',n,0,0,0,block_check_type); /* Acknowledge file header */
  304.             oldtry = numtry;              /* Reset try counters */
  305.             numtry = 0;                   /* ... */
  306.             stopflag = FALSE;             /* In case we're aborted */
  307.             aborted = FALSE;
  308.             init_attributes();            /* Prepare for attribute packets */
  309.             n = (n + 1) % 64;             /* Bump packet number, mod 64 */
  310.             return('D');                  /* Switch to Data state */
  311.  
  312.       case 'B':                           /* Break transmission (EOT) */
  313.             if (num != n)                 /* Need right packet number here */
  314.                return ('Q');
  315.             spack('Y',n,0,0,0,block_check_type); /* Say OK */
  316.             return('C');                  /* Go to complete state */
  317.  
  318.       case 'E':                           /* Error packet received */
  319.             prerrpkt(recpkt);             /* Print it out and */
  320.             return('Q');                  /* abort */
  321.  
  322.       case 'T':                           /* Timeout */
  323.             if (aborted)
  324.             {
  325.                error(PER_ABORTED);        /* send error packet */
  326.                return('Q');               /* aborted by user */
  327.             }
  328.       case FALSE:                         /* Didn't get packet */
  329.             spack('N',n,0,0,0,block_check_type); /* Return a NAK */
  330.             return(state);                /* Keep trying */
  331.  
  332.       default:                            /* Some other packet, "abort" */
  333.             return ('Q');
  334.    }
  335. }
  336.  
  337.  
  338. /*
  339.  *  r d a t a
  340.  *
  341.  *  Receive Data
  342.  */
  343.  
  344. char rdata()
  345. {
  346.    char  num;                             /* Packet number */
  347.    int   tlen;                            /* length */
  348.  
  349.    if (numtry++ >= maxtry)                /* "abort" if too many tries */
  350.       return('Q');
  351.    switch(rpack(&size,&num,recpkt,block_check_type)) /* Get packet */
  352.    {
  353.       case 'D':                           /* Got Data packet */
  354.             if (num != n)                 /* Right packet? */
  355.             {                             /* No */
  356.                if (oldtry++ >= maxtry)
  357.                   return('Q');            /* If too many tries, abort */
  358.                if (num == ((n==0) ? 63 : n-1)) /* Else check packet number */
  359.                {                          /* Previous packet again? */
  360.                   spack('Y',num,0,0,0,block_check_type); /* Yes, re-ACK it */
  361.                   numtry = 0;             /* Reset try counter */
  362.                   return(state);          /* Don't write out data! */
  363.                }
  364.                else                       /* sorry, wrong number */
  365.                   return('Q');
  366.             }
  367.             if (stopflag)                 /* Other side still sending ? */
  368.             {
  369.                error(PER_ABORTED);        /* Transfer aborted */
  370.                return('Q');
  371.             }
  372.             /* Got data with right packet number */
  373.             if (bufemp(recpkt,size,0) == ERROR)/* Write the data to the file */
  374.             {
  375.                error(PER_WRITE,"%d",errno);/* UniFLEX error */
  376.                return('Q');               /* enter abort state */
  377.             }
  378.             tlen = 1;                     /* Assume aborted */
  379.             stopflag = TRUE;
  380.             if (aborted == ABORTX)        /* Abort current file ? */
  381.                *sndpkt = 'X';
  382.             else if (aborted == ABORTZ)   /* Abort whole batch ? */
  383.             {
  384.                *sndpkt = 'Z';
  385.                filecount = 0;             /* No more files for 'GET' */
  386.             }
  387.             else
  388.             {
  389.                tlen = 0;                  /* Nothing to abort, length = 0 */
  390.                stopflag = FALSE;
  391.             }
  392.             *(sndpkt+sizeof(char)) = '\0';/* For debug printout */
  393.             spack('Y',n,tlen,sndpkt,0,block_check_type);/* Ack packet */
  394.             oldtry = numtry;              /* Reset the try counters */
  395.             numtry = 0;                   /* ... */
  396.             n = (n + 1) % 64;             /* Bump packet number, mod 64 */
  397.             return('D');                  /* Remain in data state */
  398.  
  399.       case 'F':                           /* Got a File Header */
  400.       case 'X':
  401.             if (oldtry++ >= maxtry)
  402.                return('Q');               /* If too many tries, "abort" */
  403.             if (num == ((n==0) ? 63 : n-1)) /* Else check packet number */
  404.             {                             /* It was the previous one */
  405.                spack('Y',num,0,0,0,block_check_type); /* ACK it again */
  406.                numtry = 0;                /* Reset try counter */
  407.                return(state);             /* Stay in Data state */
  408.             }
  409.             else                          /* Not previous packet, "abort" */
  410.                return('Q');
  411.  
  412.       case 'A':                           /* Attribute packet */
  413.             if (num != n)                 /* Must have right packet number */
  414.                return('Q');
  415.             if (attribute)
  416.             {
  417.                if (rcv_attributes() == ERROR) /* Process receive attributes */
  418.                {
  419.                   error(PER_DEVFULL);     /* Device full */
  420.                   return('Q');
  421.                }
  422.             }
  423.             else
  424.             {
  425.                error(PER_PACKET);         /* Packet error */
  426.                return('Q');
  427.             }
  428.             spack('Y',n,0,0,0,block_check_type); /* OK, ACK it. */
  429.             n = (n + 1) % 64;             /* Bump packet number */
  430.             return(state);                /* Stay in data state */
  431.  
  432.       case 'Z':                           /* End-Of-File */
  433.             if (num != n)                 /* Must have right packet number */
  434.                return('Q');
  435.             spack('Y',n,0,0,0,block_check_type); /* OK, ACK it. */
  436.             fclose(fp);                   /* Close the file */
  437.             if (attribute)
  438.                fset_attributes();         /* set file attributes if enabled */
  439.             if (size == 1)                /* Interrupt */
  440.             {
  441.                if (!nooutput)
  442.                {
  443.                   if (screen)
  444.                   {
  445.                      clreol(0,19);
  446.                      disp(0,19,"Transfer aborted.");
  447.                   }
  448.                   else
  449.                      fputs("Transfer aborted.\n\l",stdout);
  450.                   beep();
  451.                }
  452.                if ((*recpkt == 'D') && !save_file)
  453.                   unlink(rec_filnam);     /* Discard input file */
  454.             }
  455.             rec_filnam[0] = '\0';         /* Use default for next transfer */
  456.             n = (n + 1) % 64;             /* Bump packet number */
  457.             return('F');                  /* Go back to Receive File state */
  458.  
  459.       case 'E':                           /* Error packet received */
  460.             prerrpkt(recpkt);             /* Print it out and */
  461.             return('Q');                  /* abort */
  462.  
  463.       case 'T':                           /* Timeout */
  464.             if (aborted)
  465.             {
  466.                error(PER_ABORTED);        /* send error packet */
  467.                return('Q');               /* aborted by user */
  468.             }
  469.       case FALSE:                         /* Didn't get packet */
  470.             spack('N',n,0,0,0,block_check_type); /* Return a NAK */
  471.             return(state);                /* Keep trying */
  472.  
  473.       default:                            /* Some other packet, "abort" */
  474.             return('Q');
  475.    }
  476. }
  477.