home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
pub
/
uniflex
/
ufbuff.c
< prev
next >
Wrap
C/C++ Source or Header
|
2020-01-01
|
8KB
|
205 lines
#include "ufk.h"
/*
* b u f i l l
*
* Get a bufferful of data from the file that's being sent.
* Control-quoting, 8-bit & repeat count prefixes are handled.
*/
char *bptr, /* Output buffer pointer */
*ioptr; /* In/output buffer pointer */
bufill(buffer,first_time,input)
char buffer[]; /* Buffer */
char first_time; /* Called for the first time */
char input[]; /* Input comes from here if not 0 */
{
int new_char, /* Char read from file */
rpt_count,
max_data_size,
bufsize;
static int old_char; /* Previous character */
static char *savptr, /* Must be saved between calls */
*savbptr,
savbuf[6];
bptr = buffer; /* Init data buffer pointer */
ioptr = input;
max_data_size = spsiz - block_check_type;
if (spsiz > 94)
max_data_size -= 7; /* soh, len, seq, typ, lenx1, lenx2, hcheck */
else
max_data_size -= 4; /* soh, len, seq, typ */
if (first_time)
{
old_char = ioptr ? *ioptr++ : getc(fp); /* Pre-read char first time */
savbptr = savbuf;
}
if (savbptr != savbuf) /* Data left from previous call */
for (savptr = savbuf; savptr != savbptr;)
*bptr++ = *savptr++; /* Copy old data to buffer */
savbptr = savbuf; /* No more data in save buffer */
while (old_char != EOF) /* Do until no more data */
{
rpt_count = 1;
while(((new_char = ioptr ? *ioptr++ : getc(fp)) != EOF)
&& (rpt_count < 94)
&& (repeat_quote != 0)
&& (new_char == old_char)
&& ((new_char != '\n') /* No repeat for newline */
|| binfil))
rpt_count++; /* Count consecutive match */
if (rpt_count > 1) /* We've had more of these */
if (rpt_count == 2)
insbuf(old_char); /* Insert twice if only 2 char's */
else
{
*bptr++ = repeat_quote; /* Setup repeat quote character */
*bptr++ = tochar(rpt_count); /* Send count */
}
if (!ioptr)
transmit_chr_count += rpt_count; /* Counter for total data */
insbuf(old_char);
old_char = new_char; /* Copy next character */
*bptr = '\0'; /* So it can be printed */
bufsize = bptr - buffer; /* Current number of characters */
if (bufsize > max_data_size) /* Check length */
{
while (savptr != bptr)
*savbptr++ = *savptr++; /* Copy excess data */
return (bufsize - (savbptr - savbuf));
}
else if (bufsize == max_data_size) /* Exact fit */
return (bufsize);
savptr = bptr;
}
if (bptr == buffer) /* Wind up here only on EOF */
return(EOF);
return(bptr - buffer); /* Handle partial buffer */
}
insbuf(o_char)
int o_char;
{
char chr7;
chr7 = o_char & 0177; /* Get low order 7 bits */
if ((o_char > 127) && (eight_quote != 0))
*bptr++ = eight_quote; /* Eight_bit quoting done */
if (chr7 < SP || chr7 == DEL || chr7 == quote ||
chr7 == repeat_quote || chr7 == eight_quote)
{ /* Special handling required ? */
if (o_char == '\r' && !binfil)
{ /* Do LF->CRLF mapping if !binfil */
*bptr++ = quote;
*bptr++ = ctl('\r');
o_char = chr7 = '\l';
}
*bptr++ = quote; /* Quote the character */
if ((chr7 == 0) || ((chr7 != quote) &&
(chr7 != repeat_quote) && (chr7 != eight_quote)))
{
o_char = ctl(o_char); /* Uncontrolify it */
chr7 = ctl(chr7);
}
}
if (binfil && (eight_quote == 0))
*bptr++ = o_char; /* Deposit the character itself */
else
*bptr++ = chr7; /* Only send the low bits */
}
/*
* b u f e m p
*
* Put data from an incoming packet into a file.
* Control-quoting, 8-bit & repeat count prefixes are handled.
*/
bufemp(buffer,len,output)
char buffer[]; /* Buffer */
int len; /* Length */
char output[]; /* Output buffer if not 0 */
{
int i, j, /* Counters */
rpt_count; /* Repeat counter */
char t, t7, /* Character holder */
set_bit_eight; /* flag to set bit eight */
ioptr = output; /* Init output buffer pointer */
for (i = 0; i < len; i++) /* Loop thru the data field */
{
t = buffer[i]; /* Get character */
if (t == repeat_quote) /* Repeat quoting ? */
{
rpt_count = unchar(buffer[++i]); /* Get repeat count */
t = buffer[++i]; /* Get next character */
}
else
rpt_count = 1; /* No repeat quoting, count = 1 */
if (t == eight_quote) /* Eight-bit quoting ? */
{
set_bit_eight = TRUE; /* Set bit eight */
t = buffer[++i]; /* Get next character */
}
else
set_bit_eight = FALSE; /* Don't set bit eight */
if (t == quote) /* Control quote? */
{ /* Yes */
t = buffer[++i]; /* Get the quoted character */
t7 = t & 0177; /* Character without parity bit */
if ((t7 >= ctl(DEL)) && (t7 <= ctl(DEL) + 32))
t = ctl(t); /* Undo what others did to it */
}
if (set_bit_eight)
t |= 0x80; /* Set bit eight on request */
if (!ioptr)
transmit_chr_count += rpt_count; /* Counter for total data */
for (j = 0; j < rpt_count; j++)
if (binfil)
{
if (ioptr)
*ioptr++ = t; /* Put in output buffer if specified */
/*
* Error checking is nonsense here. putc returns it's argument if
* successful. What if 255 is written ? If putc is declared as
* char, the return value will be sign extended giving -1 == ERROR !!
* If declared as unsigned char the return value will be between 0
* and 255, which can be data. So error checking can't be done here!!
*/
else
putc(t,fp); /* send to file if image mode */
}
else
{
if (t == LF) /* strip LF in non-image mode */
{
transmit_chr_count--; /* Adjust count for char not written */
break;
}
if (t == TAB) /* expand tabs to spaces */
{
while (--tabsleft >= 0)
if (ioptr)
*ioptr++ = ' ';
else if (putc(' ',fp) == ERROR)
return(ERROR);
tabsleft = TABSIZE; /* reset tabcounter */
}
else /* pass character */
{
if (ioptr)
*ioptr++ = t; /* put in output buf if specified */
else if (putc(t,fp) == ERROR)
return(ERROR);
if ((--tabsleft <= 0) || (t == CR))
tabsleft = TABSIZE; /* take care of tabcount */
}
}
}
if (ioptr)
*ioptr = '\0'; /* Terminate string */
return(NULL);
}