1
0
Files
2022-09-29 17:59:04 +03:00

289 lines
4.9 KiB
C

/*
* Common 't' for "TCP" protocol
*/
#ident "$Revision: 1.4 $"
#include "uucp.h"
#include <netinet/in.h>
int twrmsg(char, char*, int);
int trdmsg(char*, int);
int twrdata(FILE *, int fn);
int trddata(int, FILE*);
static int trdblk(char*, int, int);
#define MAXTCPTIME 300 /* TCP can sometimes be slooow */
static jmp_buf Failbuf;
#define TPACKSIZE 512
#define TBUFSIZE 1024
struct tbuf {
long t_nbytes;
char t_data[TBUFSIZE];
};
static void
talarm() {
longjmp(Failbuf, 1);
}
static void (*tsig)();
/*
* turn on protocol timer
*/
tturnon(void)
{
tsig=signal(SIGALRM, talarm);
return(0);
}
tturnoff(void)
{
signal(SIGALRM, tsig);
return(0);
}
/*
* write message across link
* type -> message type
* str -> message body (ascii string)
* fn -> link file descriptor
* return
* FAIL -> write failed
* 0 -> write succeeded
*/
int
twrmsg(char type,
char *str,
int fn)
{
char bufr[TBUFSIZE+1];
int s1, i, s2;
bufr[0] = type;
strncpy(&bufr[1], str, TBUFSIZE);
bufr[TBUFSIZE] = '\0';
s1 = strlen(bufr) + 1;
if (s1 > TBUFSIZE) {
DEBUG0(7, "twrmsg babble\n");
return(FAIL);
}
if (bufr[s1-2] == '\n') {
bufr[s1-2] = '\0';
s1--;
}
if ((i = s1 % TPACKSIZE)) {
s1 += TPACKSIZE - i;
bufr[s1 - 1] = '\0';
}
if (setjmp(Failbuf)) {
DEBUG0(7, "twrmsg write failed\n");
return(FAIL);
}
alarm(MAXTCPTIME);
s2 = (*Write)(fn, bufr, (unsigned) s1);
alarm(0);
if (s1 != s2)
return(FAIL);
return(SUCCESS);
}
/*
* read message from link
* str -> message buffer
* fn -> file descriptor
* return
* FAIL -> read timed out
* 0 -> ok message in str
*/
int
trdmsg(char *str,
int fn)
{
register int i;
register int len;
if (setjmp(Failbuf)) {
DEBUG0(7, "trdmsg read failed\n");
return(FAIL);
}
i = 0;
alarm(MAXTCPTIME);
do {
if (i >= TBUFSIZE-1) {
DEBUG0(7, "trdmsg read babble\n");
alarm(0);
return(FAIL);
}
len = (*Read)(fn, str, TPACKSIZE);
if (len <= 0) {
DEBUG0(7, "trdmsg read failed\n");
alarm(0);
return(FAIL);
}
str += len;
i += len;
} while (*(str - 1) != '\0' || (i % TPACKSIZE) != 0);
alarm(0);
return(SUCCESS);
}
/*
* read data from file fp1 and write on link
* fp1 -> file descriptor
* fn -> link descriptor
* returns:
* FAIL ->failure in link
* 0 -> ok
*/
int
twrdata(FILE *fp1,
int fn)
{
int ret;
int len;
int fd1;
long bytes;
struct tbuf bufr;
if (setjmp(Failbuf)) {
DEBUG0(7, "twrdata failed\n");
return(FAIL);
}
bytes = 0L;
fd1 = fileno(fp1);
(void)millitick();
alarm(MAXTCPTIME);
do {
len = read(fd1, bufr.t_data, TBUFSIZE);
if (len < 0) {
DEBUG(7, "twrdata read errno=%d\n", errno);
return(FAIL);
}
if (len == 0)
break;
bytes += len;
bufr.t_nbytes = htonl(len);
DEBUG(7,"twrdata sending %d bytes\n",len);
len += sizeof(long);
alarm(MAXTCPTIME);
ret = (*Write)(fn, (char*)&bufr, len);
alarm(0);
if (ret != len) {
DEBUG(7, "twrdata ret %d\n", ret);
return(FAIL);
}
} while (len == TBUFSIZE+sizeof(long));
if (len < 0)
return(FAIL);
bufr.t_nbytes = 0;
alarm(MAXTCPTIME);
ret = (*Write)(fn, (char*)&bufr, sizeof(long));
alarm(0);
if (sizeof(long) != ret)
return(FAIL);
statlog("->", bytes, millitick());
return(SUCCESS);
}
/*
* read data from link and
* write into file
* fp2 -> file descriptor
* fn -> link descriptor
* returns:
* 0 -> ok
* FAIL -> failure on link
*/
int
trddata(int fn,
FILE *fp2)
{
int len;
int fd2;
long bytes;
long nread;
char bufr[TBUFSIZE];
int writefile = TRUE, ret = SUCCESS;
bytes = 0L;
(void) millitick();
fd2 = fileno(fp2);
for (;;) {
len = trdblk((char *)&nread,sizeof(nread),fn);
if (len != sizeof(nread) ) {
DEBUG0(7, "trdblk of block length failed\n");
return(FAIL);
}
nread = ntohl(nread);
if (nread == 0)
break;
if (nread > TBUFSIZE) {
DEBUG(7,"trddata block %ld bytes too big\n",nread);
return(FAIL);
}
DEBUG(7,"trddata expecting %ld bytes\n",nread);
len = trdblk(bufr, nread, fn);
if (len != nread)
return(FAIL);
if (writefile == TRUE && write(fd2, bufr, len) != len ) {
ret = errno;
DEBUG(7, "erddata: write to file failed, errno %d\n",
ret);
writefile = FALSE;
}
bytes += len;
}
if (writefile != TRUE)
return(ret);
statlog( "<-", bytes, millitick());
return(SUCCESS);
}
/*
* read block from link
* reads are timed
* blk -> address of buffer
* len -> size to read
* fn -> link descriptor
* returns:
* FAIL -> link error timeout on link
* i -> # of bytes read
*/
static int
trdblk(char *blk,
int len,
int fn)
{
int i, ret;
if(setjmp(Failbuf)) {
DEBUG0(7, "trdblk timeout\n");
return(FAIL);
}
for (i = 0; i < len; i += ret) {
alarm(MAXTCPTIME);
DEBUG(7, "ask %d ", len - i);
ret = (*Read)(fn, blk, (unsigned) len - i);
if (ret <= 0) {
alarm(0);
DEBUG0(7, "read failed\n");
return(FAIL);
}
DEBUG(7, "got %d\n", ret);
if (ret == 0)
break;
blk += ret;
}
alarm(0);
return(i);
}