home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
pub
/
uniflex
/
ufpack.c
< prev
next >
Wrap
C/C++ Source or Header
|
2020-01-01
|
13KB
|
395 lines
#include "ufk.h"
#include <setjmp.h>
jmp_buf rp_env;
/*
* s p a c k
*
* Send a Packet
*/
spack(type,num,len,data,offset,check)
char type, *data,
num, check;
int len,
offset;
{
int i; /* Temporary variable */
char buffer[7]; /* Packet help buffer */
unsigned int crc, chksum, ck1, ck2, ck3,/* CRC value and checksum */
calc_crc();
register char *p, *bufp; /* Buffer pointer */
char *q; /* Temp pointer */
prtdbgf("Packet transmitted: %d, Type: %c, Length: %d\n",num,type,len);
if (!remote && !nooutput)
{
if (screen)
{
posit(20,7);
printf("%2d",num);
}
else
printf("Xmit: %d\r",num);
}
if (debug) /* Display outgoing packet */
{
if (screen)
{
clreol(0,12); /* Clear out data area */
clreol(20,11);
}
if ((debug >= 1) && !remote)
{
if (screen)
{
posit(33,7);
printf("%c",type);
posit(45,7);
printf("%4d",len);
}
else
printf("Type: %c Length: %d\n\l",type,len);
}
if (len != 0)
{
if ((debug >= 1) && !remote)
{
if (screen)
{
posit(20,11);
printf("\"%.58s\"",&data[offset]);
if (len > 58)
{
posit(20,12);
printf("\"%.58s\"",&data[58+offset]);
}
}
else
printf("Data transmitted: \"%.94s\"\n\l",&data[offset]);
}
prtdbgf("Data transmitted: \"%.94s\"\n",data);
}
}
purgeline(ttyfd); /* Eat old input */
if (sflg || rflg)
pack_sent++; /* Count packet */
bufp = buffer; /* Set up buffer pointer */
zero_crc(); /* Initialize CRC calculation */
*bufp++ = mypackstart; /* Packet marker */
if (len > 91)
i = 0; /* Use long packet format */
else
i = len + check + 2; /* Use normal length */
*bufp++ = tochar(i); /* Send the character count */
chksum = tochar(i); /* Initialize the checksum */
calc_crc(tochar(i)); /* Calculate CRC */
*bufp++ = tochar(num); /* Packet number */
chksum += tochar(num); /* Update checksum */
calc_crc(tochar(num)); /* Calculate CRC */
*bufp++ = type; /* Packet type */
chksum += type; /* Update checksum */
crc = calc_crc(type); /* Calculate CRC */
if (i == 0)
{
i = len + check; /* account for header and normal checksum */
*bufp = tochar(i / 95);
chksum += *bufp; /* Update checksum */
calc_crc(*bufp++); /* Calculate CRC */
*bufp = tochar(i % 95);
chksum += *bufp; /* Update checksum */
calc_crc(*bufp++); /* Calculate CRC */
*bufp = tochar((chksum+((chksum & 0300) >> 6)) & 077);/* Hdr checksum */
chksum += *bufp; /* Update checksum */
crc = calc_crc(*bufp++); /* Calculate CRC */
}
if ((type == 'N') && (sflg || rflg))
nak_sent++; /* Count nak */
p = data + offset;
q = p + len;
while (p < q) /* Loop for all data characters */
{
chksum += (unsigned char) *p; /* Update checksum */
crc = calc_crc(*p++); /* Calculate CRC */
}
chksum &= 0x0fff; /* Prevent overflow */
for (i = 0;i < pad; i++)
kwrite(ttyfd,&padchar,1); /* Issue any padding */
kwrite(ttyfd,buffer,bufp-buffer); /* Send start of packet */
if (len != 0)
kwrite(ttyfd, &data[offset], len); /* Send the data if any */
bufp = buffer; /* Reset pointer */
switch (check)
{
case 1: /* One character checksum */
chksum = (((chksum & 0300) >> 6) + chksum) & 077;
*bufp++ = (ck1 = tochar(chksum)); /* Put it in the packet */
break;
case 2: /* Two character checksum */
*bufp++ = (ck1 = tochar((chksum >> 6) & 077));
*bufp++ = (ck2 = tochar(chksum & 077));
break;
case 3: /* Three character CRC */
*bufp++ = (ck1 = tochar((crc >> 12) & 017));
*bufp++ = (ck2 = tochar((crc >> 6) & 077));
*bufp++ = (ck3 = tochar(crc & 077));
}
*bufp++ = eol; /* Extra-packet line terminator */
kwrite(ttyfd, buffer,bufp-buffer); /* Send the rest of the packet */
if (sflg || rflg)
dchr_sent += len; /* Adjust character counters */
if (debug)
{
if (debug >= 1)
if (screen)
posit(60,7);
else
fputs("Checksum: ",stdout);
prtdbgf("Checksum: ");
switch(check)
{
case 1:
prtdbg("%02x\n",unchar(ck1));
break;
case 2:
prtdbg("%02x%02x\n",unchar(ck1),unchar(ck2));
break;
case 3:
prtdbg("%02x%02x%02x\n",unchar(ck1),unchar(ck2),unchar(ck3));
}
if (!screen)
fputs("\l",stdout);
}
if (sflg)
disp_size_transferred(); /* Show how far we've got */
}
/*
* r p a c k
*
* Read a Packet
*/
rpack(len,num,data,check)
char *num, check, /* number, checksum type */
*data; /* Packet data */
int *len; /* Length */
{
int done,
s;
unsigned int cchksum, /* Checksums */
rchksum,
ck1, ck2, ck3,
crc; /* and CRC */
char t, /* Current input character */
type, /* Packet type */
type0, /* Type 0 packet type */
*p;
do /* Wait for packet header */
{
if (kread(ttyfd,&t,1) == TIMEOUT)
return ('T'); /* Return timeout */
t &= 0177; /* Handle parity */
}
while (t != mypackstart);
done = FALSE; /* Got packet start, init loop */
while (!done) /* Loop to get a packet */
{
if (setjmp(rp_env))
return('T'); /* Return if timeout */
zero_crc(); /* Start new CRC calculation */
cchksum = 0;
if (getpck(&t,&cchksum,&crc))
continue; /* Resynch if start of packet */
if (unchar(t) == 0)
type0 = TRUE; /* Type 0 extended header */
else if ((unchar(t) == 1) ||
(unchar(t) == 2))
return(FALSE); /* Invalid packet length */
else
{
type0 = FALSE;
*len = unchar(t)-check-2; /* Character count */
}
if (getpck(&t,&cchksum,&crc))
continue; /* Resynch if start of packet */
*num = unchar(t); /* Packet number */
if (getpck(&t,&cchksum,&crc))
continue; /* Resynch if start of packet */
type = t; /* Packet type */
if ((type == 'N') && (sflg || rflg))
nak_rec++; /* Count received nak */
if (type0)
{
if (getpck(&t,&cchksum,&crc))
continue; /* Resynch if start of packet */
*len = 95 * unchar(t); /* First part of length */
if (getpck(&t,&cchksum,&crc))
continue; /* Resynch if start of packet */
*len += unchar(t); /* Second part of length */
*len -= check; /* Correction */
s = cchksum;
if (getpck(&t,&cchksum,&crc))
continue; /* Resynch if start of packet */
if (t != tochar((s + ((s & 0300) >> 6)) & 077))
return(FALSE); /* Header checksum error */
}
p = data;
while (p < data + *len) /* The data itself, if any */
{ /* Loop for character count */
if (kread(ttyfd,&t,1) == TIMEOUT)/* Get character */
return ('T');
if (!binfil) /* Handle parity */
t &= 0177;
if (t == mypackstart) /* Resynch if start of packet */
continue;
cchksum += (unsigned char) t; /* Update checksum */
crc = calc_crc(t); /* Calculate CRC */
*p++ = t; /* Put it in the data buffer */
}
cchksum &= 0x0fff; /* Prevent overflow */
*p = '\0'; /* Mark the end of the data */
if (kread(ttyfd,&t,1) == TIMEOUT) /* Get character */
return ('T');
if (check == 1)
rchksum = (ck1 = unchar(t)); /* Convert to numeric */
else if (check == 2)
{
rchksum = (ck1 = unchar(t)) << 6;
if (kread(ttyfd,&t,1) == TIMEOUT)/* Get character */
return ('T');
rchksum += (ck2 = unchar(t));
}
else if (check == 3)
{
rchksum = (ck1 = unchar(t)) << 12;
if (kread(ttyfd,&t,1) == TIMEOUT)/* Get character */
return ('T');
rchksum += (ck2 = unchar(t)) << 6;
if (kread(ttyfd,&t,1) == TIMEOUT)/* Get character */
return ('T');
rchksum += (ck3 = unchar(t));
}
if (kread(ttyfd,&t,1) == TIMEOUT) /* get EOL character and toss it */
return ('T');
t &= 0177; /* Handle parity */
if (t == mypackstart) /* Resynch if start of packet */
continue;
done = TRUE; /* Got checksum, done */
}
if (sflg || rflg)
{
dchr_rec += *len; /* Count received data characters */
pack_rec++; /* Count packet */
}
if (check == 3)
cchksum = crc; /* Set calculated value */
else if (check == 2)
cchksum &= 07777; /* Strip result to 12 bits */
if (check == 1)
cchksum = (((cchksum & 0300) >> 6) + cchksum) & 077; /* Final checksum */
prtdbgf("Packet received: %d, Type: %c, Length: %d\n",*num,type,*len);
if (!remote && !nooutput)
{
if (screen)
{
posit(20,6);
printf("%2d",*num);
}
else
printf("Rcv: %d\r",*num);
}
if (debug) /* Display incoming packet */
{
if ((debug >= 1) && !remote)
{
if (screen)
{
posit(33,6);
printf("%c",type);
posit(45,6);
printf("%4d",*len);
posit(60,6);
}
else
printf("Type: %c Length: %d\n\l",type,*len);
}
prtdbgf("Checksum: ");
if (!screen)
fputs("Checksum: ",stdout);
switch(check)
{
case 1:
prtdbg("%02x\n",ck1);
break;
case 2:
prtdbg("%02x%02x\n",ck1,ck2);
break;
case 3:
prtdbg("%02x%02x%02x\n",ck1,ck2,ck3);
}
if (!screen)
fputs("\l",stdout);
if (screen)
{
clreol(20,9);
clreol(0,10);
}
if (*len != 0)
{
if ((debug >= 1) && !remote)
{
if (screen)
{
posit(20,9);
printf("\"%.58s\"",data);
if (*len > 58)
{
posit(20,10);
printf("\"%.58s\"",&data[58]);
}
}
else
printf("Data received: \"%.94s\"\n\l",data);
}
prtdbgf("Data received: \"%.94s\"\n",data);
}
}
if (rflg)
disp_size_transferred(); /* Show how far we've got */
if (cchksum != rchksum)
return(FALSE); /* Checksum error */
else
return(type); /* All OK, return packet type */
}
getpck(t,cks,crc)
char *t;
unsigned int *cks,*crc;
{
if (kread(ttyfd,t,1) == TIMEOUT) /* Get character */
longjmp(rp_env,TRUE);
*t &= 0177; /* Handle parity */
*cks &= 0x0fff; /* Prevent overflow */
*cks += *t; /* Update checksum */
*crc = calc_crc(*t); /* Calculate CRC */
if (*t == mypackstart)
return(TRUE); /* New start of packet received */
else
return(FALSE);
}