• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
3  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  *	$Id: stream.c,v 1.24 2005/06/01 19:22:07 roland Exp $
29  */
30 
31 #include "defs.h"
32 #include <sys/syscall.h>
33 
34 #ifdef HAVE_POLL_H
35 #include <poll.h>
36 #endif
37 #ifdef HAVE_SYS_POLL_H
38 #include <sys/poll.h>
39 #endif
40 #ifdef HAVE_STROPTS_H
41 #include <stropts.h>
42 #endif
43 #ifdef HAVE_SYS_CONF_H
44 #include <sys/conf.h>
45 #endif
46 #ifdef HAVE_SYS_STREAM_H
47 #include <sys/stream.h>
48 #endif
49 #ifdef HAVE_SYS_TIHDR_H
50 #include <sys/tihdr.h>
51 #endif
52 
53 #if defined(HAVE_SYS_STREAM_H) || defined(LINUX) || defined(FREEBSD)
54 
55 #ifndef HAVE_STROPTS_H
56 #define RS_HIPRI 1
57 struct strbuf {
58         int     maxlen;                 /* no. of bytes in buffer */
59         int     len;                    /* no. of bytes returned */
60         char    *buf;                   /* pointer to data */
61 };
62 #define MORECTL 1
63 #define MOREDATA 2
64 #endif /* !HAVE_STROPTS_H */
65 
66 #ifdef HAVE_SYS_TIUSER_H
67 #include <sys/tiuser.h>
68 #include <sys/sockmod.h>
69 #include <sys/timod.h>
70 #endif /* HAVE_SYS_TIUSER_H */
71 
72 #ifndef FREEBSD
73 static const struct xlat msgflags[] = {
74 	{ RS_HIPRI,	"RS_HIPRI"	},
75 	{ 0,		NULL		},
76 };
77 
78 
79 static void
printstrbuf(tcp,sbp,getting)80 printstrbuf(tcp, sbp, getting)
81 struct tcb *tcp;
82 struct strbuf *sbp;
83 int getting;
84 {
85 	if (sbp->maxlen == -1 && getting)
86 		tprintf("{maxlen=-1}");
87 	else {
88 		tprintf("{");
89 		if (getting)
90 			tprintf("maxlen=%d, ", sbp->maxlen);
91 		tprintf("len=%d, buf=", sbp->len);
92 		printstr(tcp, (unsigned long) sbp->buf, sbp->len);
93 		tprintf("}");
94 	}
95 }
96 
97 static void
printstrbufarg(tcp,arg,getting)98 printstrbufarg(tcp, arg, getting)
99 struct tcb *tcp;
100 int arg;
101 int getting;
102 {
103 	struct strbuf buf;
104 
105 	if (arg == 0)
106 		tprintf("NULL");
107 	else if (umove(tcp, arg, &buf) < 0)
108 		tprintf("{...}");
109 	else
110 		printstrbuf(tcp, &buf, getting);
111 	tprintf(", ");
112 }
113 
114 int
sys_putmsg(tcp)115 sys_putmsg(tcp)
116 struct tcb *tcp;
117 {
118 	int i;
119 
120 	if (entering(tcp)) {
121 		/* fd */
122 		tprintf("%ld, ", tcp->u_arg[0]);
123 		/* control and data */
124 		for (i = 1; i < 3; i++)
125 			printstrbufarg(tcp, tcp->u_arg[i], 0);
126 		/* flags */
127 		printflags(msgflags, tcp->u_arg[3], "RS_???");
128 	}
129 	return 0;
130 }
131 
132 int
sys_getmsg(tcp)133 sys_getmsg(tcp)
134 struct tcb *tcp;
135 {
136 	int i, flags;
137 
138 	if (entering(tcp)) {
139 		/* fd */
140 		tprintf("%lu, ", tcp->u_arg[0]);
141 	} else {
142 		if (syserror(tcp)) {
143 			tprintf("%#lx, %#lx, %#lx",
144 				tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
145 			return 0;
146 		}
147 		/* control and data */
148 		for (i = 1; i < 3; i++)
149 			printstrbufarg(tcp, tcp->u_arg[i], 1);
150 		/* pointer to flags */
151 		if (tcp->u_arg[3] == 0)
152 			tprintf("NULL");
153 		else if (umove(tcp, tcp->u_arg[3], &flags) < 0)
154 			tprintf("[?]");
155 		else {
156 			tprintf("[");
157 			printflags(msgflags, flags, "RS_???");
158 			tprintf("]");
159 		}
160 		/* decode return value */
161 		switch (tcp->u_rval) {
162 		case MORECTL:
163 			tcp->auxstr = "MORECTL";
164 			break;
165 		case MORECTL|MOREDATA:
166 			tcp->auxstr = "MORECTL|MOREDATA";
167 			break;
168 		case MOREDATA:
169 			tcp->auxstr = "MORECTL";
170 			break;
171 		default:
172 			tcp->auxstr = NULL;
173 			break;
174 		}
175 	}
176 	return RVAL_HEX | RVAL_STR;
177 }
178 
179 #if defined SYS_putpmsg || defined SYS_getpmsg
180 static const struct xlat pmsgflags[] = {
181 #ifdef MSG_HIPRI
182 	{ MSG_HIPRI,	"MSG_HIPRI"	},
183 #endif
184 #ifdef MSG_AND
185 	{ MSG_ANY,	"MSG_ANY"	},
186 #endif
187 #ifdef MSG_BAND
188 	{ MSG_BAND,	"MSG_BAND"	},
189 #endif
190 	{ 0,		NULL		},
191 };
192 #endif
193 
194 #ifdef SYS_putpmsg
195 int
sys_putpmsg(tcp)196 sys_putpmsg(tcp)
197 struct tcb *tcp;
198 {
199 	int i;
200 
201 	if (entering(tcp)) {
202 		/* fd */
203 		tprintf("%ld, ", tcp->u_arg[0]);
204 		/* control and data */
205 		for (i = 1; i < 3; i++)
206 			printstrbufarg(tcp, tcp->u_arg[i], 0);
207 		/* band */
208 		tprintf("%ld, ", tcp->u_arg[3]);
209 		/* flags */
210 		printflags(pmsgflags, tcp->u_arg[4], "MSG_???");
211 	}
212 	return 0;
213 }
214 #endif /* SYS_putpmsg */
215 
216 #ifdef SYS_getpmsg
217 int
sys_getpmsg(tcp)218 sys_getpmsg(tcp)
219 struct tcb *tcp;
220 {
221 	int i, flags;
222 
223 	if (entering(tcp)) {
224 		/* fd */
225 		tprintf("%lu, ", tcp->u_arg[0]);
226 	} else {
227 		if (syserror(tcp)) {
228 			tprintf("%#lx, %#lx, %#lx, %#lx", tcp->u_arg[1],
229 				tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[4]);
230 			return 0;
231 		}
232 		/* control and data */
233 		for (i = 1; i < 3; i++)
234 			printstrbufarg(tcp, tcp->u_arg[i], 1);
235 		/* pointer to band */
236 		printnum(tcp, tcp->u_arg[3], "%d");
237 		tprintf(", ");
238 		/* pointer to flags */
239 		if (tcp->u_arg[4] == 0)
240 			tprintf("NULL");
241 		else if (umove(tcp, tcp->u_arg[4], &flags) < 0)
242 			tprintf("[?]");
243 		else {
244 			tprintf("[");
245 			printflags(pmsgflags, flags, "MSG_???");
246 			tprintf("]");
247 		}
248 		/* decode return value */
249 		switch (tcp->u_rval) {
250 		case MORECTL:
251 			tcp->auxstr = "MORECTL";
252 			break;
253 		case MORECTL|MOREDATA:
254 			tcp->auxstr = "MORECTL|MOREDATA";
255 			break;
256 		case MOREDATA:
257 			tcp->auxstr = "MORECTL";
258 			break;
259 		default:
260 			tcp->auxstr = NULL;
261 			break;
262 		}
263 	}
264 	return RVAL_HEX | RVAL_STR;
265 }
266 #endif /* SYS_getpmsg */
267 
268 #endif /* !FREEBSD */
269 
270 
271 #ifdef HAVE_SYS_POLL_H
272 
273 static const struct xlat pollflags[] = {
274 #ifdef POLLIN
275 	{ POLLIN,	"POLLIN"	},
276 	{ POLLPRI,	"POLLPRI"	},
277 	{ POLLOUT,	"POLLOUT"	},
278 #ifdef POLLRDNORM
279 	{ POLLRDNORM,	"POLLRDNORM"	},
280 #endif
281 #ifdef POLLWRNORM
282 	{ POLLWRNORM,	"POLLWRNORM"	},
283 #endif
284 #ifdef POLLRDBAND
285 	{ POLLRDBAND,	"POLLRDBAND"	},
286 #endif
287 #ifdef POLLWRBAND
288 	{ POLLWRBAND,	"POLLWRBAND"	},
289 #endif
290 	{ POLLERR,	"POLLERR"	},
291 	{ POLLHUP,	"POLLHUP"	},
292 	{ POLLNVAL,	"POLLNVAL"	},
293 #endif
294 	{ 0,		NULL		},
295 };
296 
297 int
sys_poll(tcp)298 sys_poll(tcp)
299 struct tcb *tcp;
300 {
301 	struct pollfd fds;
302 	unsigned nfds;
303 	unsigned long size, start, cur, end, abbrev_end;
304 	int failed = 0;
305 
306 	if (entering(tcp))
307 		return 0;
308 
309 	nfds = tcp->u_arg[1];
310 	size = sizeof(fds) * nfds;
311 	start = tcp->u_arg[0];
312 	end = start + size;
313 	if (nfds == 0 || size / sizeof(fds) != nfds || end < start) {
314 		tprintf("%#lx, %d, %ld",
315 			tcp->u_arg[0], nfds, tcp->u_arg[2]);
316 		return 0;
317 	}
318 	if (abbrev(tcp)) {
319 		abbrev_end = start + max_strlen * sizeof(fds);
320 		if (abbrev_end < start)
321 			abbrev_end = end;
322 	} else {
323 		abbrev_end = end;
324 	}
325 	tprintf("[");
326 	for (cur = start; cur < end; cur += sizeof(fds)) {
327 		if (cur > start)
328 			tprintf(", ");
329 		if (cur >= abbrev_end) {
330 			tprintf("...");
331 			break;
332 		}
333 		if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) {
334 			tprintf("?");
335 			failed = 1;
336 			break;
337 		}
338 		if (fds.fd < 0) {
339 			tprintf("{fd=%d}", fds.fd);
340 			continue;
341 		}
342 		tprintf("{fd=%d, events=", fds.fd);
343 		printflags(pollflags, fds.events, "POLL???");
344 		if (!syserror(tcp) && fds.revents) {
345 			tprintf(", revents=");
346 			printflags(pollflags, fds.revents, "POLL???");
347 		}
348 		tprintf("}");
349 	}
350 	tprintf("]");
351 	if (failed)
352 		tprintf(" %#lx", start);
353 	tprintf(", %d, ", nfds);
354 #ifdef INFTIM
355 	if (tcp->u_arg[2] == INFTIM)
356 		tprintf("INFTIM");
357 	else
358 #endif
359 		tprintf("%ld", tcp->u_arg[2]);
360 	return 0;
361 }
362 
363 
364 #else /* !HAVE_SYS_POLL_H */
365 int
sys_poll(tcp)366 sys_poll(tcp)
367 struct tcb *tcp;
368 {
369     	return 0;
370 }
371 #endif
372 
373 #if !defined(LINUX) && !defined(FREEBSD)
374 
375 static const struct xlat stream_flush_options[] = {
376 	{ FLUSHR,	"FLUSHR"	},
377 	{ FLUSHW,	"FLUSHW"	},
378 	{ FLUSHRW,	"FLUSHRW"	},
379 #ifdef FLUSHBAND
380 	{ FLUSHBAND,	"FLUSHBAND"	},
381 #endif
382 	{ 0,		NULL		},
383 };
384 
385 static const struct xlat stream_setsig_flags[] = {
386 	{ S_INPUT,	"S_INPUT"	},
387 	{ S_HIPRI,	"S_HIPRI"	},
388 	{ S_OUTPUT,	"S_OUTPUT"	},
389 	{ S_MSG,	"S_MSG"		},
390 #ifdef S_ERROR
391 	{ S_ERROR,	"S_ERROR"	},
392 #endif
393 #ifdef S_HANGUP
394 	{ S_HANGUP,	"S_HANGUP"	},
395 #endif
396 #ifdef S_RDNORM
397 	{ S_RDNORM,	"S_RDNORM"	},
398 #endif
399 #ifdef S_WRNORM
400 	{ S_WRNORM,	"S_WRNORM"	},
401 #endif
402 #ifdef S_RDBAND
403 	{ S_RDBAND,	"S_RDBAND"	},
404 #endif
405 #ifdef S_WRBAND
406 	{ S_WRBAND,	"S_WRBAND"	},
407 #endif
408 #ifdef S_BANDURG
409 	{ S_BANDURG,	"S_BANDURG"	},
410 #endif
411 	{ 0,		NULL		},
412 };
413 
414 static const struct xlat stream_read_options[] = {
415 	{ RNORM,	"RNORM"		},
416 	{ RMSGD,	"RMSGD"		},
417 	{ RMSGN,	"RMSGN"		},
418 	{ 0,		NULL		},
419 };
420 
421 static const struct xlat stream_read_flags[] = {
422 #ifdef RPROTDAT
423 	{ RPROTDAT,	"RPROTDAT"	},
424 #endif
425 #ifdef RPROTDIS
426 	{ RPROTDIS,	"RPROTDIS"	},
427 #endif
428 #ifdef RPROTNORM
429 	{ RPROTNORM,	"RPROTNORM"	},
430 #endif
431 	{ 0,		NULL		},
432 };
433 
434 #ifndef RMODEMASK
435 #define RMODEMASK (~0)
436 #endif
437 
438 #ifdef I_SWROPT
439 static const struct xlat stream_write_flags[] = {
440 	{ SNDZERO,	"SNDZERO"	},
441 	{ SNDPIPE,	"SNDPIPE"	},
442 	{ 0,		NULL		},
443 };
444 #endif /* I_SWROPT */
445 
446 #ifdef I_ATMARK
447 static const struct xlat stream_atmark_options[] = {
448 	{ ANYMARK,	"ANYMARK"	},
449 	{ LASTMARK,	"LASTMARK"	},
450 	{ 0,		NULL		},
451 };
452 #endif /* I_ATMARK */
453 
454 #ifdef TI_BIND
455 static const struct xlat transport_user_options[] = {
456 	{ T_CONN_REQ,	"T_CONN_REQ"	},
457 	{ T_CONN_RES,	"T_CONN_RES"	},
458 	{ T_DISCON_REQ,	"T_DISCON_REQ"	},
459 	{ T_DATA_REQ,	"T_DATA_REQ"	},
460 	{ T_EXDATA_REQ,	"T_EXDATA_REQ"	},
461 	{ T_INFO_REQ,	"T_INFO_REQ"	},
462 	{ T_BIND_REQ,	"T_BIND_REQ"	},
463 	{ T_UNBIND_REQ,	"T_UNBIND_REQ"	},
464 	{ T_UNITDATA_REQ,"T_UNITDATA_REQ"},
465 	{ T_OPTMGMT_REQ,"T_OPTMGMT_REQ"	},
466 	{ T_ORDREL_REQ,	"T_ORDREL_REQ"	},
467 	{ 0,		NULL		},
468 };
469 
470 static const struct xlat transport_user_flags [] = {
471 	{ 0,		"0"		},
472 	{ T_MORE,	"T_MORE"	},
473 	{ T_EXPEDITED,	"T_EXPEDITED"	},
474 	{ T_NEGOTIATE,	"T_NEGOTIATE"	},
475 	{ T_CHECK,	"T_CHECK"	},
476 	{ T_DEFAULT,	"T_DEFAULT"	},
477 	{ T_SUCCESS,	"T_SUCCESS"	},
478 	{ T_FAILURE,	"T_FAILURE"	},
479 	{ T_CURRENT,	"T_CURRENT"	},
480 	{ T_PARTSUCCESS,"T_PARTSUCCESS"	},
481 	{ T_READONLY,	"T_READONLY"	},
482 	{ T_NOTSUPPORT,	"T_NOTSUPPORT"	},
483 	{ 0,		NULL		},
484 };
485 
486 
487 #ifdef HAVE_STRUCT_T_OPTHDR
488 
489 static const struct xlat xti_level [] = {
490 	{ XTI_GENERIC,	"XTI_GENERIC"	},
491 	{ 0,		NULL		},
492 };
493 
494 static const struct xlat xti_generic [] = {
495 	{ XTI_DEBUG,	"XTI_DEBUG"	},
496 	{ XTI_LINGER,	"XTI_LINGER"	},
497 	{ XTI_RCVBUF,	"XTI_RCVBUF"	},
498 	{ XTI_RCVLOWAT,	"XTI_RCVLOWAT"	},
499 	{ XTI_SNDBUF,	"XTI_SNDBUF"	},
500 	{ XTI_SNDLOWAT,	"XTI_SNDLOWAT"	},
501 	{ 0,		NULL		},
502 };
503 
504 
505 
506 void
print_xti_optmgmt(tcp,addr,len)507 print_xti_optmgmt (tcp, addr, len)
508 struct tcb *tcp;
509 long addr;
510 int len;
511 {
512 	int c = 0;
513 	struct t_opthdr hdr;
514 
515 	while (len >= (int) sizeof hdr) {
516 		if (umove(tcp, addr, &hdr) < 0) break;
517 		if (c++) {
518 			tprintf (", ");
519 		}
520 		else if (len > hdr.len + sizeof hdr) {
521 			tprintf ("[");
522 		}
523 		tprintf ("{level=");
524 		printxval (xti_level, hdr.level, "???");
525 		tprintf (", name=");
526 		switch (hdr.level) {
527 		    case XTI_GENERIC:
528 			printxval (xti_generic, hdr.name, "XTI_???");
529 			break;
530 		    default:
531 			tprintf ("%ld", hdr.name);
532 			break;
533 		}
534 		tprintf (", status=");
535 		printxval (transport_user_flags,  hdr.status, "T_???");
536 		addr += sizeof hdr;
537 		len -= sizeof hdr;
538 		if ((hdr.len -= sizeof hdr) > 0) {
539 			if (hdr.len > len) break;
540 			tprintf (", val=");
541 			if (len == sizeof (int))
542 				printnum (tcp, addr, "%d");
543 			else
544 				printstr (tcp, addr, hdr.len);
545 			addr += hdr.len;
546 			len -= hdr.len;
547 		}
548 		tprintf ("}");
549 	}
550 	if (len > 0) {
551 		if (c++) tprintf (", ");
552 		printstr (tcp, addr, len);
553 	}
554 	if (c > 1) tprintf ("]");
555 }
556 
557 #endif
558 
559 
560 static void
print_optmgmt(tcp,addr,len)561 print_optmgmt (tcp, addr, len)
562 struct tcb *tcp;
563 long addr;
564 int len;
565 {
566 	/* We don't know how to tell if TLI (socket) or XTI
567 	   optmgmt is being used yet, assume TLI. */
568 #if defined (HAVE_STRUCT_OPTHDR)
569 	print_sock_optmgmt (tcp, addr, len);
570 #elif defined (HAVE_STRUCT_T_OPTHDR)
571 	print_xti_optmgmt (tcp, addr, len);
572 #else
573 	printstr (tcp, addr, len);
574 #endif
575 }
576 
577 
578 
579 
580 static const struct xlat service_type [] = {
581 	{ T_COTS,	"T_COTS"	},
582 	{ T_COTS_ORD,	"T_COTS_ORD"	},
583 	{ T_CLTS,	"T_CLTS"	},
584 	{ 0,		NULL		},
585 };
586 
587 static const struct xlat ts_state [] = {
588 	{ TS_UNBND,	"TS_UNBND"	},
589 	{ TS_WACK_BREQ,	"TS_WACK_BREQ"	},
590 	{ TS_WACK_UREQ,	"TS_WACK_UREQ"	},
591 	{ TS_IDLE,	"TS_IDLE"	},
592 	{ TS_WACK_OPTREQ,"TS_WACK_OPTREQ"},
593 	{ TS_WACK_CREQ,	"TS_WACK_CREQ"	},
594 	{ TS_WCON_CREQ,	"TS_WCON_CREQ"	},
595 	{ TS_WRES_CIND,	"TS_WRES_CIND"	},
596 	{ TS_WACK_CRES,	"TS_WACK_CRES"	},
597 	{ TS_DATA_XFER,	"TS_DATA_XFER"	},
598 	{ TS_WIND_ORDREL,"TS_WIND_ORDREL"},
599 	{ TS_WREQ_ORDREL,"TS_WREQ_ORDREL"},
600 	{ TS_WACK_DREQ6,"TS_WACK_DREQ6"	},
601 	{ TS_WACK_DREQ7,"TS_WACK_DREQ7"	},
602 	{ TS_WACK_DREQ9,"TS_WACK_DREQ9"	},
603 	{ TS_WACK_DREQ10,"TS_WACK_DREQ10"},
604 	{ TS_WACK_DREQ11,"TS_WACK_DREQ11"},
605 	{ 0,		NULL		},
606 };
607 
608 static const struct xlat provider_flags [] = {
609 	{ 0,		"0"		},
610 	{ SENDZERO,	"SENDZERO"	},
611 	{ EXPINLINE,	"EXPINLINE"	},
612 	{ XPG4_1,	"XPG4_1"	},
613 	{ 0,		NULL		},
614 };
615 
616 
617 static const struct xlat tli_errors [] = {
618 	{ TBADADDR,	"TBADADDR"	},
619 	{ TBADOPT,	"TBADOPT"	},
620 	{ TACCES,	"TACCES"	},
621 	{ TBADF,	"TBADF"		},
622 	{ TNOADDR,	"TNOADDR"	},
623 	{ TOUTSTATE,	"TOUTSTATE"	},
624 	{ TBADSEQ,	"TBADSEQ"	},
625 	{ TSYSERR,	"TSYSERR"	},
626 	{ TLOOK,	"TLOOK"		},
627 	{ TBADDATA,	"TBADDATA"	},
628 	{ TBUFOVFLW,	"TBUFOVFLW"	},
629 	{ TFLOW,	"TFLOW"		},
630 	{ TNODATA,	"TNODATA"	},
631 	{ TNODIS,	"TNODIS"	},
632 	{ TNOUDERR,	"TNOUDERR"	},
633 	{ TBADFLAG,	"TBADFLAG"	},
634 	{ TNOREL,	"TNOREL"	},
635 	{ TNOTSUPPORT,	"TNOTSUPPORT"	},
636 	{ TSTATECHNG,	"TSTATECHNG"	},
637 	{ TNOSTRUCTYPE,	"TNOSTRUCTYPE"	},
638 	{ TBADNAME,	"TBADNAME"	},
639 	{ TBADQLEN,	"TBADQLEN"	},
640 	{ TADDRBUSY,	"TADDRBUSY"	},
641 	{ TINDOUT,	"TINDOUT"	},
642 	{ TPROVMISMATCH,"TPROVMISMATCH"	},
643 	{ TRESQLEN,	"TRESQLEN"	},
644 	{ TRESADDR,	"TRESADDR"	},
645 	{ TQFULL,	"TQFULL"	},
646 	{ TPROTO,	"TPROTO"	},
647 	{ 0,		NULL		},
648 };
649 
650 
651 static int
print_transport_message(tcp,expect,addr,len)652 print_transport_message (tcp, expect, addr, len)
653 struct tcb *tcp;
654 int expect;
655 long addr;
656 int len;
657 {
658 	union T_primitives m;
659 	int c = 0;
660 
661 	if (len < sizeof m.type) goto dump;
662 
663 	if (umove (tcp, addr, &m.type) < 0) goto dump;
664 
665 #define GET(type, struct)	\
666 	do {							\
667 		if (len < sizeof m.struct) goto dump;		\
668 		if (umove (tcp, addr, &m.struct) < 0) goto dump;\
669 		tprintf ("{");					\
670 		if (expect != type) {				\
671 			++c;					\
672 			tprintf (#type);			\
673 		}						\
674 	}							\
675 	while (0)
676 
677 #define COMMA() \
678 	do { if (c++) tprintf (", "); } while (0)
679 
680 
681 #define STRUCT(struct, elem, print)					\
682 	do {								\
683 		COMMA ();						\
684 		if (m.struct.elem##_length < 0 ||			\
685 		    m.struct.elem##_offset < sizeof m.struct ||		\
686 		    m.struct.elem##_offset + m.struct.elem##_length > len) \
687 		{							\
688 			tprintf (#elem "_length=%ld, " #elem "_offset=%ld",\
689 				m.struct.elem##_length,			\
690 				m.struct.elem##_offset);		\
691 		}							\
692 		else {							\
693 			tprintf (#elem "=");				\
694 			print (tcp,					\
695 				 addr + m.struct.elem##_offset,		\
696 				 m.struct.elem##_length);		\
697 		}							\
698 	}								\
699 	while (0)
700 
701 #define ADDR(struct, elem) STRUCT (struct, elem, printstr)
702 
703 	switch (m.type) {
704 #ifdef T_CONN_REQ
705 	    case T_CONN_REQ:	/* connect request   */
706 		GET (T_CONN_REQ, conn_req);
707 		ADDR (conn_req, DEST);
708 		ADDR (conn_req, OPT);
709 		break;
710 #endif
711 #ifdef T_CONN_RES
712 	    case T_CONN_RES:	/* connect response   */
713 		GET (T_CONN_RES, conn_res);
714 #ifdef HAVE_STRUCT_T_CONN_RES_QUEUE_PTR
715 		COMMA ();
716 		tprintf ("QUEUE=%p", m.conn_res.QUEUE_ptr);
717 #elif defined HAVE_STRUCT_T_CONN_RES_ACCEPTOR_ID
718 		COMMA ();
719 		tprintf ("ACCEPTOR=%#lx", m.conn_res.ACCEPTOR_id);
720 #endif
721 		ADDR (conn_res, OPT);
722 		COMMA ();
723 		tprintf ("SEQ=%ld", m.conn_res.SEQ_number);
724 		break;
725 #endif
726 #ifdef T_DISCON_REQ
727 	    case T_DISCON_REQ:	/* disconnect request */
728 		GET (T_DISCON_REQ, discon_req);
729 		COMMA ();
730 		tprintf ("SEQ=%ld", m.discon_req.SEQ_number);
731 		break;
732 #endif
733 #ifdef T_DATA_REQ
734 	    case T_DATA_REQ:	/* data request       */
735 		GET (T_DATA_REQ, data_req);
736 		COMMA ();
737 		tprintf ("MORE=%ld", m.data_req.MORE_flag);
738 		break;
739 #endif
740 #ifdef T_EXDATA_REQ
741 	    case T_EXDATA_REQ:	/* expedited data req */
742 		GET (T_EXDATA_REQ, exdata_req);
743 		COMMA ();
744 		tprintf ("MORE=%ld", m.exdata_req.MORE_flag);
745 		break;
746 #endif
747 #ifdef T_INFO_REQ
748 	    case T_INFO_REQ:	/* information req    */
749 		GET (T_INFO_REQ, info_req);
750 		break;
751 #endif
752 #ifdef T_BIND_REQ
753 	    case T_BIND_REQ:	/* bind request       */
754 #ifdef O_T_BIND_REQ
755 	    case O_T_BIND_REQ:	/* Ugly xti/tli hack */
756 #endif
757 		GET (T_BIND_REQ, bind_req);
758 		ADDR (bind_req, ADDR);
759 		COMMA ();
760 		tprintf ("CONIND=%ld", m.bind_req.CONIND_number);
761 		break;
762 #endif
763 #ifdef T_UNBIND_REQ
764 	    case T_UNBIND_REQ:	/* unbind request     */
765 		GET (T_UNBIND_REQ, unbind_req);
766 		break;
767 #endif
768 #ifdef T_UNITDATA_REQ
769 	    case T_UNITDATA_REQ:	/* unitdata requset   */
770 		GET (T_UNITDATA_REQ, unitdata_req);
771 		ADDR (unitdata_req, DEST);
772 		ADDR (unitdata_req, OPT);
773 		break;
774 #endif
775 #ifdef T_OPTMGMT_REQ
776 	    case T_OPTMGMT_REQ:	/* manage opt req     */
777 		GET (T_OPTMGMT_REQ, optmgmt_req);
778 		COMMA ();
779 		tprintf ("MGMT=");
780 		printflags (transport_user_flags, m.optmgmt_req.MGMT_flags,
781 			    "T_???");
782 		STRUCT (optmgmt_req, OPT, print_optmgmt);
783 		break;
784 #endif
785 #ifdef T_ORDREL_REQ
786 	    case T_ORDREL_REQ:	/* orderly rel req    */
787 		GET (T_ORDREL_REQ, ordrel_req);
788 		break;
789 #endif
790 #ifdef T_CONN_IND
791 	    case T_CONN_IND:	/* connect indication */
792 		GET (T_CONN_IND, conn_ind);
793 		ADDR (conn_ind, SRC);
794 		ADDR (conn_ind, OPT);
795 		tprintf (", SEQ=%ld", m.conn_ind.SEQ_number);
796 		break;
797 #endif
798 #ifdef T_CONN_CON
799 	    case T_CONN_CON:	/* connect corfirm    */
800 		GET (T_CONN_CON, conn_con);
801 		ADDR (conn_con, RES);
802 		ADDR (conn_con, OPT);
803 		break;
804 #endif
805 #ifdef T_DISCON_IND
806 	    case T_DISCON_IND:	/* discon indication  */
807 		GET (T_DISCON_IND, discon_ind);
808 		COMMA ();
809 		tprintf ("DISCON=%ld, SEQ=%ld",
810 			 m.discon_ind.DISCON_reason, m.discon_ind.SEQ_number);
811 		break;
812 #endif
813 #ifdef T_DATA_IND
814 	    case T_DATA_IND:	/* data indication    */
815 		GET (T_DATA_IND, data_ind);
816 		COMMA ();
817 		tprintf ("MORE=%ld", m.data_ind.MORE_flag);
818 		break;
819 #endif
820 #ifdef T_EXDATA_IND
821 	    case T_EXDATA_IND:	/* expedited data ind */
822 		GET (T_EXDATA_IND, exdata_ind);
823 		COMMA ();
824 		tprintf ("MORE=%ld", m.exdata_ind.MORE_flag);
825 		break;
826 #endif
827 #ifdef T_INFO_ACK
828 	    case T_INFO_ACK:	/* info ack           */
829 		GET (T_INFO_ACK, info_ack);
830 		COMMA ();
831 		tprintf ("TSDU=%ld, ETSDU=%ld, CDATA=%ld, DDATA=%ld, "
832 			 "ADDR=%ld, OPT=%ld, TIDU=%ld, SERV=",
833 			 m.info_ack.TSDU_size, m.info_ack.ETSDU_size,
834 			 m.info_ack.CDATA_size, m.info_ack.DDATA_size,
835 			 m.info_ack.ADDR_size, m.info_ack.OPT_size,
836 			 m.info_ack.TIDU_size);
837 		printxval (service_type, m.info_ack.SERV_type, "T_???");
838 		tprintf (", CURRENT=");
839 		printxval (ts_state, m.info_ack.CURRENT_state, "TS_???");
840 		tprintf (", PROVIDER=");
841 		printflags (provider_flags, m.info_ack.PROVIDER_flag, "???");
842 		break;
843 #endif
844 #ifdef T_BIND_ACK
845 	    case T_BIND_ACK:	/* bind ack           */
846 		GET (T_BIND_ACK, bind_ack);
847 		ADDR (bind_ack, ADDR);
848 		tprintf (", CONIND=%ld", m.bind_ack.CONIND_number);
849 		break;
850 #endif
851 #ifdef T_ERROR_ACK
852 	    case T_ERROR_ACK:	/* error ack          */
853 		GET (T_ERROR_ACK, error_ack);
854 		COMMA ();
855 		tprintf ("ERROR=");
856 		printxval (transport_user_options,
857 			   m.error_ack.ERROR_prim, "TI_???");
858 		tprintf (", TLI=");
859 		printxval (tli_errors, m.error_ack.TLI_error, "T???");
860 		tprintf ("UNIX=%s", strerror (m.error_ack.UNIX_error));
861 		break;
862 #endif
863 #ifdef T_OK_ACK
864 	    case T_OK_ACK:	/* ok ack             */
865 		GET (T_OK_ACK, ok_ack);
866 		COMMA ();
867 		tprintf ("CORRECT=");
868 		printxval (transport_user_options,
869 			   m.ok_ack.CORRECT_prim, "TI_???");
870 		break;
871 #endif
872 #ifdef T_UNITDATA_IND
873 	    case T_UNITDATA_IND:	/* unitdata ind       */
874 		GET (T_UNITDATA_IND, unitdata_ind);
875 		ADDR (unitdata_ind, SRC);
876 		ADDR (unitdata_ind, OPT);
877 		break;
878 #endif
879 #ifdef T_UDERROR_IND
880 	    case T_UDERROR_IND:	/* unitdata error ind */
881 		GET (T_UDERROR_IND, uderror_ind);
882 		ADDR (uderror_ind, DEST);
883 		ADDR (uderror_ind, OPT);
884 		tprintf (", ERROR=%ld", m.uderror_ind.ERROR_type);
885 		break;
886 #endif
887 #ifdef T_OPTMGMT_ACK
888 	    case T_OPTMGMT_ACK:	/* manage opt ack     */
889 		GET (T_OPTMGMT_ACK, optmgmt_ack);
890 		COMMA ();
891 		tprintf ("MGMT=");
892 		printflags (transport_user_flags, m.optmgmt_ack.MGMT_flags,
893 			    "T_???");
894 		STRUCT (optmgmt_ack, OPT, print_optmgmt);
895 		break;
896 #endif
897 #ifdef T_ORDREL_IND
898 	case T_ORDREL_IND:	/* orderly rel ind    */
899 		GET (T_ORDREL_IND, ordrel_ind);
900 		break;
901 #endif
902 #ifdef T_ADDR_REQ
903 	    case T_ADDR_REQ:	/* address req        */
904 		GET (T_ADDR_REQ, addr_req);
905 		break;
906 #endif
907 #ifdef T_ADDR_ACK
908 	    case T_ADDR_ACK:	/* address response   */
909 		GET (T_ADDR_ACK, addr_ack);
910 		ADDR (addr_ack, LOCADDR);
911 		ADDR (addr_ack, REMADDR);
912 		break;
913 #endif
914 	    default:
915 	    dump:
916 		c = -1;
917 		printstr(tcp, addr, len);
918 		break;
919 	}
920 
921 	if (c >= 0) tprintf ("}");
922 
923 #undef ADDR
924 #undef COMMA
925 #undef STRUCT
926 
927 	return 0;
928 }
929 
930 
931 #endif /* TI_BIND */
932 
933 
934 static int
internal_stream_ioctl(tcp,arg)935 internal_stream_ioctl(tcp, arg)
936 struct tcb *tcp;
937 int arg;
938 {
939 	struct strioctl si;
940 	struct ioctlent *iop;
941 	int in_and_out;
942 	int timod = 0;
943 #ifdef SI_GETUDATA
944 	struct si_udata udata;
945 #endif /* SI_GETUDATA */
946 
947 	if (!arg)
948 		return 0;
949 	if (umove(tcp, arg, &si) < 0) {
950 		if (entering(tcp))
951 			tprintf(", {...}");
952 		return 1;
953 	}
954 	if (entering(tcp)) {
955 		iop = ioctl_lookup(si.ic_cmd);
956 		if (iop) {
957 			tprintf(", {ic_cmd=%s", iop->symbol);
958 			while ((iop = ioctl_next_match(iop)))
959 				tprintf(" or %s", iop->symbol);
960 		} else
961 			tprintf(", {ic_cmd=%#x", si.ic_cmd);
962 		if (si.ic_timout == INFTIM)
963 			tprintf(", ic_timout=INFTIM, ");
964 		else
965 			tprintf(" ic_timout=%d, ", si.ic_timout);
966 	}
967 	in_and_out = 1;
968 	switch (si.ic_cmd) {
969 #ifdef SI_GETUDATA
970 	case SI_GETUDATA:
971 		in_and_out = 0;
972 		break;
973 #endif /* SI_GETUDATA */
974 	}
975 	if (in_and_out) {
976 		if (entering(tcp))
977 			tprintf("/* in */ ");
978 		else
979 			tprintf(", /* out */ ");
980 	}
981 	if (in_and_out || entering(tcp))
982 		tprintf("ic_len=%d, ic_dp=", si.ic_len);
983 	switch (si.ic_cmd) {
984 #ifdef TI_BIND
985 	case TI_BIND:
986 		/* in T_BIND_REQ, out T_BIND_ACK */
987 		++timod;
988 		if (entering(tcp)) {
989 			print_transport_message (tcp,
990 						 T_BIND_REQ,
991 						 si.ic_dp, si.ic_len);
992 		}
993 		else {
994 			print_transport_message (tcp,
995 						 T_BIND_ACK,
996 						 si.ic_dp, si.ic_len);
997 		}
998 		break;
999 #endif /* TI_BIND */
1000 #ifdef TI_UNBIND
1001 	case TI_UNBIND:
1002 		/* in T_UNBIND_REQ, out T_OK_ACK */
1003 		++timod;
1004 		if (entering(tcp)) {
1005 			print_transport_message (tcp,
1006 						 T_UNBIND_REQ,
1007 						 si.ic_dp, si.ic_len);
1008 		}
1009 		else {
1010 			print_transport_message (tcp,
1011 						 T_OK_ACK,
1012 						 si.ic_dp, si.ic_len);
1013 		}
1014 		break;
1015 #endif /* TI_UNBIND */
1016 #ifdef TI_GETINFO
1017 	case TI_GETINFO:
1018 		/* in T_INFO_REQ, out T_INFO_ACK */
1019 		++timod;
1020 		if (entering(tcp)) {
1021 			print_transport_message (tcp,
1022 						 T_INFO_REQ,
1023 						 si.ic_dp, si.ic_len);
1024 		}
1025 		else {
1026 			print_transport_message (tcp,
1027 						 T_INFO_ACK,
1028 						 si.ic_dp, si.ic_len);
1029 		}
1030 		break;
1031 #endif /* TI_GETINFO */
1032 #ifdef TI_OPTMGMT
1033 	case TI_OPTMGMT:
1034 		/* in T_OPTMGMT_REQ, out T_OPTMGMT_ACK */
1035 		++timod;
1036 		if (entering(tcp)) {
1037 			print_transport_message (tcp,
1038 						 T_OPTMGMT_REQ,
1039 						 si.ic_dp, si.ic_len);
1040 		}
1041 		else {
1042 			print_transport_message (tcp,
1043 						 T_OPTMGMT_ACK,
1044 						 si.ic_dp, si.ic_len);
1045 		}
1046 		break;
1047 #endif /* TI_OPTMGMT */
1048 #ifdef SI_GETUDATA
1049 	case SI_GETUDATA:
1050 		if (entering(tcp))
1051 			break;
1052 #if 0
1053 		tprintf("struct si_udata ");
1054 #endif
1055 		if (umove(tcp, (int) si.ic_dp, &udata) < 0)
1056 			tprintf("{...}");
1057 		else {
1058 			tprintf("{tidusize=%d, addrsize=%d, ",
1059 				udata.tidusize, udata.addrsize);
1060 			tprintf("optsize=%d, etsdusize=%d, ",
1061 				udata.optsize, udata.etsdusize);
1062 			tprintf("servtype=%d, so_state=%d, ",
1063 				udata.servtype, udata.so_state);
1064 			tprintf("so_options=%d", udata.so_options);
1065 #if 0
1066 			tprintf(", tsdusize=%d", udata.tsdusize);
1067 #endif
1068 			tprintf("}");
1069 		}
1070 		break;
1071 #endif /* SI_GETUDATA */
1072 	default:
1073 		printstr(tcp, (long) si.ic_dp, si.ic_len);
1074 		break;
1075 	}
1076 	if (exiting(tcp)) {
1077 		tprintf("}");
1078 		if (timod && tcp->u_rval) {
1079 			tcp->auxstr = xlookup (tli_errors, tcp->u_rval);
1080 			return RVAL_STR + 1;
1081 		}
1082 	}
1083 
1084 	return 1;
1085 }
1086 
1087 int
stream_ioctl(tcp,code,arg)1088 stream_ioctl(tcp, code, arg)
1089 struct tcb *tcp;
1090 int code, arg;
1091 {
1092 #ifdef I_LIST
1093 	int i;
1094 #endif
1095 	int val;
1096 #ifdef I_FLUSHBAND
1097 	struct bandinfo bi;
1098 #endif
1099 	struct strpeek sp;
1100 	struct strfdinsert sfi;
1101 	struct strrecvfd srf;
1102 #ifdef I_LIST
1103 	struct str_list sl;
1104 #endif
1105 
1106 	/* I_STR is a special case because the data is read & written. */
1107 	if (code == I_STR)
1108 		return internal_stream_ioctl(tcp, arg);
1109 	if (entering(tcp))
1110 		return 0;
1111 
1112 	switch (code) {
1113 	case I_PUSH:
1114 	case I_LOOK:
1115 	case I_FIND:
1116 		/* arg is a string */
1117 		tprintf(", ");
1118 		printpath(tcp, arg);
1119 		return 1;
1120 	case I_POP:
1121 		/* doesn't take an argument */
1122 		return 1;
1123 	case I_FLUSH:
1124 		/* argument is an option */
1125 		tprintf(", ");
1126 		printxval(stream_flush_options, arg, "FLUSH???");
1127 		return 1;
1128 #ifdef I_FLUSHBAND
1129 	case I_FLUSHBAND:
1130 		/* argument is a pointer to a bandinfo struct */
1131 		if (umove(tcp, arg, &bi) < 0)
1132 			tprintf(", {...}");
1133 		else {
1134 			tprintf(", {bi_pri=%d, bi_flag=", bi.bi_pri);
1135 			printflags(stream_flush_options, bi.bi_flag, "FLUSH???");
1136 			tprintf("}");
1137 		}
1138 		return 1;
1139 #endif /* I_FLUSHBAND */
1140 	case I_SETSIG:
1141 		/* argument is a set of flags */
1142 		tprintf(", ");
1143 		printflags(stream_setsig_flags, arg, "S_???");
1144 		return 1;
1145 	case I_GETSIG:
1146 		/* argument is a pointer to a set of flags */
1147 		if (syserror(tcp))
1148 			return 0;
1149 		tprintf(", [");
1150 		if (umove(tcp, arg, &val) < 0)
1151 			tprintf("?");
1152 		else
1153 			printflags(stream_setsig_flags, val, "S_???");
1154 		tprintf("]");
1155 		return 1;
1156 	case I_PEEK:
1157 		/* argument is a pointer to a strpeek structure */
1158 		if (syserror(tcp) || !arg)
1159 			return 0;
1160 		if (umove(tcp, arg, &sp) < 0) {
1161 			tprintf(", {...}");
1162 			return 1;
1163 		}
1164 		tprintf(", {ctlbuf=");
1165 		printstrbuf(tcp, &sp.ctlbuf, 1);
1166 		tprintf(", databuf=");
1167 		printstrbuf(tcp, &sp.databuf, 1);
1168 		tprintf(", flags=");
1169 		printflags(msgflags, sp.flags, "RS_???");
1170 		tprintf("}");
1171 		return 1;
1172 	case I_SRDOPT:
1173 		/* argument is an option with flags */
1174 		tprintf(", ");
1175 		printxval(stream_read_options, arg & RMODEMASK, "R???");
1176 		addflags(stream_read_flags, arg & ~RMODEMASK);
1177 		return 1;
1178 	case I_GRDOPT:
1179 		/* argument is an pointer to an option with flags */
1180 		if (syserror(tcp))
1181 			return 0;
1182 		tprintf(", [");
1183 		if (umove(tcp, arg, &val) < 0)
1184 			tprintf("?");
1185 		else {
1186 			printxval(stream_read_options,
1187 				  arg & RMODEMASK, "R???");
1188 			addflags(stream_read_flags, arg & ~RMODEMASK);
1189 		}
1190 		tprintf("]");
1191 		return 1;
1192 	case I_NREAD:
1193 #ifdef I_GETBAND
1194 	case I_GETBAND:
1195 #endif
1196 #ifdef I_SETCLTIME
1197 	case I_SETCLTIME:
1198 #endif
1199 #ifdef I_GETCLTIME
1200 	case I_GETCLTIME:
1201 #endif
1202 		/* argument is a pointer to a decimal integer */
1203 		if (syserror(tcp))
1204 			return 0;
1205 		tprintf(", ");
1206 		printnum(tcp, arg, "%d");
1207 		return 1;
1208 	case I_FDINSERT:
1209 		/* argument is a pointer to a strfdinsert structure */
1210 		if (syserror(tcp) || !arg)
1211 			return 0;
1212 		if (umove(tcp, arg, &sfi) < 0) {
1213 			tprintf(", {...}");
1214 			return 1;
1215 		}
1216 		tprintf(", {ctlbuf=");
1217 		printstrbuf(tcp, &sfi.ctlbuf, 1);
1218 		tprintf(", databuf=");
1219 		printstrbuf(tcp, &sfi.databuf, 1);
1220 		tprintf(", flags=");
1221 		printflags(msgflags, sfi.flags, "RS_???");
1222 		tprintf(", filedes=%d, offset=%d}", sfi.fildes, sfi.offset);
1223 		return 1;
1224 #ifdef I_SWROPT
1225 	case I_SWROPT:
1226 		/* argument is a set of flags */
1227 		tprintf(", ");
1228 		printflags(stream_write_flags, arg, "SND???");
1229 		return 1;
1230 #endif /* I_SWROPT */
1231 #ifdef I_GWROPT
1232 	case I_GWROPT:
1233 		/* argument is an pointer to an option with flags */
1234 		if (syserror(tcp))
1235 			return 0;
1236 		tprintf(", [");
1237 		if (umove(tcp, arg, &val) < 0)
1238 			tprintf("?");
1239 		else
1240 			printflags(stream_write_flags, arg, "SND???");
1241 		tprintf("]");
1242 		return 1;
1243 #endif /* I_GWROPT */
1244 	case I_SENDFD:
1245 #ifdef I_CKBAND
1246 	case I_CKBAND:
1247 #endif
1248 #ifdef I_CANPUT
1249 	case I_CANPUT:
1250 #endif
1251 	case I_LINK:
1252 	case I_UNLINK:
1253 	case I_PLINK:
1254 	case I_PUNLINK:
1255 		/* argument is a decimal integer */
1256 		tprintf(", %d", arg);
1257 		return 1;
1258 	case I_RECVFD:
1259 		/* argument is a pointer to a strrecvfd structure */
1260 		if (syserror(tcp) || !arg)
1261 			return 0;
1262 		if (umove(tcp, arg, &srf) < 0) {
1263 			tprintf(", {...}");
1264 			return 1;
1265 		}
1266 		tprintf(", {fd=%d, uid=%lu, gid=%lu}", srf.fd,
1267 			(unsigned long) srf.uid, (unsigned long) srf.gid);
1268 		return 1;
1269 #ifdef I_LIST
1270 	case I_LIST:
1271 		if (syserror(tcp))
1272 			return 0;
1273 		if (arg == 0) {
1274 			tprintf(", NULL");
1275 			return 1;
1276 		}
1277 		if (umove(tcp, arg, &sl) < 0) {
1278 			tprintf(", {...}");
1279 			return 1;
1280 		}
1281 		tprintf(", {sl_nmods=%d, sl_modlist=[", sl.sl_nmods);
1282 		for (i = 0; i < tcp->u_rval; i++) {
1283 			if (i)
1284 				tprintf(", ");
1285 			printpath(tcp, (int) sl.sl_modlist[i].l_name);
1286 		}
1287 		tprintf("]}");
1288 		return 1;
1289 #endif /* I_LIST */
1290 #ifdef I_ATMARK
1291 	case I_ATMARK:
1292 		tprintf(", ");
1293 		printxval(stream_atmark_options, arg, "???MARK");
1294 		return 1;
1295 #endif /* I_ATMARK */
1296 	default:
1297 		return 0;
1298 	}
1299 }
1300 
1301 #endif /* !LINUX && !FREEBSD */
1302 
1303 #endif /* HAVE_SYS_STREAM_H || LINUX || FREEBSD */
1304