xref: /original-bsd/usr.bin/uucp/uucico/tio.c (revision a1c2194a)
1 /*-
2  * Copyright (c) 1982 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Rick Adams.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 static char sccsid[] = "@(#)tio.c	4.12 (Berkeley) 03/15/91";
13 #endif /* not lint */
14 
15 #include <sys/param.h>
16 #include <sys/signal.h>
17 #include <sys/stat.h>
18 #include "uucp.h"
19 #include <setjmp.h>
20 
21 extern void pkfail();
22 #define TPACKSIZE	512
23 #define TBUFSIZE	1024
24 #define min(a,b)	(((a)<(b))?(a):(b))
25 
26 /*
27  *	htonl is a function that converts a long from host
28  *		order to network order
29  *	ntohl is a function that converts a long from network
30  *		order to host order
31  *
32  *	network order is 		0 1 2 3 (bytes in a long)
33  *	host order on a vax is		3 2 1 0
34  *	host order on a pdp11 is	1 0 3 2
35  *	host order on a 68000 is	0 1 2 3
36  *	most other machines are		0 1 2 3
37  */
38 
39 struct tbuf {
40 	long t_nbytes;
41 	char t_data[TBUFSIZE];
42 };
43 
44 extern jmp_buf Failbuf;
45 
46 extern long Bytes_Sent, Bytes_Received;
47 
48 twrmsg(type, str, fn)
49 char type;
50 register char *str;
51 {
52 	char bufr[TBUFSIZE];
53 	register char *s;
54 	int len, i;
55 
56 	if(setjmp(Failbuf))
57 		return FAIL;
58 	signal(SIGALRM, pkfail);
59 	alarm(MAXMSGTIME*5);
60 	bufr[0] = type;
61 	s = &bufr[1];
62 	while (*str)
63 		*s++ = *str++;
64 	*s = '\0';
65 	if (*(--s) == '\n')
66 		*s = '\0';
67 	len = strlen(bufr) + 1;
68 	if ((i = len % TPACKSIZE)) {
69 		len = len + TPACKSIZE - i;
70 		bufr[len - 1] = '\0';
71 	}
72 	twrblk(bufr, len, fn);
73 	alarm(0);
74 	return SUCCESS;
75 }
76 
77 trdmsg(str, fn)
78 register char *str;
79 {
80 	int len, cnt = 0;
81 
82 	if(setjmp(Failbuf))
83 		return FAIL;
84 	signal(SIGALRM, pkfail);
85 	alarm(MAXMSGTIME*5);
86 	for (;;) {
87 		len = read(fn, str, TPACKSIZE);
88 		if (len <= 0) {
89 			alarm(0);
90 			return FAIL;
91 		}
92 		str += len;
93 		cnt += len;
94 		if (*(str - 1) == '\0' && (cnt % TPACKSIZE) == 0)
95 			break;
96 	}
97 	alarm(0);
98 	return SUCCESS;
99 }
100 
101 twrdata(fp1, fn)
102 FILE *fp1;
103 {
104 	struct tbuf bufr;
105 	register int len;
106 	int ret, mil;
107 	struct timeb t1, t2;
108 	long bytes;
109 	char text[TBUFSIZE];
110 	float ft;
111 
112 	if(setjmp(Failbuf))
113 		return FAIL;
114 	signal(SIGALRM, pkfail);
115 	bytes = 0L;
116 #ifdef USG
117 	time(&t1.time);
118 	t1.millitm = 0;
119 #else !USG
120 	ftime(&t1);
121 #endif !USG
122 	while ((len = read(fileno(fp1), bufr.t_data, TBUFSIZE)) > 0) {
123 		bytes += len;
124 #if defined(vax) || defined(pdp11) || defined(ns32000)
125 		bufr.t_nbytes = htonl((long)len);
126 #else !vax and !pdp11 and !ns32000
127 		bufr.t_nbytes = len;
128 #endif !vax and !pdp11 and !ns32000
129 		DEBUG(8,"twrdata sending %d bytes\n",len);
130 		len += sizeof(long);
131 		alarm(MAXMSGTIME*5);
132 		ret = twrblk((char *)&bufr, len, fn);
133 		alarm(0);
134 		if (ret != len)
135 			return FAIL;
136 		if (len != TBUFSIZE+sizeof(long))
137 			break;
138 	}
139 	bufr.t_nbytes = 0;
140 	len = sizeof(long);
141 	alarm(MAXMSGTIME*5);
142 	ret = twrblk((char *)&bufr, len, fn);
143 	alarm(0);
144 	if (ret != len)
145 		return FAIL;
146 #ifdef USG
147 	time(&t2.time);
148 	t2.millitm = 0;
149 #else !USG
150 	ftime(&t2);
151 #endif !USG
152 	Now = t2;
153 	t2.time -= t1.time;
154 	mil = t2.millitm - t1.millitm;
155 	if (mil < 0) {
156 		--t2.time;
157 		mil += 1000;
158 	}
159 	ft = (float)t2.time + (float)mil/1000.;
160 	sprintf(text, "sent data %ld bytes %.2f secs %ld bps",
161 		bytes, ft, (long)((float)bytes*8./ft));
162 	sysacct(bytes, t2.time);
163 	Bytes_Sent += bytes;
164 	DEBUG(1, "%s\n", text);
165 	log_xferstats(text);
166 	return SUCCESS;
167 }
168 
169 trddata(fn, fp2)
170 FILE *fp2;
171 {
172 	register int len, nread;
173 	char bufr[TBUFSIZE];
174 	struct timeb t1, t2;
175 	int mil;
176 	long bytes, Nbytes;
177 	float ft;
178 
179 	if(setjmp(Failbuf))
180 		return FAIL;
181 	signal(SIGALRM, pkfail);
182 #ifdef USG
183 	time(&t1.time);
184 	t1.millitm = 0;
185 #else !USG
186 	ftime(&t1);
187 #endif !USG
188 	bytes = 0L;
189 	for (;;) {
190 		alarm(MAXMSGTIME*5);
191 		len = trdblk((char *)&Nbytes,sizeof Nbytes,fn);
192 		alarm(0);
193 		if (len != sizeof Nbytes)
194 			return FAIL;
195 #if defined(vax) || defined(pdp11) || defined(ns32000)
196 		Nbytes = ntohl(Nbytes);
197 #endif vax or pdp11 or ns32000
198 		DEBUG(8,"trddata expecting %ld bytes\n",Nbytes);
199 		nread = Nbytes;
200 		if (nread == 0)
201 			break;
202 		alarm(MAXMSGTIME*5);
203 		len = trdblk(bufr, nread, fn);
204 		alarm(0);
205 		if (len < 0) {
206 			return FAIL;
207 		}
208 		bytes += len;
209 		DEBUG(11,"trddata got %ld\n",bytes);
210 		if (write(fileno(fp2), bufr, len) != len) {
211 			alarm(0);
212 			return FAIL;
213 		}
214 	}
215 #ifdef USG
216 	time(&t2.time);
217 	t2.millitm = 0;
218 #else !USG
219 	ftime(&t2);
220 #endif !USG
221 	Now = t2;
222 	t2.time -= t1.time;
223 	mil = t2.millitm - t1.millitm;
224 	if (mil < 0) {
225 		--t2.time;
226 		mil += 1000;
227 	}
228 	ft = (float)t2.time + (float)mil/1000.;
229 	sprintf(bufr, "received data %ld bytes %.2f secs %ld bps",
230 		bytes, ft, (long)((float)bytes*8./ft));
231 	sysacct(bytes, t2.time);
232 	Bytes_Received += bytes;
233 	DEBUG(1, "%s\n", bufr);
234 	log_xferstats(bufr);
235 	return SUCCESS;
236 }
237 
238 #if !defined(BSD4_2) && !defined(USG)
239 #define	TC	1024
240 static	int tc = TC;
241 #endif !BSD4_2 && !USG
242 
243 trdblk(blk, len,  fn)
244 register int len;
245 char *blk;
246 {
247 	register int i, ret;
248 
249 #if !defined(BSD4_2) && !defined(USG)
250 	/* call ultouch occasionally */
251 	if (--tc < 0) {
252 		tc = TC;
253 		ultouch();
254 	}
255 #endif !BSD4_2 && !USG
256 	for (i = 0; i < len; i += ret) {
257 		ret = read(fn, blk, len - i);
258 		if (ret < 0)
259 			return FAIL;
260 		blk += ret;
261 		if (ret == 0)
262 			return i;
263 	}
264 	return i;
265 }
266 
267 
268 twrblk(blk, len, fn)
269 register char *blk;
270 {
271 #if !defined(BSD4_2) && !defined(USG)
272 	/* call ultouch occasionally */
273 	if (--tc < 0) {
274 		tc = TC;
275 		ultouch();
276 	}
277 #endif !BSD4_2 && !USG
278 	return write(fn, blk, len);
279 }
280