|
|
researchv10 Norman
/* /sccs/src/cmd/uucp/s.eio.c
eio.c 1.4 8/30/84 17:37:17
*/
#include "uucp.h"
VERSION(@(#)eio.c 1.4);
#ifdef ATTSV
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
#define XBUFSIZ 4096
#define CMLEN 20
static jmp_buf Failbuf;
/*
* error-free channel protocol
*/
static
ealarm() {
DEBUG(4, "read timeout\n", "");
longjmp(Failbuf, 1);
}
static int (*esig)();
/*
* turn on protocol timer
*/
eturnon()
{
esig=signal(SIGALRM, ealarm);
return(0);
}
eturnoff()
{
signal(SIGALRM, esig);
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
*/
ewrmsg(type, str, fn)
register char *str;
int fn;
char type;
{
register char *s;
char bufr[BUFSIZ];
int s1, s2;
bufr[0] = type;
s = &bufr[1];
while (*str)
*s++ = *str++;
*s = '\0';
if (*(--s) == '\n')
*s = '\0';
s1 = strlen(bufr) + 1;
if (setjmp(Failbuf)) {
DEBUG(7, "ewrmsg write failed\n", "");
return(FAIL);
}
alarm(120);
s2 = write(fn, bufr, (unsigned) s1);
alarm(0);
if (s1 != s2)
return(FAIL);
return(0);
}
/*
* read message from link
* str -> message buffer
* fn -> file descriptor
* return
* FAIL -> read timed out
* 0 -> ok message in str
*/
erdmsg(str, fn)
register char *str;
{
register int i;
register unsigned len;
if(setjmp(Failbuf)) {
DEBUG(7, "erdmsg read failed\n", "");
return(FAIL);
}
i = BUFSIZ;
for (;;) {
alarm(120);
if ((len = read(fn, str, i)) == 0)
continue; /* Perhaps should be FAIL, but the */
/* timeout will get it (skip alarm(0) */
alarm(0);
if (len < 0) {
DEBUG(4, "read fail errno %d", errno);
return(FAIL);
}
str += len; i -= len;
if (*(str - 1) == '\0')
break;
}
return(0);
}
/*
* read data from file fp1 and write
* on link
* fp1 -> file descriptor
* fn -> link descriptor
* returns:
* FAIL ->failure in link
* 0 -> ok
*/
ewrdata(fp1, fn)
int fn;
register FILE *fp1;
{
register int ret;
int len;
long bytes;
char bufr[XBUFSIZ];
char text[BUFSIZ];
time_t ticks;
int mil;
struct stat statbuf;
off_t msglen;
char cmsglen[CMLEN];
int fd;
if (setjmp(Failbuf)) {
DEBUG(7, "ewrdata failed\n", "");
return(FAIL);
}
bytes = 0L;
fd = fileno(fp1);
fstat(fd, &statbuf);
bytes = msglen = statbuf.st_size;
(void) millitick();
sprintf(cmsglen, "%ld", (long) msglen);
alarm(120);
ret = write(fn, cmsglen, sizeof(cmsglen));
DEBUG(7, "ewrmsg write %d\n", statbuf.st_size);
while ((len = read(fd, bufr, XBUFSIZ)) > 0) {
alarm(120);
ret = write(fn, bufr, (unsigned) len);
alarm(0);
DEBUG(7, "ewrmsg ret %d\n", ret);
if (ret != len)
return(FAIL);
if ((msglen -= len) <= 0)
break;
}
if (len < 0 || (len == 0 && msglen != 0)) return(FAIL);
ticks = millitick();
sprintf(text, "-> %ld / %ld.%.3d secs", bytes, ticks / 1000, ticks % 1000);
DEBUG(4, "%s\n", text);
syslog(text);
return(0);
}
/*
* read data from link and
* write into file
* fp2 -> file descriptor
* fn -> link descriptor
* returns:
* 0 -> ok
* FAIL -> failure on link
*/
erddata(fn, fp2)
register FILE *fp2;
{
register int len;
long bytes;
char text[BUFSIZ];
char bufr[XBUFSIZ];
time_t ticks;
int mil;
long msglen;
char cmsglen[CMLEN];
int fd;
bytes = 0L;
fd = fileno(fp2);
(void) millitick();
len = erdblk(cmsglen, sizeof(cmsglen), fn);
if (len < 0) return(FAIL);
sscanf(cmsglen, "%ld", &msglen);
bytes = msglen;
DEBUG(7, "erdblk msglen %d\n", msglen);
for (;;) {
len = erdblk(bufr, MIN(msglen, XBUFSIZ), fn);
DEBUG(7, "erdblk ret %d\n", len);
if (len < 0) {
DEBUG(7, "erdblk failed\n", "");
return(FAIL);
}
if ((msglen -= len) < 0) {
DEBUG(7, "erdblk read too much\n", "");
return(FAIL);
}
if (write(fd, bufr, len) != len) {
DEBUG(7, "fs write failed %d", errno);
return (FAIL);
}
if (msglen == 0)
break;
}
ticks = millitick();
sprintf(text, "<- %ld / %ld.%.3d secs", bytes, ticks / 1000, ticks % 1000);
DEBUG(4, "%s\n", text);
syslog(text);
return(0);
}
/*
* 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
*/
erdblk(blk, len, fn)
register char *blk;
{
register int i, ret;
if(setjmp(Failbuf)) {
DEBUG(7, "erdblk timeout\n", "");
return(FAIL);
}
for (i = 0; i < len; i += ret) {
alarm(120);
DEBUG(7, "ask %d ", len - i);
if ((ret = read(fn, blk, (unsigned) len - i)) < 0) {
alarm(0);
DEBUG(7, "read failed\n", "");
return(FAIL);
}
DEBUG(7, "got %d\n", ret);
blk += ret;
if (ret == 0)
break;
}
alarm(0);
return(i);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.