home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / perkinelmeridris / pe7pta.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  19KB  |  715 lines

  1. /* pe7pta.c */
  2. /* Include external declarations */
  3. #include "pe7inc.h"
  4.  
  5. /*
  6.  *    g i n i t
  7.  *
  8.  *    Get receive Initialization
  9.  *
  10.  */
  11.  
  12. TEXT ginit(l, file)
  13. int l;                /* Length of the filename */
  14. TEXT *file;            /* File name pointer */
  15. {
  16.     int len, num, slen;            /* Packet length, number */
  17.  
  18.     if (numtry++ > MAXTRY) return ('A'); /* If too many tries, "abort" */
  19.     flushinput();            /* Clear out the i/o channel */
  20.  
  21.     spack('R',n,l,file);        /* Send the requested file name */
  22.     switch(rpack(&len,&num,recpkt)) /* Get a packet */
  23.     {
  24.     case 'S':                /* Send-Init packet */
  25.         if ( n != num)
  26.         {
  27.     case 'N':
  28.     case FALSE:
  29.             nxi++;
  30.             return (state);
  31.         }
  32.         if (!rpar(recpkt,&len))    /* Get the other side's init data */
  33.             return ('A');    /* error with the packet parameters */
  34.         slen = spar(packet0);    /* Fill up packet with my init info */
  35.         spack('Y',n,slen,packet0);/* ACK with my parameters */
  36.         oldtry = numtry;    /* Save old try count */
  37.         nxtpkt();
  38.         return ('F');        /* Enter File-Receive state */
  39.  
  40.     case 'E':                /* Error packet received */
  41.         prerrpkt(recpkt);    /* Print it out and */
  42.     default:
  43.         return ('A');        /* Some other packet type, "abort" */
  44.     }
  45. }
  46.  
  47. /*
  48.  *    x i n i t
  49.  *
  50.  *    Server command scanning
  51.  */
  52.     
  53. TEXT xinit()
  54. {
  55.     int i,                    /* A counter */
  56.         search,                /* Filename search state flag */
  57.         len, num, slen;            /* Packet length, number */
  58.     TEXT *filep;        /* Pointer to input buffer */
  59.  
  60.     switch(rpack(&len,&num,recpkt)) /* Get a packet */
  61.     {
  62.     case 'S':                /* Send-Init packet */
  63.         if (!rpar(recpkt,&len))    /* Get the other side's init data */
  64.             return ('A');        /* error with the packet parameters */
  65.         slen = spar(packet0);        /* Fill up packet with my init info */
  66.         spack('Y',n,slen,packet0); /* ACK with my parameters */
  67.         oldtry = numtry;    /* Save old try count */
  68.         nxtpkt();
  69.         return ('F');        /* Enter File-Receive state */
  70.  
  71.     case 'I':                /* Send-Init packet */
  72.         if (!rpar(recpkt,&len))    /* Get the other side's init data */
  73.             return ('A');        /* error with the packet parameters */
  74.         slen = spar(packet0);        /* Fill up packet with my init info */
  75.         spack('Y',n,slen,packet0); /* ACK with my parameters */
  76.         oldtry = numtry;    /* Save old try count */
  77.         n = 0;
  78.         numtry = 0;
  79.         return (state);        /* Say we got our parameters */
  80.  
  81.     case 'E':                /* Error packet received */
  82.         prerrpkt(recpkt);    /* Print it out and */
  83.         return ('A');        /* abort */
  84.  
  85.     case FALSE:                /* Didn't get packet */
  86.         nxi++;
  87.         spack('N',n,0,0);    /* Return a NAK */
  88.     case 'N':
  89.         return (state);        /* Keep trying */
  90.  
  91.     case 'R':
  92.         /* copy the packet data into a filename_buffer */
  93.         /* cpystr(&filename_buffer, &recpkt, NULL); /* */
  94.         btobemp(filename_buffer, recpkt, MAXPACKSIZ); /* Uncode packet */
  95.         filecount = 0;
  96.         filelist = &files;
  97.         filep = &filename_buffer;
  98.         search = 2;
  99.         while (*filep != NULL && filecount < 10)
  100.         {
  101.             switch (search)
  102.             {
  103.             case 1:        /* Looking for next filename */
  104.                 if (iswhite(*filep))
  105.                     break;
  106.                 search = 2;
  107.             case 2:        /* Looking for filename */
  108.                 if (iswhite(*filep))
  109.                     break;
  110.                 files[filecount++] = filep;
  111.                 search = 3;
  112.             case 3:        /* Looking for end of filename */
  113.                 if (!iswhite(*filep))
  114.                     break;
  115.                 *filep = NULL;
  116.                 search = 1;
  117.             }
  118.             filep++;
  119.         }
  120.         if (debug) printf("Xinit 1: Request for %d files...\n", filecount);
  121.         if (gnxtfl() == FALSE)    /* Any files to send? */
  122.             return ('B');    /* if not, break, EOT, all done */
  123.         return ('S');        /* Start sending files, switch state to S */
  124.     case 'G':
  125.         if (recpkt[0] == 'F')
  126.         {
  127.             spack('Y',n,0,0);    /* say ok */
  128.             return ('G');
  129.         }
  130.         else
  131.         {
  132.             error("Invalid server command");
  133.             return (state);    /* keep trying */
  134.         }
  135.     default:
  136.         error("Unknown packet type");
  137.         return (state);
  138.     }
  139. }
  140.  
  141. /*
  142.  *    s f i l e
  143.  *
  144.  *    Send File Header.
  145.  */
  146.  
  147. TEXT sfile()
  148. {
  149.     TEXT filnam1[MAXFNAME],        /* Converted file name */
  150.     *newfilnam,                /* Pointer to file name to send */
  151.     *cp;                    /* char pointer */
  152.     int num, len;            /* Packet number, length */
  153.     ULONG time();
  154.  
  155.     if (numtry++ > MAXTRY) return ('A'); /* If too many tries, give up */
  156.     
  157.     if (fd == NULL)            /* If not already open, */
  158.     {
  159.         if (debug) printf("Sfile 1: Opening %s for sending.\n",filnam);
  160.         /* Open file to be sent */
  161.         if ((fd = fopen(&pfio, filnam, READ)) == NULL)
  162.                             /* If bad file pointer, give up */
  163.         {
  164.             printmsg("Cannot open file %s\n",filnam);
  165.             return ('A');
  166.         }
  167.  
  168.         /* cpystr(filnam1, filnam, NULL);    /* Copy file name */
  169.         btobemp(filnam1, filnam, MAXFNAME);    /* Copy file name */
  170.         newfilnam = cp = filnam1;
  171.         while (*cp != '\0')        /* Strip off all leading directory */
  172.             if (*cp++ == '/')        /* names (ie. up to the last /). */
  173.                 newfilnam = cp;
  174.  
  175.         if (filnamcnv)            /* Convert lower case to upper */
  176.             for (cp = newfilnam; *cp != '\0'; cp++)
  177.                 *cp = toupper(*cp);
  178.  
  179.         len = cp - newfilnam;        /* Compute length of new filename */
  180.  
  181.         if (vflg)
  182.             printmsg("Sending %s as %s",filnam,newfilnam);
  183.     }
  184.     dostat(2);
  185.     spack('F',n,len,newfilnam); /* Send an F packet */
  186.     switch(rpack(&len,&num,recpkt)) /* What was the reply? */
  187.     {
  188.     case 'N':                /* NAK, just stay in this state, */
  189.         num = (--num<0 ? 63 : num);/* unless it's NAK for next packet */
  190.     case 'Y':
  191.         if (n != num)        /* which is just like an ACK for */ 
  192.         {                    /* Wrong packet number */
  193.     case FALSE:                /* Receive failure, stay in F state */
  194.             nxi++;
  195.             return (state);
  196.         }
  197.         nxtpkt();
  198.         dostat(4);
  199.         repeat_count = 0;    /* Reset repeat character counter */
  200.         empty[1-pknum] = 0;    /* Make other buffer empty */
  201.         if ((empty[pknum] = size[pknum] = bufill (packet[pknum])) != EOF)
  202.             return ('E');    /* Switch to data state */
  203.         return ('Z');        /* Must be end of file */
  204.  
  205.     case 'E':                /* Error packet received */
  206.         prerrpkt(recpkt);    /* Print it out and */
  207.     default:
  208.         return ('A');        /* Something else, just "abort" */
  209.     }
  210. }
  211.  
  212. /*
  213.  *    r f i l e
  214.  *
  215.  *    Receive File Header
  216.  */
  217.  
  218. TEXT rfile()
  219. {
  220.     TEXT filnam1[MAXFNAME];        /* Holds the converted file name */
  221.     int num, len, slen;            /* Packet number, length */
  222.     int dum;                /* Holds array pointer */
  223.     ULONG time();
  224.  
  225.     if (numtry++ > MAXTRY) return ('A'); /* "abort" if too many tries */
  226.     dostat(2);
  227.     switch(rpack(&len,&num,recpkt)) /* Get a packet */
  228.     {
  229.     case 'S':            /* Send-Init, maybe our ACK lost */
  230.         if (oldtry++ > MAXTRY) return ('A'); /* If too many tries "abort" */
  231.         if (num == ((n==0) ? 63 : n-1)) /* Previous packet, mod 64? */
  232.         {
  233.             /* Yes, ACK it again with    */
  234.             slen = spar(packet0);/* our Send-Init parameters */
  235.             spack('Y',num,slen,packet0);
  236.             numtry = 0; /* Reset try counter */
  237.             return (state);    /* Stay in this state */
  238.         }
  239.         else return ('A');    /* Not previous packet, "abort" */
  240.  
  241.     case 'Z':            /* End-Of-File */
  242.         if (oldtry++ > MAXTRY) return ('A');
  243.         if (num == ((n==0) ? 63 : n-1)) /* Previous packet, mod 64? */
  244.         {
  245.             /* Yes, ACK it again. */
  246.             spack('Y',num,0,0);
  247.             numtry = 0;
  248.             return (state);    /* Stay in this state */
  249.         }
  250.         else return ('A');    /* Not previous packet, "abort" */
  251.  
  252.     case 'F':            /* File Header (just what we want) */
  253.         if (num != n) return ('A');/* The packet number must be right */
  254.         /* cpystr(filnam1, recpkt, NULL);    /* Copy the file name */
  255.         btobemp(filnam1, recpkt, MAXFNAME);    /* Copy the file name */
  256.  
  257.         if (filnamcnv)        /* Convert upper case to lower */
  258.             for (filnam=filnam1; *filnam != '\0'; filnam++)
  259.                 *filnam = tolower(*filnam);
  260.  
  261.         /* Create the file for writing into */
  262.         if ((fd = fcreate(&pfio, filnam1, WRITE)) == NULL)
  263.         {
  264.             error("Cannot create %s",filnam1); /* Give up if can't */
  265.             return ('A');
  266.         }
  267.         if (vflg)
  268.             printmsg("Receiving %s as %s",recpkt,filnam1);
  269.         spack('Y',n,0,0);    /* Acknowledge the file header */
  270.         oldtry = numtry;    /* Reset try counters */
  271.         nxtpkt();
  272.         dostat(4);
  273.         return ('D');        /* Switch to Data state */
  274.  
  275.     case 'B':            /* Break transmission (EOT) */
  276.         if (num != n) return ('A'); /* Need right packet number here */
  277.         spack('Y',n,0,0);    /* Say OK */
  278.         return ('C');        /* Go to complete state */
  279.  
  280.     case FALSE:            /* Didn't get packet */
  281.         nxi++;
  282.         spack('N',n,0,0);    /* Return a NAK */
  283.         return (state);        /* Keep trying */
  284.  
  285.     case 'E':            /* Error packet received */
  286.         prerrpkt(recpkt);    /* Print it out and */
  287.     default:
  288.         return ('A');        /* Some other packet, "abort" */
  289.     }
  290. }
  291.  
  292. /*
  293.  * Checksum computations
  294.  *
  295.  * chk1 - Compute a type 1 Kermit 6 bit checksum
  296.  * chk2 - Compute a type 2 Kermit block check
  297.  * chk3 - Compute a type 3 Kermit block check
  298.  *
  299.  */
  300. chk1(packet)
  301.     char *packet;
  302. {
  303.     int checksum;
  304.     checksum = chk2(packet);
  305.     return ((((checksum & 0300) >> 6) + checksum) & 077);
  306. }
  307.  
  308. chk2(packet)
  309.     char *packet;
  310. {
  311.     ULONG checksum;
  312.  
  313.     for (checksum = 0; *packet != '\0' ; packet++)
  314.         checksum += pflg ? *packet & 0177 : *packet;
  315.     return (checksum);
  316. }
  317.  
  318. chk3(packet)
  319.     char *packet;
  320. {
  321.     int c, checksum, q;
  322.  
  323.     checksum = 0;
  324.     while ((c = pflg ? *packet & 0177 : *packet) != '\0')
  325.     {
  326.         q = (checksum ^ c) & 017;        /* Low order nibble */
  327.         checksum = (checksum >> 4) ^ (q * 010201);
  328.         q = (checksum ^ (c >> 4)) & 017;    /* High order nibble */
  329.         checksum = (checksum >> 4) ^ (q * 010201);
  330.         packet++;
  331.     }
  332.     return (checksum);
  333. }
  334.  
  335. /*
  336.  *    s p a r
  337.  *
  338.  *    Fill the data array with my send-init parameters
  339.  *
  340.  */
  341.  
  342. spar(data)
  343. TEXT data[];
  344. {
  345.     int len;
  346.     data[0] = tochar(MAXPACKSIZ);/* Biggest packet I can receive */
  347.     data[1] = tochar(MYTIME);    /* When I want to be timed out */
  348.     data[2] = tochar(MYPAD);    /* How much padding I need */
  349.     data[3] = ctl(MYPCHAR);        /* Padding character I want */
  350.     data[4] = tochar(MYEOL);    /* End-Of-Line character I want */
  351.     data[5] = MYQUOTE;            /* Control-Quote character I send */
  352.     if (state == 'S')
  353.     {
  354.         /* Set up the startup parameters */
  355.         /* The other side may call the shots if we are a server */
  356.         data[6] = sqbin = image ? pflg ? MYQBIN : DEFQBIN : 'N';
  357.         data[7] = DEFCHKT;        /* I will use this check sum */
  358.         data[8] = DEFREPT;        /* This is my repeat character */
  359.         data[9] = tochar(NULL); /* No bit mask at this time */
  360.         data[10] = tochar(NULL);
  361.         data[11] = tochar(NULL);
  362.         data[12] = tochar(NULL);
  363.         data[13] = tochar(NULL);
  364.         /* Tell the other side what we set up in the start */
  365.         data[14] = image ? tochar( 1 ) : tochar ( NULL );
  366.         data[15] = pflg ? pflg : tochar(NULL);
  367.         len = 16;
  368.     }
  369.     else        /* Receive flag must be on. We are not the starters */
  370.     {
  371.         data[6] = rqbin;        /* Quote character both sides will use */
  372.         data[7] = chkt;            /* Checksum type */
  373.         data[8] = rrept;        /* Set My repeat character */
  374.         data[9] = tochar(NULL); /* No bit mask at this time */
  375.         len = 10;
  376.     }
  377.     if (debug > 1)
  378.     {
  379.         printf("Spar: spsiz=%d, timint=%d\n", spsiz, timint);
  380.         printf("      pad=%d, padchar=%d, eol=%d, ", pad, padchar, eol);
  381.         printf("quote=%d, qbin=%d, chkt=%d, ", quote, qbin, chkt);
  382.         printf("rept=%d\n", rept);
  383.         if (len > 10)
  384.             printf("      image= %d, pflg= %c, iflg= %d, spflg= %c\n",
  385.                 image,pflg,iflg,spflg);
  386.     }
  387.     return ( len );
  388. }
  389.  
  390. /*    r p a r
  391.  *
  392.  *    Get the other host's send-init parameters
  393.  *
  394.  */
  395.  
  396. rpar(data,len)
  397. TEXT data[];
  398. int *len;
  399. {
  400.     TEXT chkchar();
  401.  
  402. /* Maximum send packet size */
  403.     spsiz = *len < 1 ? DEFPACKSIZ : unchar(data[0]);
  404.  
  405. /* When I should time out */
  406.     timint = *len < 2 ? MYTIME : unchar(data[1]);
  407.  
  408. /* Number of pads to send */
  409.     pad = *len < 3 ? 0 : unchar(data[2]);
  410.  
  411. /* Padding character to send */
  412.     padchar = dopar(*len < 4 ? NULL : ctl(data[3]));
  413.  
  414. /* EOL character I must send */
  415.     eol = *len < 5 ? CR : unchar(data[4]);
  416.  
  417. /* Incoming data quote character */
  418.     quote = *len < 6 ? '#' : data[5];
  419.  
  420. /* Force to a type one check sum */
  421.     chkt = *len < 8 ? DEFCHKT : data[7] != MYCHKT ? DEFCHKT : MYCHKT;
  422.  
  423. /* Set up the multi repeat char */
  424.     rrept = *len < 9 ? ' ' : data[8];
  425.  
  426.     if (state != 'S')
  427.     {
  428. /* Determine the state of image and parity flags from the other side */
  429.         image = *len < 15 ? iflg : data[14] == SP ? FALSE : TRUE;
  430.         pflg = *len < 16 ? spflg : data[15] == SP ? FALSE : data[15];
  431.  
  432. /* Determine the state of the sqbin */
  433.         sqbin = image ? pflg ? MYQBIN : DEFQBIN : 'N';
  434.  
  435. /* Determine the quoting mode we will use based on what the other side
  436.  * allows and what we are capable of */
  437.         rqbin = *len < 7 ? 'N' : data[6] == DEFQBIN ? sqbin : data[6];
  438.         qbin  = chkchar(rqbin);
  439.  
  440. /* Determine the repeat mode based on what the other side allows */
  441.         rept = chkchar(rrept);
  442.  
  443.     }
  444.     else
  445.     {
  446. /* Determine the final quoting mode based on what the other side allows */
  447.         rqbin = *len < 7 ? 'N' : data[6];
  448.         qbin = sqbin == DEFQBIN ?
  449.             chkchar(rqbin) : rqbin == MYQBIN ? MYQBIN : FALSE;
  450.  
  451. /* Determine the final repeat mode based on what the other side allows */
  452.         rept = rrept == DEFREPT ? rrept : FALSE;
  453.     }
  454.  
  455. /* Force 8 bit quoting if requested and we are not generating parity */
  456.     if (qbin && !pflg)
  457.         pflg = 'n';
  458.     /* Maybe we can not do image because the other end can
  459.         not support binary quote */
  460.     if (image && rqbin == 'N')
  461.     {
  462.         error("Binary file transfer not supported");
  463.         return (FALSE);
  464.     }
  465.  
  466.     if (debug > 1)
  467.     {
  468.         printf("Rpar: spsiz=%d, timint=%d\n", spsiz, timint);
  469.         printf("      pad=%d, padchar=%d, eol=%d, ", pad, padchar, eol);
  470.         printf("quote=%d, qbin=%d, chkt=%d, ", quote, qbin, chkt);
  471.         printf("rept=%d\n", rept);
  472.         if (*len > 14 )
  473.             printf("      image=%d, pflg=%c\n",image,pflg);
  474.     }
  475.     return (TRUE);
  476. }
  477.  
  478. /*
  479.  *    b u f i l l
  480.  *
  481.  *    Get a bufferful of data from the file that's being sent.
  482.  *
  483.  */
  484.  
  485. bufill(buffer)
  486. TEXT buffer[];            /* Buffer */
  487. {
  488.     int i;                /* Loop index */
  489.     METACH t;            /* Character that may be output */
  490.     static METACH tt {0}; /* For the comparisions of the repeat count */
  491.  
  492.     i = 0;            /* Init data buffer pointer */
  493.  
  494.     while ((t = getc(&pfio)) != EOF)    /* fetch till end */
  495.     {
  496.         file.fc++;
  497.         if (rept)        /* If rept set then true */
  498.         {
  499.             if (repeat_count)        /* If r..c.. set then true */
  500.             {
  501.                 /* Check for repeat character and not too many of them */
  502.                 if ((tt == t) && (++repeat_count < 95))
  503.                     continue;
  504.                 /* The characters were different or we ran out of
  505.                         repeat count */
  506.                 if (repeat_count > 3) /* Output repeat string */
  507.                 {
  508.                     buffer[i++] = rept;
  509.                     if (repeat_count >= 95) repeat_count = 94;
  510.                     buffer[i++] = tochar(repeat_count);
  511.                     repeat_count = 1;        /* Set for next */
  512.                 }
  513.                 for (; repeat_count ; repeat_count -= 1)
  514.                     store_in_buffer(tt, buffer, &i);
  515.             /* We have output the repeat count and the repeat character */
  516.             }
  517.             /* End of repeat_count test */
  518.             tt = t;        /* Set up temps for next character */
  519.             repeat_count = 1;
  520.         }
  521.         /* End of non NULL rept */
  522.         else        /* rept = 0 */
  523.             store_in_buffer(t, buffer, &i);
  524.  
  525.         if (i >= spsiz-SPOVER) return (i);        /* Check length */
  526.     }
  527.     /* End of while loop */
  528.     /* Test if there is an repeat count outstanding.
  529.         It could be that we have not inserted any data into
  530.         output buffer */
  531.     if (repeat_count > 3)
  532.     {
  533.         buffer[i++] = rept;
  534.         buffer[i++] = tochar(repeat_count);
  535.         repeat_count = 1;        /* Set for next */
  536.     }
  537.     for (; repeat_count ; --repeat_count)
  538.         store_in_buffer(tt, buffer, &i);
  539.  
  540.     if (i==0) return (EOF);        /* Wind up here only on EOF */
  541.         /* We need to split the packet. Scan backwards for a natural
  542.             * break, and then send of the packet. When we return point
  543.             * to the data and move to the front the rest and fetch more
  544.             * more data. */
  545.         /* Natural breaks are the quote character, repeat character
  546.             * and the binary character */
  547.     return (i);            /* Handle partial buffer */
  548. }
  549.  
  550. /*
  551.  *    b u f e m p
  552.  *
  553.  *    Put data from an incoming packet into a file.
  554.  *
  555.  */
  556.  
  557. bufemp(buffer,len)
  558. register TEXT    buffer[];                /* Buffer */
  559. int len;                /* Length */
  560. {
  561.     register int i;        /* Counter for number of characters */
  562.         int ri;            /* Repeat counter for repeated characters */
  563.     TEXT t, t7, tm;    /* Character holders */
  564.  
  565.     for (i = 0; i < len; i++)        /* Loop thru the data field */
  566.     {
  567.         tm = 0;                /* Preset for next */
  568.         t = buffer[i];            /* Get character */
  569.         ri = 1;            /* Set repeat count to one (do at least one) */
  570.         /* At this point we check for a repeat character
  571.             * if the rept char is set then the condition will be tested
  572.             * else we can not get here since the character t may
  573.             * not be a NULL */
  574.         if (t == rept)        /* Repeated character? */
  575.         {
  576.             ri = unchar(buffer[++i]);    /* Fetch repeat count */
  577.             t = buffer[++i];    /* Fetch next character */
  578.         }
  579.         if (t == qbin)    /* Next character have high bit on? */
  580.         {
  581.             tm = 0200;        /* Set mask to high bit on */
  582.             t = buffer[++i];/* Fetch next character */
  583.         }
  584.         if (t == quote)        /* Control quote? */
  585.         {
  586.             /* Yes */
  587.             t = buffer[++i];    /* Get the quoted character */
  588.             t7 = t & 0177;    /* make a match character */
  589.             if (t7 != quote && t7 != rept && t7 != qbin) /* Low bits
  590.                                 match quote, rept or qbin? */
  591.             t = ctl(t);        /* No, uncontrollify it */
  592.         }
  593.         if (t==CR && !image)        /* Pass CR if in image mode */
  594.             continue;
  595.  
  596.         t |= tm;
  597.         for (; ri ; --ri) /* We put at least one character away */
  598.         {
  599.             putc(&pfio, t);
  600.             file.fc++;
  601.         }
  602.     }
  603. }
  604.  
  605. /*
  606.  *    b t o b e m p
  607.  *
  608.  *    Put data from an incoming packet into a buffer.
  609.  *
  610.  */
  611.  
  612. btobemp(bout,buffer,len)
  613. register TEXT    buffer[];                /* Buffer */
  614. register TEXT    bout[];                /* Output Buffer */
  615. int len;                /* Length */
  616. {
  617.     register int i;        /* Counter for number of characters */
  618.     register int j;     /* Output buffer counter */
  619.         int ri;            /* Repeat counter for repeated characters */
  620.     TEXT t, t7, tm;    /* Character holders */
  621.  
  622.     j = 0;                            /* Initialize output buffer pointer */
  623.     if(debug) printf("[btobemp] buffer=>>>%s<<<\n",buffer);
  624.     /* for (i = 0; i < len; i++)        /* Loop thru the data field */
  625.     for (i = 0;  buffer[i] != '\0'; i++)        /* Loop thru the data field */
  626.     {
  627.         tm = 0;                /* Preset for next */
  628.         t = buffer[i];            /* Get character */
  629.         ri = 1;            /* Set repeat count to one (do at least one) */
  630.         /* At this point we check for a repeat character
  631.             * if the rept char is set then the condition will be tested
  632.             * else we can not get here since the character t may
  633.             * not be a NULL */
  634.         if (t == rept)        /* Repeated character? */
  635.         {
  636.             ri = unchar(buffer[++i]);    /* Fetch repeat count */
  637.             t = buffer[++i];    /* Fetch next character */
  638.         }
  639.         if (t == qbin)    /* Next character have high bit on? */
  640.         {
  641.             tm = 0200;        /* Set mask to high bit on */
  642.             t = buffer[++i];/* Fetch next character */
  643.         }
  644.         if (t == quote)        /* Control quote? */
  645.         {
  646.             /* Yes */
  647.             t = buffer[++i];    /* Get the quoted character */
  648.             t7 = t & 0177;    /* make a match character */
  649.             if (t7 != quote && t7 != rept && t7 != qbin) /* Low bits
  650.                                 match quote, rept or qbin? */
  651.             t = ctl(t);        /* No, uncontrollify it */
  652.         }
  653.         if (t==CR && !image)        /* Pass CR if in image mode */
  654.             continue;
  655.  
  656.         t |= tm;
  657.         for (; ri ; --ri) /* We put at least one character away */
  658.         {
  659.             if( j >= (len) ) {
  660.             printf("Kermit: [btobemp] Expanded packet overflows buffer\
  661. \n         j=%d     MAXFNAME=%d\n",j,(MAXFNAME));
  662.             error("Kermit: [btobemp] Expanded packet overflows buffer\n");
  663.             break;
  664.             }
  665.             bout[j] = t;
  666.             j++;
  667.         }
  668.     }
  669.     if( j < len )
  670.         bout[j] = '\0';
  671. }
  672.  
  673. /*
  674.  * s t o r e _ i n _ b u f f e r
  675.  *
  676.  * This routine stores the character into the output buffer
  677.  *
  678.  */
  679.  
  680. store_in_buffer(t, buffer, i)
  681. TEXT t;
  682. register TEXT buffer[];
  683. register int *i;
  684. {
  685.     TEXT t7,tm;
  686.  
  687.     t7 = t & 0177;                /* Strip high bit */
  688.  
  689.     if (t7 == '\n' && !image)
  690.     {
  691.         /* Do LF->CRLF mapping if !image */
  692.         buffer[(*i)++] = MYQUOTE;
  693.         buffer[(*i)++] = ctl('\r');
  694.     }
  695.     if (qbin != 0 && (pflg ? t & 0200 : 0) != 0) /* Binary quote on? */
  696.         buffer[(*i)++] = MYQBIN;        /* Output a flag char */
  697.  
  698.     /* Does this character need special handling? */
  699.     if (t7 < SP || t7 == DEL)
  700.     {
  701.         /* Yes this character need some changes */
  702.         buffer[(*i)++] = MYQUOTE;    /* Quote the character */
  703.         t7 = ctl(t7);        /* and uncontrolify */
  704.         t = ctl(t);
  705.     }
  706.     else    /* it is not a special character */
  707.     {
  708.         if (t7 == MYQUOTE || t7 == rept || t7 == qbin)
  709.             buffer[(*i)++] = MYQUOTE;    /* Quote the character */
  710.     }
  711.  
  712.     buffer[(*i)++] = pflg ? t7 : t;
  713. }
  714. /* pe7pta.c End-of-file */
  715.