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]
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"
37 #define MIN(a,b) (((a)<(b))?(a):(b))
40 #if defined(BSD4_2) || defined (ATTSVR4)
41 #include <netinet/in.h>
42 #endif /* BSD4_2 || ATTSVR4 */
50 extern long lseek(); /* Find offset into the file. */
51 static jmp_buf Failbuf
;
53 extern unsigned msgtime
;
55 static char Erdstash
[EBUFSIZ
];
59 * error-free channel protocol
68 static void (*esig
)();
71 * turn on protocol timer
76 esig
=signal(SIGALRM
, ealarm
);
83 signal(SIGALRM
, esig
);
88 * write message across link
89 * type -> message type
90 * str -> message body (ascii string)
91 * fn -> link file descriptor
93 * FAIL -> write failed
94 * SUCCESS -> write succeeded
102 return(etwrmsg(type
, str
, fn
, 0));
106 * read message from link
107 * str -> message buffer
108 * fn -> file descriptor
110 * FAIL -> read timed out
111 * SUCCESS -> ok message in str
117 return(etrdmsg(str
, fn
, 0));
121 * read data from file fp1 and write
123 * fp1 -> file descriptor
124 * fn -> link descriptor
126 * FAIL ->failure in link
141 char cmsglen
[EMESGLEN
];
142 off_t startPoint
; /* Offset from begining of the file in
143 * case we are restarting from a check
147 if (setjmp(Failbuf
)) {
148 DEBUG(7, "ewrdata failed\n%s", "");
153 fstat(fd1
, &statbuf
);
154 startPoint
= lseek(fd1
, 0L, 1);
157 DEBUG(7, "ewrdata lseek failed. Errno=%d\n", errno
);
160 msglen
= statbuf
.st_size
- startPoint
;
163 DEBUG(7, "ewrdata: startPoint past end of file.\n%s", "");
166 sprintf(cmsglen
, "%ld", (long) msglen
);
167 DEBUG(9, "ewrdata writing %d ...", sizeof(cmsglen
));
169 ret
= (*Write
)(fn
, cmsglen
, sizeof(cmsglen
));
171 DEBUG(9, "ret %d\n", ret
);
172 if (ret
!= sizeof(cmsglen
))
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
);
180 ret
= (*Write
)(fn
, bufr
, (unsigned) len
);
182 DEBUG(9, "ewrdata ret %d\n", ret
);
185 if ((msglen
-= len
) <= 0)
188 if (len
< 0 || (len
== 0 && msglen
!= 0)) return(FAIL
);
193 * read data from link and
195 * fp2 -> file descriptor
196 * fn -> link descriptor
199 * FAIL -> failure on link
210 char cmsglen
[EMESGLEN
], *cptr
, *erdptr
= Erdstash
;
212 DEBUG(9, "erddata wants %d\n", sizeof(cmsglen
));
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
);
221 memcpy(cmsglen
, Erdstash
, Erdlen
);
222 cptr
= cmsglen
+ Erdlen
;
223 len
= sizeof(cmsglen
) - Erdlen
;
224 ret
= erdblk(cptr
, len
, fn
);
228 len
= sizeof(cmsglen
);
229 ret
= erdblk(cmsglen
, sizeof(cmsglen
), fn
);
234 sscanf(cmsglen
, "%ld", &msglen
);
235 if ( ((msglen
-1)/512 +1) > Ulimit
)
237 DEBUG(7, "erddata file is %ld bytes\n", msglen
);
241 DEBUG(9, "%d bytes stashed\n", Erdlen
);
242 if (write(fileno(fp2
), erdptr
, Erdlen
) != Erdlen
)
246 DEBUG(7, "erddata remainder is %ld bytes\n", msglen
);
250 len
= erdblk(bufr
, (int) MIN(msglen
, EBUFSIZ
), fn
);
251 DEBUG(9, "erdblk ret %d\n", len
);
253 DEBUG(7, "erdblk failed\n%s", "");
258 * handle the case for remote socket close.
262 DEBUG(7, "erddata: remote socket closed, errno %d\n",
268 if ((msglen
-= len
) < 0) {
269 DEBUG(7, "erdblk read too much\n%s", "");
272 /* this write is to file -- use write(2), not (*Write) */
273 if ( ret
== SUCCESS
&& write( fd2
, bufr
, len
) != len
) {
275 DEBUG(7, "erddata: write to file failed, errno %d\n", ret
);
284 * read block from link
286 * blk -> address of buffer
287 * len -> size to read
288 * fn -> link descriptor
290 * FAIL -> link error timeout on link
291 * i -> # of bytes read (must not be 0)
299 if(setjmp(Failbuf
)) {
300 DEBUG(7, "timeout (%d sec)\n", 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) {
309 DEBUG(7, "erdblk read failed\n%s", "");
312 DEBUG(9, "erdblk got %d\n", ret
);
323 char t_data
[TBUFSIZE
];
327 * read message from link
328 * str -> message buffer
329 * fn -> file descriptor
331 * FAIL -> read timed out
332 * SUCCESS -> ok message in 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
347 * FAIL -> write failed
348 * SUCCESS -> write succeeded
351 twrmsg(type
, str
, fn
)
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
363 * FAIL ->failure in link
377 if (setjmp(Failbuf
)) {
378 DEBUG(7, "twrdata failed\n", 0);
381 fstat(fileno(fp1
), &statbuf
);
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
);
390 ret
= (*Write
)(fn
, (char *)&bufr
, (unsigned) len
);
392 DEBUG(7, "ret %d\n", ret
);
395 if (len
!= TBUFSIZE
+sizeof(long))
400 ret
= write(fn
, (char *)&bufr
, sizeof(long));
402 if (ret
!= sizeof(long))
408 * read data from link and write into file
409 * fp2 -> file descriptor
410 * fn -> link descriptor
413 * FAIL -> failure on link
421 unsigned long bytes
= 0L;
425 len
= erdblk((char *)&Nbytes
, sizeof(Nbytes
), fn
);
426 DEBUG(7, "trddata ret %d\n", len
);
427 if (len
!= sizeof(Nbytes
))
429 Nbytes
= ntohl(Nbytes
);
430 DEBUG(7,"trddata expecting %ld bytes\n", Nbytes
);
434 len
= erdblk(bufr
, nread
, fn
);
439 if (write(fileno(fp2
), bufr
, len
) != len
)
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'
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.
470 DEBUG(9, "etrdmsg looking for null terminator\n", 0);
476 if(setjmp(Failbuf
)) {
477 DEBUG(7, "timeout (%d sec)\n", msgtime
);
483 DEBUG(9, "etrdmsg want %d ...", i
);
484 len
= (*Read
)(fn
, str
, i
);
485 DEBUG(9, "got %d\n", len
);
487 continue; /* timeout will get this */
495 /* no way can a msg be as long as EBUFSIZ-1 ... */
497 null
= strchr(argstr
, '\0');
499 null
++; /* start of stash */
500 memcpy(Erdstash
+ Erdlen
, null
, str
- null
);
501 Erdlen
+= str
- null
;
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)
522 * FAIL -> write failed
523 * SUCCESS -> write succeeded
526 etwrmsg(type
, str
, fn
, len
)
531 char bufr
[EBUFSIZ
], *endstr
;
536 /* point endstr to last character to be sent */
537 if ((endstr
= strchr(str
, '\n')) != 0)
540 endstr
= str
+ strlen(str
);
542 memcpy(bufr
+1, str
, (endstr
- str
) + 1); /* include '\0' */
544 len
= (endstr
- str
) + 2; /* include bufr[0] and '\0' */
546 bufr
[len
-1] = 0; /* 't' needs this terminator */
549 if (setjmp(Failbuf
)) {
550 DEBUG(7, "etwrmsg write failed\n", 0);
553 DEBUG(9, "etwrmsg want %d ... ", len
);
555 ret
= (*Write
)(fn
, bufr
, (unsigned) len
);
557 DEBUG(9, "sent %d\n", ret
);
562 #endif /* E_PROTOCOL */