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