#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); }