147438Sbostic /*-
2*62391Sbostic * Copyright (c) 1982, 1993
3*62391Sbostic * The Regents of the University of California. All rights reserved.
447438Sbostic *
547438Sbostic * This code is derived from software contributed to Berkeley by
647438Sbostic * Rick Adams.
747438Sbostic *
847438Sbostic * %sccs.include.redist.c%
947438Sbostic */
1047438Sbostic
1117827Sralph #ifndef lint
12*62391Sbostic static char sccsid[] = "@(#)tio.c 8.1 (Berkeley) 06/06/93";
1347438Sbostic #endif /* not lint */
1417827Sralph
1545947Sbostic #include <sys/param.h>
1645947Sbostic #include <sys/signal.h>
1745947Sbostic #include <sys/stat.h>
1818622Sralph #include "uucp.h"
1917827Sralph #include <setjmp.h>
2017827Sralph
2146879Sbostic extern void pkfail();
2217827Sralph #define TPACKSIZE 512
2317827Sralph #define TBUFSIZE 1024
2417827Sralph #define min(a,b) (((a)<(b))?(a):(b))
2517827Sralph
2617827Sralph /*
2717827Sralph * htonl is a function that converts a long from host
2817827Sralph * order to network order
2917827Sralph * ntohl is a function that converts a long from network
3017827Sralph * order to host order
3117827Sralph *
3217827Sralph * network order is 0 1 2 3 (bytes in a long)
3317827Sralph * host order on a vax is 3 2 1 0
3417827Sralph * host order on a pdp11 is 1 0 3 2
3517827Sralph * host order on a 68000 is 0 1 2 3
3617827Sralph * most other machines are 0 1 2 3
3717827Sralph */
3817827Sralph
3917827Sralph struct tbuf {
4017827Sralph long t_nbytes;
4117827Sralph char t_data[TBUFSIZE];
4217827Sralph };
4317827Sralph
4423676Sbloom extern jmp_buf Failbuf;
4517827Sralph
4633572Srick extern long Bytes_Sent, Bytes_Received;
4733572Srick
twrmsg(type,str,fn)4817827Sralph twrmsg(type, str, fn)
4917827Sralph char type;
5017827Sralph register char *str;
5117827Sralph {
5217827Sralph char bufr[TBUFSIZE];
5317827Sralph register char *s;
5417827Sralph int len, i;
5517827Sralph
5617827Sralph if(setjmp(Failbuf))
5717827Sralph return FAIL;
5817827Sralph signal(SIGALRM, pkfail);
5933572Srick alarm(MAXMSGTIME*5);
6017827Sralph bufr[0] = type;
6117827Sralph s = &bufr[1];
6217827Sralph while (*str)
6317827Sralph *s++ = *str++;
6417827Sralph *s = '\0';
6517827Sralph if (*(--s) == '\n')
6617827Sralph *s = '\0';
6717827Sralph len = strlen(bufr) + 1;
6817827Sralph if ((i = len % TPACKSIZE)) {
6917827Sralph len = len + TPACKSIZE - i;
7017827Sralph bufr[len - 1] = '\0';
7117827Sralph }
7217827Sralph twrblk(bufr, len, fn);
7317827Sralph alarm(0);
7417827Sralph return SUCCESS;
7517827Sralph }
7617827Sralph
trdmsg(str,fn)7717827Sralph trdmsg(str, fn)
7817827Sralph register char *str;
7917827Sralph {
8017827Sralph int len, cnt = 0;
8117827Sralph
8217827Sralph if(setjmp(Failbuf))
8317827Sralph return FAIL;
8417827Sralph signal(SIGALRM, pkfail);
8533572Srick alarm(MAXMSGTIME*5);
8617827Sralph for (;;) {
8717827Sralph len = read(fn, str, TPACKSIZE);
8833970Srick if (len <= 0) {
8917827Sralph alarm(0);
9017827Sralph return FAIL;
9117827Sralph }
9217827Sralph str += len;
9317827Sralph cnt += len;
9417827Sralph if (*(str - 1) == '\0' && (cnt % TPACKSIZE) == 0)
9517827Sralph break;
9617827Sralph }
9717827Sralph alarm(0);
9817827Sralph return SUCCESS;
9917827Sralph }
10017827Sralph
twrdata(fp1,fn)10117827Sralph twrdata(fp1, fn)
10217827Sralph FILE *fp1;
10317827Sralph {
10417827Sralph struct tbuf bufr;
10517827Sralph register int len;
10617827Sralph int ret, mil;
10717827Sralph struct timeb t1, t2;
10817827Sralph long bytes;
10917827Sralph char text[TBUFSIZE];
11033572Srick float ft;
11117827Sralph
11217827Sralph if(setjmp(Failbuf))
11317827Sralph return FAIL;
11417827Sralph signal(SIGALRM, pkfail);
11517827Sralph bytes = 0L;
11618622Sralph #ifdef USG
11718622Sralph time(&t1.time);
11818622Sralph t1.millitm = 0;
11918622Sralph #else !USG
12017827Sralph ftime(&t1);
12118622Sralph #endif !USG
12217827Sralph while ((len = read(fileno(fp1), bufr.t_data, TBUFSIZE)) > 0) {
12317827Sralph bytes += len;
12425967Sbloom #if defined(vax) || defined(pdp11) || defined(ns32000)
12517827Sralph bufr.t_nbytes = htonl((long)len);
12625967Sbloom #else !vax and !pdp11 and !ns32000
12717827Sralph bufr.t_nbytes = len;
12825967Sbloom #endif !vax and !pdp11 and !ns32000
12917827Sralph DEBUG(8,"twrdata sending %d bytes\n",len);
13017827Sralph len += sizeof(long);
13133572Srick alarm(MAXMSGTIME*5);
13223676Sbloom ret = twrblk((char *)&bufr, len, fn);
13317827Sralph alarm(0);
13417827Sralph if (ret != len)
13517827Sralph return FAIL;
13617827Sralph if (len != TBUFSIZE+sizeof(long))
13717827Sralph break;
13817827Sralph }
13917827Sralph bufr.t_nbytes = 0;
14017827Sralph len = sizeof(long);
14133572Srick alarm(MAXMSGTIME*5);
14223676Sbloom ret = twrblk((char *)&bufr, len, fn);
14317827Sralph alarm(0);
14417827Sralph if (ret != len)
14517827Sralph return FAIL;
14618622Sralph #ifdef USG
14718622Sralph time(&t2.time);
14818622Sralph t2.millitm = 0;
14918622Sralph #else !USG
15017827Sralph ftime(&t2);
15118622Sralph #endif !USG
15218622Sralph Now = t2;
15317827Sralph t2.time -= t1.time;
15417827Sralph mil = t2.millitm - t1.millitm;
15517827Sralph if (mil < 0) {
15617827Sralph --t2.time;
15717827Sralph mil += 1000;
15817827Sralph }
15933572Srick ft = (float)t2.time + (float)mil/1000.;
16033572Srick sprintf(text, "sent data %ld bytes %.2f secs %ld bps",
16133572Srick bytes, ft, (long)((float)bytes*8./ft));
16225150Sbloom sysacct(bytes, t2.time);
16333572Srick Bytes_Sent += bytes;
16417827Sralph DEBUG(1, "%s\n", text);
16533970Srick log_xferstats(text);
16617827Sralph return SUCCESS;
16717827Sralph }
16817827Sralph
trddata(fn,fp2)16917827Sralph trddata(fn, fp2)
17017827Sralph FILE *fp2;
17117827Sralph {
17217827Sralph register int len, nread;
17317827Sralph char bufr[TBUFSIZE];
17417827Sralph struct timeb t1, t2;
17517827Sralph int mil;
17617827Sralph long bytes, Nbytes;
17733572Srick float ft;
17817827Sralph
17917827Sralph if(setjmp(Failbuf))
18017827Sralph return FAIL;
18117827Sralph signal(SIGALRM, pkfail);
18218622Sralph #ifdef USG
18318622Sralph time(&t1.time);
18418622Sralph t1.millitm = 0;
18518622Sralph #else !USG
18617827Sralph ftime(&t1);
18718622Sralph #endif !USG
18817827Sralph bytes = 0L;
18917827Sralph for (;;) {
19033572Srick alarm(MAXMSGTIME*5);
19123676Sbloom len = trdblk((char *)&Nbytes,sizeof Nbytes,fn);
19217827Sralph alarm(0);
19317827Sralph if (len != sizeof Nbytes)
19417827Sralph return FAIL;
19525967Sbloom #if defined(vax) || defined(pdp11) || defined(ns32000)
19617827Sralph Nbytes = ntohl(Nbytes);
19725967Sbloom #endif vax or pdp11 or ns32000
19817827Sralph DEBUG(8,"trddata expecting %ld bytes\n",Nbytes);
19917827Sralph nread = Nbytes;
20017827Sralph if (nread == 0)
20117827Sralph break;
20233572Srick alarm(MAXMSGTIME*5);
20317827Sralph len = trdblk(bufr, nread, fn);
20417827Sralph alarm(0);
20517827Sralph if (len < 0) {
20617827Sralph return FAIL;
20717827Sralph }
20817827Sralph bytes += len;
20917827Sralph DEBUG(11,"trddata got %ld\n",bytes);
21017827Sralph if (write(fileno(fp2), bufr, len) != len) {
21117827Sralph alarm(0);
21217827Sralph return FAIL;
21317827Sralph }
21417827Sralph }
21518622Sralph #ifdef USG
21618622Sralph time(&t2.time);
21718622Sralph t2.millitm = 0;
21818622Sralph #else !USG
21917827Sralph ftime(&t2);
22018622Sralph #endif !USG
22118622Sralph Now = t2;
22217827Sralph t2.time -= t1.time;
22317827Sralph mil = t2.millitm - t1.millitm;
22417827Sralph if (mil < 0) {
22517827Sralph --t2.time;
22617827Sralph mil += 1000;
22717827Sralph }
22833572Srick ft = (float)t2.time + (float)mil/1000.;
22933572Srick sprintf(bufr, "received data %ld bytes %.2f secs %ld bps",
23033572Srick bytes, ft, (long)((float)bytes*8./ft));
23133572Srick sysacct(bytes, t2.time);
23233572Srick Bytes_Received += bytes;
23317827Sralph DEBUG(1, "%s\n", bufr);
23433970Srick log_xferstats(bufr);
23517827Sralph return SUCCESS;
23617827Sralph }
23717827Sralph
23825137Sbloom #if !defined(BSD4_2) && !defined(USG)
23917827Sralph #define TC 1024
24017827Sralph static int tc = TC;
24125137Sbloom #endif !BSD4_2 && !USG
24217827Sralph
trdblk(blk,len,fn)24317827Sralph trdblk(blk, len, fn)
24417827Sralph register int len;
24517827Sralph char *blk;
24617827Sralph {
24717827Sralph register int i, ret;
24817827Sralph
24925137Sbloom #if !defined(BSD4_2) && !defined(USG)
25017827Sralph /* call ultouch occasionally */
25117827Sralph if (--tc < 0) {
25217827Sralph tc = TC;
25317827Sralph ultouch();
25417827Sralph }
25525137Sbloom #endif !BSD4_2 && !USG
25617827Sralph for (i = 0; i < len; i += ret) {
25717827Sralph ret = read(fn, blk, len - i);
25817827Sralph if (ret < 0)
25917827Sralph return FAIL;
26017827Sralph blk += ret;
26117827Sralph if (ret == 0)
26217827Sralph return i;
26317827Sralph }
26417827Sralph return i;
26517827Sralph }
26617827Sralph
26717827Sralph
twrblk(blk,len,fn)26817827Sralph twrblk(blk, len, fn)
26917827Sralph register char *blk;
27017827Sralph {
27125137Sbloom #if !defined(BSD4_2) && !defined(USG)
27217827Sralph /* call ultouch occasionally */
27317827Sralph if (--tc < 0) {
27417827Sralph tc = TC;
27517827Sralph ultouch();
27617827Sralph }
27725137Sbloom #endif !BSD4_2 && !USG
27825137Sbloom return write(fn, blk, len);
27917827Sralph }
280