blob: 4abf861b684b16bdb742b174505444660c0c913e [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
2 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00003 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00004 * 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$
29 */
30
31#include "defs.h"
32
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000033#if defined(HAVE_SYS_STREAM_H) || defined(linux) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000034
Wichert Akkermand4d8e921999-04-18 23:30:29 +000035#if defined(linux)
Pavel Machek245a6ac2000-02-01 16:12:33 +000036#ifdef HAVE_SYS_POLL_H
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000037#include <sys/poll.h>
Pavel Machek245a6ac2000-02-01 16:12:33 +000038#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000039
40#define RS_HIPRI 1
41struct strbuf {
42 int maxlen; /* no. of bytes in buffer */
43 int len; /* no. of bytes returned */
44 char *buf; /* pointer to data */
45};
46#define MORECTL 1
47#define MOREDATA 2
48
Wichert Akkermand4d8e921999-04-18 23:30:29 +000049#else /* linux */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000050
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000051#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000052#include <stropts.h>
53#include <poll.h>
54#include <sys/conf.h>
55#include <sys/stream.h>
56#include <sys/tihdr.h>
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000057#else /* FREEBSD */
58#include <poll.h>
59#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000060
Wichert Akkermand4d8e921999-04-18 23:30:29 +000061#endif /* linux */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000062
63#ifdef HAVE_SYS_TIUSER_H
64#include <sys/tiuser.h>
65#include <sys/sockmod.h>
66#include <sys/timod.h>
67#endif /* HAVE_SYS_TIUSER_H */
68
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000069#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000070static struct xlat msgflags[] = {
71 { RS_HIPRI, "RS_HIPRI" },
72 { 0, NULL },
73};
74
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000075
76static void
77printstrbuf(tcp, sbp, getting)
78struct tcb *tcp;
79struct strbuf *sbp;
80int getting;
81{
82 if (sbp->maxlen == -1 && getting)
83 tprintf("{maxlen=-1}");
84 else {
85 tprintf("{");
86 if (getting)
87 tprintf("maxlen=%d, ", sbp->maxlen);
88 tprintf("len=%d, buf=", sbp->len);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +000089 printstr(tcp, (unsigned long) sbp->buf, sbp->len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000090 tprintf("}");
91 }
92}
93
94static void
95printstrbufarg(tcp, arg, getting)
96struct tcb *tcp;
97int arg;
98int getting;
99{
100 struct strbuf buf;
101
102 if (arg == 0)
103 tprintf("NULL");
104 else if (umove(tcp, arg, &buf) < 0)
105 tprintf("{...}");
106 else
107 printstrbuf(tcp, &buf, getting);
108 tprintf(", ");
109}
110
111int
112sys_putmsg(tcp)
113struct tcb *tcp;
114{
115 int i;
116
117 if (entering(tcp)) {
118 /* fd */
119 tprintf("%ld, ", tcp->u_arg[0]);
120 /* control and data */
121 for (i = 1; i < 3; i++)
122 printstrbufarg(tcp, tcp->u_arg[i], 0);
123 /* flags */
124 if (!printflags(msgflags, tcp->u_arg[3]))
125 tprintf("0");
126 }
127 return 0;
128}
129
130int
131sys_getmsg(tcp)
132struct tcb *tcp;
133{
134 int i, flags;
135
136 if (entering(tcp)) {
137 /* fd */
138 tprintf("%lu, ", tcp->u_arg[0]);
139 } else {
140 if (syserror(tcp)) {
141 tprintf("%#lx, %#lx, %#lx",
142 tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
143 return 0;
144 }
145 /* control and data */
146 for (i = 1; i < 3; i++)
147 printstrbufarg(tcp, tcp->u_arg[i], 1);
148 /* pointer to flags */
149 if (tcp->u_arg[3] == 0)
150 tprintf("NULL");
151 else if (umove(tcp, tcp->u_arg[3], &flags) < 0)
152 tprintf("[?]");
153 else {
154 tprintf("[");
155 if (!printflags(msgflags, flags))
156 tprintf("0");
157 tprintf("]");
158 }
159 /* decode return value */
160 switch (tcp->u_rval) {
161 case MORECTL:
162 tcp->auxstr = "MORECTL";
163 break;
164 case MORECTL|MOREDATA:
165 tcp->auxstr = "MORECTL|MOREDATA";
166 break;
167 case MOREDATA:
168 tcp->auxstr = "MORECTL";
169 break;
170 default:
171 tcp->auxstr = NULL;
172 break;
173 }
174 }
175 return RVAL_HEX | RVAL_STR;
176}
177
178#ifdef HAVE_PUTPMSG
179
180static struct xlat pmsgflags[] = {
181 { MSG_HIPRI, "MSG_HIPRI" },
182 { MSG_ANY, "MSG_ANY" },
183 { MSG_BAND, "MSG_BAND" },
184 { 0, NULL },
185};
186
187int
188sys_putpmsg(tcp)
189struct tcb *tcp;
190{
191 int i;
192
193 if (entering(tcp)) {
194 /* fd */
195 tprintf("%ld, ", tcp->u_arg[0]);
196 /* control and data */
197 for (i = 1; i < 3; i++)
198 printstrbufarg(tcp, tcp->u_arg[i], 0);
199 /* band */
200 tprintf("%ld, ", tcp->u_arg[3]);
201 /* flags */
202 if (!printflags(pmsgflags, tcp->u_arg[4]))
203 tprintf("0");
204 }
205 return 0;
206}
207
208int
209sys_getpmsg(tcp)
210struct tcb *tcp;
211{
212 int i, flags;
213
214 if (entering(tcp)) {
215 /* fd */
216 tprintf("%lu, ", tcp->u_arg[0]);
217 } else {
218 if (syserror(tcp)) {
219 tprintf("%#lx, %#lx, %#lx, %#lx", tcp->u_arg[1],
220 tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[4]);
221 return 0;
222 }
223 /* control and data */
224 for (i = 1; i < 3; i++)
225 printstrbufarg(tcp, tcp->u_arg[i], 1);
226 /* pointer to band */
227 printnum(tcp, tcp->u_arg[3], "%d");
Wichert Akkerman906dade1999-11-26 09:18:37 +0000228 tprintf(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000229 /* pointer to flags */
230 if (tcp->u_arg[4] == 0)
231 tprintf("NULL");
232 else if (umove(tcp, tcp->u_arg[4], &flags) < 0)
233 tprintf("[?]");
234 else {
235 tprintf("[");
236 if (!printflags(pmsgflags, flags))
237 tprintf("0");
238 tprintf("]");
239 }
240 /* decode return value */
241 switch (tcp->u_rval) {
242 case MORECTL:
243 tcp->auxstr = "MORECTL";
244 break;
245 case MORECTL|MOREDATA:
246 tcp->auxstr = "MORECTL|MOREDATA";
247 break;
248 case MOREDATA:
249 tcp->auxstr = "MORECTL";
250 break;
251 default:
252 tcp->auxstr = NULL;
253 break;
254 }
255 }
256 return RVAL_HEX | RVAL_STR;
257}
258
259#endif /* HAVE_PUTPMSG */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000260#endif /* !FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000261
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000262
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000263#ifdef HAVE_SYS_POLL_H
264
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000265static struct xlat pollflags[] = {
Pavel Machek245a6ac2000-02-01 16:12:33 +0000266#ifdef POLLIN
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000267 { POLLIN, "POLLIN" },
268 { POLLPRI, "POLLPRI" },
269 { POLLOUT, "POLLOUT" },
270#ifdef POLLRDNORM
271 { POLLRDNORM, "POLLRDNORM" },
272#endif
273#ifdef POLLWRNORM
274 { POLLWRNORM, "POLLWRNORM" },
275#endif
276#ifdef POLLRDBAND
277 { POLLRDBAND, "POLLRDBAND" },
278#endif
279#ifdef POLLWRBAND
280 { POLLWRBAND, "POLLWRBAND" },
281#endif
282 { POLLERR, "POLLERR" },
283 { POLLHUP, "POLLHUP" },
284 { POLLNVAL, "POLLNVAL" },
Pavel Machek245a6ac2000-02-01 16:12:33 +0000285#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000286 { 0, NULL },
287};
288
289int
290sys_poll(tcp)
291struct tcb *tcp;
292{
293 struct pollfd *pollp;
294
295 if (exiting(tcp)) {
296 int i;
297 int nfds = tcp->u_arg[1];
298
299 if (nfds <= 0) {
300 tprintf("%#lx, %d, %ld\n",
301 tcp->u_arg[0], nfds, tcp->u_arg[2]);
302 return 0;
303 }
304 pollp = (struct pollfd *) malloc(nfds * sizeof(*pollp));
305 if (pollp == NULL) {
306 fprintf(stderr, "sys_poll: no memory\n");
307 tprintf("%#lx, %d, %ld",
308 tcp->u_arg[0], nfds, tcp->u_arg[2]);
309 return 0;
310 }
311 if (umoven(tcp, tcp->u_arg[0],
312 (nfds * sizeof(*pollp)), (char *) pollp) < 0) {
313 tprintf("%#lx", tcp->u_arg[0]);
314 }
315 else {
316 tprintf("[");
317 for (i = 0; i < nfds; i++) {
318 if (i)
319 tprintf(", ");
320 if (pollp[i].fd < 0) {
321 tprintf("{fd=%d}", pollp[i].fd);
322 continue;
323 }
324 tprintf("{fd=%d, events=", pollp[i].fd);
325 if (!printflags(pollflags, pollp[i].events))
326 tprintf("0");
327 if (!syserror(tcp) && pollp[i].revents) {
328 tprintf(", revents=");
329 if (!printflags(pollflags,
330 pollp[i].revents))
331 tprintf("0");
332 }
333 tprintf("}");
334 }
335 tprintf("]");
336 }
337 tprintf(", %d, ", nfds);
338#ifdef INFTIM
339 if (tcp->u_arg[2] == INFTIM)
340 tprintf("INFTIM");
341 else
342#endif
343 tprintf("%ld", tcp->u_arg[2]);
344 free(pollp);
345 }
346 return 0;
347}
348
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000349#else /* !HAVE_SYS_POLL_H */
350int
351sys_poll(tcp)
352struct tcb *tcp;
353{
354 return 0;
355}
356#endif
357
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000358#if !defined(linux) && !defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000359
360static struct xlat stream_flush_options[] = {
361 { FLUSHR, "FLUSHR" },
362 { FLUSHW, "FLUSHW" },
363 { FLUSHRW, "FLUSHRW" },
364#ifdef FLUSHBAND
365 { FLUSHBAND, "FLUSHBAND" },
366#endif
367 { 0, NULL },
368};
369
370static struct xlat stream_setsig_flags[] = {
371 { S_INPUT, "S_INPUT" },
372 { S_HIPRI, "S_HIPRI" },
373 { S_OUTPUT, "S_OUTPUT" },
374 { S_MSG, "S_MSG" },
375#ifdef S_ERROR
376 { S_ERROR, "S_ERROR" },
377#endif
378#ifdef S_HANGUP
379 { S_HANGUP, "S_HANGUP" },
380#endif
381#ifdef S_RDNORM
382 { S_RDNORM, "S_RDNORM" },
383#endif
384#ifdef S_WRNORM
385 { S_WRNORM, "S_WRNORM" },
386#endif
387#ifdef S_RDBAND
388 { S_RDBAND, "S_RDBAND" },
389#endif
390#ifdef S_WRBAND
391 { S_WRBAND, "S_WRBAND" },
392#endif
393#ifdef S_BANDURG
394 { S_BANDURG, "S_BANDURG" },
395#endif
396 { 0, NULL },
397};
398
399static struct xlat stream_read_options[] = {
400 { RNORM, "RNORM" },
401 { RMSGD, "RMSGD" },
402 { RMSGN, "RMSGN" },
403 { 0, NULL },
404};
405
406static struct xlat stream_read_flags[] = {
407#ifdef RPROTDAT
408 { RPROTDAT, "RPROTDAT" },
409#endif
410#ifdef RPROTDIS
411 { RPROTDIS, "RPROTDIS" },
412#endif
413#ifdef RPROTNORM
414 { RPROTNORM, "RPROTNORM" },
415#endif
416 { 0, NULL },
417};
418
419#ifndef RMODEMASK
420#define RMODEMASK (~0)
421#endif
422
423#ifdef I_SWROPT
424static struct xlat stream_write_flags[] = {
425 { SNDZERO, "SNDZERO" },
426 { SNDPIPE, "SNDPIPE" },
427 { 0, NULL },
428};
429#endif /* I_SWROPT */
430
431#ifdef I_ATMARK
432static struct xlat stream_atmark_options[] = {
433 { ANYMARK, "ANYMARK" },
434 { LASTMARK, "LASTMARK" },
435 { 0, NULL },
436};
437#endif /* I_ATMARK */
438
439#ifdef TI_BIND
440static struct xlat transport_user_options[] = {
441 { T_CONN_REQ, "T_CONN_REQ" },
442 { T_CONN_RES, "T_CONN_RES" },
443 { T_DISCON_REQ, "T_DISCON_REQ" },
444 { T_DATA_REQ, "T_DATA_REQ" },
445 { T_EXDATA_REQ, "T_EXDATA_REQ" },
446 { T_INFO_REQ, "T_INFO_REQ" },
447 { T_BIND_REQ, "T_BIND_REQ" },
448 { T_UNBIND_REQ, "T_UNBIND_REQ" },
449 { T_UNITDATA_REQ,"T_UNITDATA_REQ"},
450 { T_OPTMGMT_REQ,"T_OPTMGMT_REQ" },
451 { T_ORDREL_REQ, "T_ORDREL_REQ" },
452 { 0, NULL },
453};
454
455static struct xlat transport_provider_options[] = {
456 { T_CONN_IND, "T_CONN_IND" },
457 { T_CONN_CON, "T_CONN_CON" },
458 { T_DISCON_IND, "T_DISCON_IND" },
459 { T_DATA_IND, "T_DATA_IND" },
460 { T_EXDATA_IND, "T_EXDATA_IND" },
461 { T_INFO_ACK, "T_INFO_ACK" },
462 { T_BIND_ACK, "T_BIND_ACK" },
463 { T_ERROR_ACK, "T_ERROR_ACK" },
464 { T_OK_ACK, "T_OK_ACK" },
465 { T_UNITDATA_IND,"T_UNITDATA_IND"},
466 { T_UDERROR_IND,"T_UDERROR_IND" },
467 { T_OPTMGMT_ACK,"T_OPTMGMT_ACK" },
468 { T_ORDREL_IND, "T_ORDREL_IND" },
469 { 0, NULL },
470};
471#endif /* TI_BIND */
472
473static int
474internal_stream_ioctl(tcp, arg)
475struct tcb *tcp;
476int arg;
477{
478 struct strioctl si;
479 char *name;
480 int in_and_out;
481#ifdef SI_GETUDATA
482 struct si_udata udata;
483#endif /* SI_GETUDATA */
484
485 if (!arg)
486 return 0;
487 if (umove(tcp, arg, &si) < 0) {
488 if (entering(tcp))
489 tprintf(", {...}");
490 return 1;
491 }
492 if (entering(tcp)) {
493 name = ioctl_lookup(si.ic_cmd);
494 if (name)
495 tprintf(", {ic_cmd=%s", name);
496 else
497 tprintf(", {ic_cmd=%#x", si.ic_cmd);
498 if (si.ic_timout == INFTIM)
499 tprintf(", ic_timout=INFTIM, ");
500 else
501 tprintf(" ic_timout=%d, ", si.ic_timout);
502 }
503 in_and_out = 1;
504 switch (si.ic_cmd) {
505#ifdef SI_GETUDATA
506 case SI_GETUDATA:
507 in_and_out = 0;
508 break;
509#endif /* SI_GETUDATA */
510 }
511 if (in_and_out) {
512 if (entering(tcp))
513 tprintf("/* in */ ");
514 else
515 tprintf(", /* out */ ");
516 }
517 if (in_and_out || entering(tcp))
518 tprintf("ic_len=%d, ic_dp=", si.ic_len);
519 switch (si.ic_cmd) {
520#ifdef TI_BIND
521 case TI_BIND:
522 /* in T_BIND_REQ, out T_BIND_ACK */
523 if (entering(tcp)) {
524 struct T_bind_req data;
525
526#if 0
527 tprintf("struct T_bind_req ");
528#endif
529 if (umove(tcp, (int) si.ic_dp, &data) < 0)
530 tprintf("{...}");
531 else {
532 tprintf("{PRIM_type=");
533 printxval(transport_user_options,
534 data.PRIM_type, "T_???");
535 tprintf(", ADDR_length=%ld, ADDR_offset=%ld",
536 data.ADDR_length, data.ADDR_offset);
537 tprintf(", CONIND_number=%ld}",
538 data.CONIND_number);
539 }
540 }
541 else {
542 struct T_bind_ack data;
543
544#if 0
545 tprintf("struct T_bind_ack ");
546#endif
547 if (umove(tcp, (int) si.ic_dp, &data) < 0)
548 tprintf("{...}");
549 else {
550 tprintf("[");
551 tprintf("{PRIM_type=");
552 printxval(transport_provider_options,
553 data.PRIM_type, "T_???");
554 tprintf(", ADDR_length=%ld, ADDR_offset=%ld",
555 data.ADDR_length, data.ADDR_offset);
556 tprintf(", CONIND_number=%ld}",
557 data.CONIND_number);
558 tprintf(", ");
559 printstr(tcp,
560 (int) si.ic_dp + data.ADDR_offset,
561 data.ADDR_length);
562 tprintf("]");
563 }
564 }
565 break;
566#endif /* TI_BIND */
567#if 0
568#ifdef TI_UNBIND
569 case TI_UNBIND:
570 /* in T_UNBIND_REQ, out T_OK_ACK */
571 break;
572#endif /* TI_UNBIND */
573#ifdef TI_GETINFO
574 case TI_GETINFO:
575 /* in T_INFO_REQ, out T_INFO_ACK */
576 break;
577#endif /* TI_GETINFO */
578#ifdef TI_OPTMGMT
579 case TI_OPTMGMT:
580 /* in T_OPTMGMT_REQ, out T_OPTMGMT_ACK */
581 break;
582#endif /* TI_OPTMGMT */
583#endif
584#ifdef SI_GETUDATA
585 case SI_GETUDATA:
586 if (entering(tcp))
587 break;
588#if 0
589 tprintf("struct si_udata ");
590#endif
591 if (umove(tcp, (int) si.ic_dp, &udata) < 0)
592 tprintf("{...}");
593 else {
594 tprintf("{tidusize=%d, addrsize=%d, ",
595 udata.tidusize, udata.addrsize);
596 tprintf("optsize=%d, etsdusize=%d, ",
597 udata.optsize, udata.etsdusize);
598 tprintf("servtype=%d, so_state=%d, ",
599 udata.servtype, udata.so_state);
600 tprintf("so_options=%d", udata.so_options);
601#if 0
602 tprintf(", tsdusize=%d", udata.tsdusize);
603#endif
604 tprintf("}");
605 }
606 break;
607#endif /* SI_GETUDATA */
608 default:
609 printstr(tcp, (int) si.ic_dp, si.ic_len);
610 break;
611 }
612 if (exiting(tcp))
613 tprintf("}");
614 return 1;
615}
616
617int
618stream_ioctl(tcp, code, arg)
619struct tcb *tcp;
620int code, arg;
621{
622#ifdef I_LIST
623 int i;
624#endif
625 int val;
626#ifdef I_FLUSHBAND
627 struct bandinfo bi;
628#endif
629 struct strpeek sp;
630 struct strfdinsert sfi;
631 struct strrecvfd srf;
632#ifdef I_LIST
633 struct str_list sl;
634#endif
635
636 /* I_STR is a special case because the data is read & written. */
637 if (code == I_STR)
638 return internal_stream_ioctl(tcp, arg);
639 if (entering(tcp))
640 return 0;
641
642 switch (code) {
643 case I_PUSH:
644 case I_LOOK:
645 case I_FIND:
646 /* arg is a string */
647 tprintf(", ");
648 printpath(tcp, arg);
649 return 1;
650 case I_POP:
651 /* doesn't take an argument */
652 return 1;
653 case I_FLUSH:
654 /* argument is an option */
655 tprintf(", ");
656 printxval(stream_flush_options, arg, "FLUSH???");
657 return 1;
658#ifdef I_FLUSHBAND
659 case I_FLUSHBAND:
660 /* argument is a pointer to a bandinfo struct */
661 if (umove(tcp, arg, &bi) < 0)
662 tprintf(", {...}");
663 else {
664 tprintf(", {bi_pri=%d, bi_flag=", bi.bi_pri);
665 if (!printflags(stream_flush_options, bi.bi_flag))
666 tprintf("0");
667 tprintf("}");
668 }
669 return 1;
670#endif /* I_FLUSHBAND */
671 case I_SETSIG:
672 /* argument is a set of flags */
673 tprintf(", ");
674 if (!printflags(stream_setsig_flags, arg))
675 tprintf("0");
676 return 1;
677 case I_GETSIG:
678 /* argument is a pointer to a set of flags */
679 if (syserror(tcp))
680 return 0;
681 tprintf(", [");
682 if (umove(tcp, arg, &val) < 0)
683 tprintf("?");
684 else if (!printflags(stream_setsig_flags, val))
685 tprintf("0");
686 tprintf("]");
687 return 1;
688 case I_PEEK:
689 /* argument is a pointer to a strpeek structure */
690 if (syserror(tcp) || !arg)
691 return 0;
692 if (umove(tcp, arg, &sp) < 0) {
693 tprintf(", {...}");
694 return 1;
695 }
696 tprintf(", {ctlbuf=");
697 printstrbuf(tcp, &sp.ctlbuf, 1);
698 tprintf(", databuf=");
699 printstrbuf(tcp, &sp.databuf, 1);
700 if (!printflags(msgflags, sp.flags))
701 tprintf("0");
702 return 1;
703 case I_SRDOPT:
704 /* argument is an option with flags */
705 tprintf(", ");
706 printxval(stream_read_options, arg & RMODEMASK, "R???");
707 addflags(stream_read_flags, arg & ~RMODEMASK);
708 return 1;
709 case I_GRDOPT:
710 /* argument is an pointer to an option with flags */
711 if (syserror(tcp))
712 return 0;
713 tprintf(", [");
714 if (umove(tcp, arg, &val) < 0)
715 tprintf("?");
716 else {
717 printxval(stream_read_options,
718 arg & RMODEMASK, "R???");
719 addflags(stream_read_flags, arg & ~RMODEMASK);
720 }
721 tprintf("]");
722 return 1;
723 case I_NREAD:
724#ifdef I_GETBAND
725 case I_GETBAND:
726#endif
727#ifdef I_SETCLTIME
728 case I_SETCLTIME:
729#endif
730#ifdef I_GETCLTIME
731 case I_GETCLTIME:
732#endif
733 /* argument is a pointer to a decimal integer */
734 if (syserror(tcp))
735 return 0;
736 tprintf(", ");
737 printnum(tcp, arg, "%d");
738 return 1;
739 case I_FDINSERT:
740 /* argument is a pointer to a strfdinsert structure */
741 if (syserror(tcp) || !arg)
742 return 0;
743 if (umove(tcp, arg, &sfi) < 0) {
744 tprintf(", {...}");
745 return 1;
746 }
747 tprintf(", {ctlbuf=");
748 printstrbuf(tcp, &sfi.ctlbuf, 1);
749 tprintf(", databuf=");
750 printstrbuf(tcp, &sfi.databuf, 1);
751 if (!printflags(msgflags, sfi.flags))
752 tprintf("0");
753 tprintf(", filedes=%d, offset=%d}", sfi.fildes, sfi.offset);
754 return 1;
755#ifdef I_SWROPT
756 case I_SWROPT:
757 /* argument is a set of flags */
758 tprintf(", ");
759 if (!printflags(stream_write_flags, arg))
760 tprintf("0");
761 return 1;
762#endif /* I_SWROPT */
763#ifdef I_GWROPT
764 case I_GWROPT:
765 /* argument is an pointer to an option with flags */
766 if (syserror(tcp))
767 return 0;
768 tprintf(", [");
769 if (umove(tcp, arg, &val) < 0)
770 tprintf("?");
771 else if (!printflags(stream_write_flags, arg))
772 tprintf("0");
773 tprintf("]");
774 return 1;
775#endif /* I_GWROPT */
776 case I_SENDFD:
777#ifdef I_CKBAND
778 case I_CKBAND:
779#endif
780#ifdef I_CANPUT
781 case I_CANPUT:
782#endif
783 case I_LINK:
784 case I_UNLINK:
785 case I_PLINK:
786 case I_PUNLINK:
787 /* argument is a decimal integer */
788 tprintf(", %d", arg);
789 return 1;
790 case I_RECVFD:
791 /* argument is a pointer to a strrecvfd structure */
792 if (syserror(tcp) || !arg)
793 return 0;
794 if (umove(tcp, arg, &srf) < 0) {
795 tprintf(", {...}");
796 return 1;
797 }
798 tprintf(", {fd=%d, uid=%lu, gid=%lu}", srf.fd,
799 (unsigned long) srf.uid, (unsigned long) srf.gid);
800 return 1;
801#ifdef I_LIST
802 case I_LIST:
803 if (syserror(tcp))
804 return 0;
805 if (arg == 0) {
806 tprintf(", NULL");
807 return 1;
808 }
809 if (umove(tcp, arg, &sl) < 0) {
810 tprintf(", {...}");
811 return 1;
812 }
813 tprintf(", {sl_nmods=%d, sl_modlist=[", sl.sl_nmods);
814 for (i = 0; i < tcp->u_rval; i++) {
815 if (i)
816 tprintf(", ");
817 printpath(tcp, (int) sl.sl_modlist[i].l_name);
818 }
819 tprintf("]}");
820 return 1;
821#endif /* I_LIST */
822#ifdef I_ATMARK
823 case I_ATMARK:
824 tprintf(", ");
825 printxval(stream_atmark_options, arg, "???MARK");
826 return 1;
827#endif /* I_ATMARK */
828 default:
829 return 0;
830 }
831}
832
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000833#endif /* !linux && !FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000834
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000835#endif /* HAVE_SYS_STREAM_H || linux || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000836