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