1 /*-
2 * Copyright (c) 1982, 1993
3 * The Regents of the University of California. 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 8.1 (Berkeley) 06/06/93";
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
twrmsg(type,str,fn)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
trdmsg(str,fn)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
twrdata(fp1,fn)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
trddata(fn,fp2)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
trdblk(blk,len,fn)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
twrblk(blk,len,fn)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