|
|
1.1 root 1: /* /sccs/src/cmd/uucp/s.eio.c
2: eio.c 1.4 8/30/84 17:37:17
3: */
4:
5: #include "uucp.h"
6: VERSION(@(#)eio.c 1.4);
7:
8: #ifdef ATTSV
9: #define MIN(a,b) (((a)<(b))?(a):(b))
10: #endif
11:
12: static jmp_buf Failbuf;
13:
14: /*
15: * error-free channel protocol
16: */
17: static
18: ealarm() {
19: longjmp(Failbuf, 1);
20: }
21: static int (*esig)();
22:
23: /*
24: * turn on protocol timer
25: */
26: eturnon()
27: {
28: esig=signal(SIGALRM, ealarm);
29: return(0);
30: }
31:
32: eturnoff()
33: {
34: signal(SIGALRM, esig);
35: return(0);
36: }
37:
38: /*
39: * write message across link
40: * type -> message type
41: * str -> message body (ascii string)
42: * fn -> link file descriptor
43: * return
44: * FAIL -> write failed
45: * 0 -> write succeeded
46: */
47: ewrmsg(type, str, fn)
48: register char *str;
49: int fn;
50: char type;
51: {
52: register char *s;
53: char bufr[BUFSIZ];
54: int s1, s2;
55:
56: bufr[0] = type;
57: s = &bufr[1];
58: while (*str)
59: *s++ = *str++;
60: *s = '\0';
61: if (*(--s) == '\n')
62: *s = '\0';
63: s1 = strlen(bufr) + 1;
64: if (setjmp(Failbuf)) {
65: DEBUG(7, "ewrmsg write failed\n", "");
66: return(FAIL);
67: }
68: alarm(60);
69: s2 = write(fn, bufr, (unsigned) s1);
70: alarm(0);
71: if (s1 != s2)
72: return(FAIL);
73: return(0);
74: }
75:
76: /*
77: * read message from link
78: * str -> message buffer
79: * fn -> file descriptor
80: * return
81: * FAIL -> read timed out
82: * 0 -> ok message in str
83: */
84: erdmsg(str, fn)
85: register char *str;
86: {
87: register int i;
88: register unsigned len;
89:
90: if(setjmp(Failbuf)) {
91: DEBUG(7, "erdmsg read failed\n", "");
92: return(FAIL);
93: }
94:
95: i = BUFSIZ;
96: for (;;) {
97: alarm(60);
98: if ((len = read(fn, str, i)) == 0)
99: continue; /* Perhaps should be FAIL, but the */
100: /* timeout will get it (skip alarm(0) */
101: alarm(0);
102: if (len < 0) return(FAIL);
103: str += len; i -= len;
104: if (*(str - 1) == '\0')
105: break;
106: }
107: return(0);
108: }
109:
110: /*
111: * read data from file fp1 and write
112: * on link
113: * fp1 -> file descriptor
114: * fn -> link descriptor
115: * returns:
116: * FAIL ->failure in link
117: * 0 -> ok
118: */
119: ewrdata(fp1, fn)
120: int fn;
121: register FILE *fp1;
122: {
123: register int ret;
124: int len;
125: long bytes;
126: char bufr[BUFSIZ];
127: char text[BUFSIZ];
128: time_t ticks;
129: int mil;
130: struct stat statbuf;
131: off_t msglen;
132: char cmsglen[20];
133:
134: if (setjmp(Failbuf)) {
135: DEBUG(7, "ewrdata failed\n", "");
136: return(FAIL);
137: }
138: bytes = 0L;
139: fstat(fileno(fp1), &statbuf);
140: bytes = msglen = statbuf.st_size;
141: (void) millitick();
142: sprintf(cmsglen, "%ld", (long) msglen);
143: alarm(60);
144: ret = write(fn, cmsglen, sizeof(cmsglen));
145: DEBUG(7, "ewrmsg write %d\n", statbuf.st_size);
146: while ((len = fread(bufr, sizeof (char), BUFSIZ, fp1)) > 0) {
147: alarm(60);
148: ret = write(fn, bufr, (unsigned) len);
149: alarm(0);
150: DEBUG(7, "ewrmsg ret %d\n", ret);
151: if (ret != len)
152: return(FAIL);
153: if ((msglen -= len) <= 0)
154: break;
155: }
156: if (len < 0 || (len == 0 && msglen != 0)) return(FAIL);
157: ticks = millitick();
158: sprintf(text, "-> %ld / %ld.%.3d secs", bytes, ticks / 1000, ticks % 1000);
159: DEBUG(4, "%s\n", text);
160: syslog(text);
161: return(0);
162: }
163:
164: /*
165: * read data from link and
166: * write into file
167: * fp2 -> file descriptor
168: * fn -> link descriptor
169: * returns:
170: * 0 -> ok
171: * FAIL -> failure on link
172: */
173: erddata(fn, fp2)
174: register FILE *fp2;
175: {
176: register int len;
177: long bytes;
178: char text[BUFSIZ];
179: char bufr[BUFSIZ];
180: time_t ticks;
181: int mil;
182: long msglen;
183: char cmsglen[20];
184:
185: bytes = 0L;
186: (void) millitick();
187: len = erdblk(cmsglen, sizeof(cmsglen), fn);
188: if (len < 0) return(FAIL);
189: sscanf(cmsglen, "%ld", &msglen);
190: bytes = msglen;
191: DEBUG(7, "erdblk msglen %d\n", msglen);
192: for (;;) {
193: len = erdblk(bufr, MIN(msglen, BUFSIZ), fn);
194: DEBUG(7, "erdblk ret %d\n", len);
195: if (len < 0) {
196: DEBUG(7, "erdblk failed\n", "");
197: return(FAIL);
198: }
199: if ((msglen -= len) < 0) {
200: DEBUG(7, "erdblk read too much\n", "");
201: return(FAIL);
202: }
203: fwrite(bufr, sizeof (char), len, fp2);
204: if (msglen == 0)
205: break;
206: }
207: ticks = millitick();
208: sprintf(text, "<- %ld / %ld.%.3d secs", bytes, ticks / 1000, ticks % 1000);
209: DEBUG(4, "%s\n", text);
210: syslog(text);
211: return(0);
212: }
213:
214: /*
215: * read block from link
216: * reads are timed
217: * blk -> address of buffer
218: * len -> size to read
219: * fn -> link descriptor
220: * returns:
221: * FAIL -> link error timeout on link
222: * i -> # of bytes read
223: */
224: erdblk(blk, len, fn)
225: register char *blk;
226: {
227: register int i, ret;
228:
229: if(setjmp(Failbuf)) {
230: DEBUG(7, "erdblk timeout\n", "");
231: return(FAIL);
232: }
233:
234: for (i = 0; i < len; i += ret) {
235: alarm(60);
236: DEBUG(7, "ask %d ", len - i);
237: if ((ret = read(fn, blk, (unsigned) len - i)) < 0) {
238: alarm(0);
239: DEBUG(7, "read failed\n", "");
240: return(FAIL);
241: }
242: DEBUG(7, "got %d\n", ret);
243: blk += ret;
244: if (ret == 0)
245: break;
246: }
247: alarm(0);
248: return(i);
249: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.