8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / bnu / eio.c
blobf151af851ed0497ab146e0175aa9887abe0c4d62
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
32 #include "uucp.h"
34 #ifdef E_PROTOCOL
36 #ifndef MIN
37 #define MIN(a,b) (((a)<(b))?(a):(b))
38 #endif
40 #if defined(BSD4_2) || defined (ATTSVR4)
41 #include <netinet/in.h>
42 #endif /* BSD4_2 || ATTSVR4 */
44 #define EBUFSIZ 1024
45 #define EMESGLEN 20
47 #define TBUFSIZE 1024
48 #define TPACKSIZE 512
50 extern long lseek(); /* Find offset into the file. */
51 static jmp_buf Failbuf;
52 extern int erdblk();
53 extern unsigned msgtime;
55 static char Erdstash[EBUFSIZ];
56 static int Erdlen;
59 * error-free channel protocol
61 /* ARGSUSED */
62 static void
63 ealarm(sig)
64 int sig;
66 longjmp(Failbuf, 1);
68 static void (*esig)();
71 * turn on protocol timer
73 int
74 eturnon()
76 esig=signal(SIGALRM, ealarm);
77 return(0);
80 int
81 eturnoff()
83 signal(SIGALRM, esig);
84 return(0);
88 * write message across link
89 * type -> message type
90 * str -> message body (ascii string)
91 * fn -> link file descriptor
92 * return
93 * FAIL -> write failed
94 * SUCCESS -> write succeeded
96 int
97 ewrmsg(type, str, fn)
98 char *str;
99 int fn;
100 char type;
102 return(etwrmsg(type, str, fn, 0));
106 * read message from link
107 * str -> message buffer
108 * fn -> file descriptor
109 * return
110 * FAIL -> read timed out
111 * SUCCESS -> ok message in str
114 erdmsg(str, fn)
115 char *str;
117 return(etrdmsg(str, fn, 0));
121 * read data from file fp1 and write
122 * on link
123 * fp1 -> file descriptor
124 * fn -> link descriptor
125 * returns:
126 * FAIL ->failure in link
127 * SUCCESS -> ok
130 ewrdata(fp1, fn)
131 FILE *fp1;
132 int fn;
134 int ret;
135 int fd1;
136 int len;
137 unsigned long bytes;
138 char bufr[EBUFSIZ];
139 struct stat statbuf;
140 off_t msglen;
141 char cmsglen[EMESGLEN];
142 off_t startPoint; /* Offset from begining of the file in
143 * case we are restarting from a check
144 * point.
147 if (setjmp(Failbuf)) {
148 DEBUG(7, "ewrdata failed\n%s", "");
149 return(FAIL);
151 bytes = 0L;
152 fd1 = fileno(fp1);
153 fstat(fd1, &statbuf);
154 startPoint = lseek(fd1, 0L, 1);
155 if (startPoint < 0)
157 DEBUG(7, "ewrdata lseek failed. Errno=%d\n", errno);
158 return(FAIL);
160 msglen = statbuf.st_size - startPoint;
161 if (msglen < 0)
163 DEBUG(7, "ewrdata: startPoint past end of file.\n%s", "");
164 return(FAIL);
166 sprintf(cmsglen, "%ld", (long) msglen);
167 DEBUG(9, "ewrdata writing %d ...", sizeof(cmsglen));
168 alarm(msgtime);
169 ret = (*Write)(fn, cmsglen, sizeof(cmsglen));
170 alarm(0);
171 DEBUG(9, "ret %d\n", ret);
172 if (ret != sizeof(cmsglen))
173 return(FAIL);
174 DEBUG(7, "ewrdata planning to send %ld bytes to remote.\n", msglen);
175 while ((len = read( fd1, bufr, EBUFSIZ )) > 0) {
176 DEBUG(9, "ewrdata writing %d ...", len);
177 alarm(msgtime);
178 bytes += len;
179 putfilesize(bytes);
180 ret = (*Write)(fn, bufr, (unsigned) len);
181 alarm(0);
182 DEBUG(9, "ewrdata ret %d\n", ret);
183 if (ret != len)
184 return(FAIL);
185 if ((msglen -= len) <= 0)
186 break;
188 if (len < 0 || (len == 0 && msglen != 0)) return(FAIL);
189 return(SUCCESS);
193 * read data from link and
194 * write into file
195 * fp2 -> file descriptor
196 * fn -> link descriptor
197 * returns:
198 * SUCCESS -> ok
199 * FAIL -> failure on link
202 erddata(fn, fp2)
203 FILE *fp2;
205 int ret;
206 int fd2;
207 char bufr[EBUFSIZ];
208 int len;
209 long msglen, bytes;
210 char cmsglen[EMESGLEN], *cptr, *erdptr = Erdstash;
212 DEBUG(9, "erddata wants %d\n", sizeof(cmsglen));
213 if (Erdlen > 0) {
214 DEBUG(9, "%d bytes stashed\n", Erdlen);
215 if (Erdlen >= sizeof(cmsglen)) {
216 memcpy(cmsglen, erdptr, sizeof(cmsglen));
217 Erdlen -= sizeof(cmsglen);
218 erdptr += sizeof(cmsglen);
219 ret = len = 0;
220 } else {
221 memcpy(cmsglen, Erdstash, Erdlen);
222 cptr = cmsglen + Erdlen;
223 len = sizeof(cmsglen) - Erdlen;
224 ret = erdblk(cptr, len, fn);
225 Erdlen = 0;
227 } else {
228 len = sizeof(cmsglen);
229 ret = erdblk(cmsglen, sizeof(cmsglen), fn);
231 if (ret != len)
232 return(FAIL);
233 ret = SUCCESS;
234 sscanf(cmsglen, "%ld", &msglen);
235 if ( ((msglen-1)/512 +1) > Ulimit )
236 ret = EFBIG;
237 DEBUG(7, "erddata file is %ld bytes\n", msglen);
238 fd2 = fileno( fp2 );
240 if (Erdlen > 0) {
241 DEBUG(9, "%d bytes stashed\n", Erdlen);
242 if (write(fileno(fp2), erdptr, Erdlen) != Erdlen)
243 return(FAIL);
244 msglen -= Erdlen;
245 Erdlen = 0;
246 DEBUG(7, "erddata remainder is %ld bytes\n", msglen);
249 for (;;) {
250 len = erdblk(bufr, (int) MIN(msglen, EBUFSIZ), fn);
251 DEBUG(9, "erdblk ret %d\n", len);
252 if (len < 0) {
253 DEBUG(7, "erdblk failed\n%s", "");
254 return(FAIL);
258 * handle the case for remote socket close.
260 if (len == 0) {
261 ret = errno;
262 DEBUG(7, "erddata: remote socket closed, errno %d\n",
263 ret);
264 break;
266 bytes += len;
267 putfilesize(bytes);
268 if ((msglen -= len) < 0) {
269 DEBUG(7, "erdblk read too much\n%s", "");
270 return(FAIL);
272 /* this write is to file -- use write(2), not (*Write) */
273 if ( ret == SUCCESS && write( fd2, bufr, len ) != len ) {
274 ret = errno;
275 DEBUG(7, "erddata: write to file failed, errno %d\n", ret);
277 if (msglen == 0)
278 break;
280 return(ret);
284 * read block from link
285 * reads are timed
286 * blk -> address of buffer
287 * len -> size to read
288 * fn -> link descriptor
289 * returns:
290 * FAIL -> link error timeout on link
291 * i -> # of bytes read (must not be 0)
294 erdblk(blk, len, fn)
295 char *blk;
297 int i, ret;
299 if(setjmp(Failbuf)) {
300 DEBUG(7, "timeout (%d sec)\n", msgtime);
301 return(FAIL);
304 alarm(msgtime);
305 for (i = 0; i < len; i += ret) {
306 DEBUG(9, "erdblk ask %d ", len - i);
307 if ((ret = (*Read)(fn, blk, (unsigned) len - i)) < 0) {
308 alarm(0);
309 DEBUG(7, "erdblk read failed\n%s", "");
310 return(FAIL);
312 DEBUG(9, "erdblk got %d\n", ret);
313 if (ret == 0)
314 break;
315 blk += ret;
317 alarm(0);
318 return(i);
321 struct tbuf {
322 long t_nbytes;
323 char t_data[TBUFSIZE];
327 * read message from link
328 * str -> message buffer
329 * fn -> file descriptor
330 * return
331 * FAIL -> read timed out
332 * SUCCESS -> ok message in str
335 trdmsg(str, fn)
336 char *str;
338 return(etrdmsg(str, fn, TPACKSIZE));
342 * write message across link
343 * type -> message type
344 * str -> message body (ascii string)
345 * fn -> link file descriptor
346 * return
347 * FAIL -> write failed
348 * SUCCESS -> write succeeded
351 twrmsg(type, str, fn)
352 char type;
353 char *str;
355 return(etwrmsg(type, str, fn, TPACKSIZE));
359 * read data from file fp1 and write on link
360 * fp1 -> file descriptor
361 * fn -> link descriptor
362 * returns:
363 * FAIL ->failure in link
364 * SUCCESS -> ok
367 twrdata(fp1, fn)
368 FILE *fp1;
369 int fn;
371 int ret;
372 int len;
373 unsigned long bytes;
374 struct tbuf bufr;
375 struct stat statbuf;
377 if (setjmp(Failbuf)) {
378 DEBUG(7, "twrdata failed\n", 0);
379 return(FAIL);
381 fstat(fileno(fp1), &statbuf);
382 bytes = 0L;
383 while ((len = read(fileno(fp1), bufr.t_data, TBUFSIZE)) > 0) {
384 bufr.t_nbytes = htonl((long)len);
385 DEBUG(7, "twrdata writing %d ...", len);
386 bytes += len;
387 putfilesize(bytes);
388 len += sizeof(long);
389 alarm(msgtime);
390 ret = (*Write)(fn, (char *)&bufr, (unsigned) len);
391 alarm(0);
392 DEBUG(7, "ret %d\n", ret);
393 if (ret != len)
394 return(FAIL);
395 if (len != TBUFSIZE+sizeof(long))
396 break;
398 bufr.t_nbytes = 0;
399 alarm(msgtime);
400 ret = write(fn, (char *)&bufr, sizeof(long));
401 alarm(0);
402 if (ret != sizeof(long))
403 return FAIL;
404 return(SUCCESS);
408 * read data from link and write into file
409 * fp2 -> file descriptor
410 * fn -> link descriptor
411 * returns:
412 * SUCCESS -> ok
413 * FAIL -> failure on link
416 trddata(fn, fp2)
417 FILE *fp2;
419 int len, nread;
420 long Nbytes;
421 unsigned long bytes = 0L;
422 char bufr[TBUFSIZE];
424 for (;;) {
425 len = erdblk((char *)&Nbytes, sizeof(Nbytes), fn);
426 DEBUG(7, "trddata ret %d\n", len);
427 if (len != sizeof(Nbytes))
428 return(FAIL);
429 Nbytes = ntohl(Nbytes);
430 DEBUG(7,"trddata expecting %ld bytes\n", Nbytes);
431 nread = Nbytes;
432 if (nread == 0)
433 break;
434 len = erdblk(bufr, nread, fn);
435 if (len != Nbytes)
436 return(FAIL);
437 bytes += len;
438 putfilesize(bytes);
439 if (write(fileno(fp2), bufr, len) != len)
440 return(FAIL);
442 return(SUCCESS);
446 * read message from link
447 * str -> message buffer
448 * fn -> file descriptor
449 * i -> if non-zero, amount to read; o.w., read up to '\0'
450 * return
451 * FAIL -> read timed out
452 * SUCCESS -> ok message in str
454 * 'e' is fatally flawed -- in a byte stream world, rdmsg can pick up
455 * the cmsglen on a R request. if this happens, we stash the excess
456 * where rddata can pick it up.
460 etrdmsg(str, fn, i)
461 char *str;
462 int i;
464 int len;
465 int nullterm = 0;
466 char *null, *argstr;
469 if (i == 0) {
470 DEBUG(9, "etrdmsg looking for null terminator\n", 0);
471 nullterm++;
472 i = EBUFSIZ;
473 argstr = str;
476 if(setjmp(Failbuf)) {
477 DEBUG(7, "timeout (%d sec)\n", msgtime);
478 return(FAIL);
481 alarm(msgtime);
482 for (;;) {
483 DEBUG(9, "etrdmsg want %d ...", i);
484 len = (*Read)(fn, str, i);
485 DEBUG(9, "got %d\n", len);
486 if (len == 0)
487 continue; /* timeout will get this */
488 if (len < 0) {
489 alarm(0);
490 return(FAIL);
492 str += len;
493 i -= len;
494 if (nullterm) {
495 /* no way can a msg be as long as EBUFSIZ-1 ... */
496 *str = 0;
497 null = strchr(argstr, '\0');
498 if (null != str) {
499 null++; /* start of stash */
500 memcpy(Erdstash + Erdlen, null, str - null);
501 Erdlen += str - null;
502 break;
503 } else
504 argstr = str;
505 } else {
506 if (i == 0)
507 break;
510 alarm(0);
511 return(SUCCESS);
515 * write message across link
516 * type -> message type
517 * str -> message body (ascii string)
518 * fn -> link file descriptor
519 * len -> if non-zero, amount to write;
520 o.w., write up to '\0' (inclusive)
521 * return
522 * FAIL -> write failed
523 * SUCCESS -> write succeeded
526 etwrmsg(type, str, fn, len)
527 char type;
528 char *str;
529 int fn, len;
531 char bufr[EBUFSIZ], *endstr;
532 int ret;
534 bufr[0] = type;
536 /* point endstr to last character to be sent */
537 if ((endstr = strchr(str, '\n')) != 0)
538 *endstr = 0;
539 else
540 endstr = str + strlen(str);
542 memcpy(bufr+1, str, (endstr - str) + 1); /* include '\0' */
543 if (len == 0)
544 len = (endstr - str) + 2; /* include bufr[0] and '\0' */
545 else
546 bufr[len-1] = 0; /* 't' needs this terminator */
549 if (setjmp(Failbuf)) {
550 DEBUG(7, "etwrmsg write failed\n", 0);
551 return(FAIL);
553 DEBUG(9, "etwrmsg want %d ... ", len);
554 alarm(msgtime);
555 ret = (*Write)(fn, bufr, (unsigned) len);
556 alarm(0);
557 DEBUG(9, "sent %d\n", ret);
558 if (ret != len)
559 return(FAIL);
560 return(SUCCESS);
562 #endif /* E_PROTOCOL */