]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/compat/svr4/svr4_stream.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / compat / svr4 / svr4_stream.c
1 /*-
2  * Copyright (c) 1998 Mark Newton.  All rights reserved.
3  * Copyright (c) 1994, 1996 Christos Zoulas.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Christos Zoulas.
16  * 4. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 /*
32  * Pretend that we have streams...
33  * Yes, this is gross.
34  *
35  * ToDo: The state machine for getmsg needs re-thinking
36  */
37
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
40
41 #include "opt_compat.h"
42 #include "opt_ktrace.h"
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/capability.h>
47 #include <sys/fcntl.h>
48 #include <sys/filedesc.h>
49 #include <sys/filio.h>
50 #include <sys/lock.h>
51 #include <sys/malloc.h>
52 #include <sys/file.h>           /* Must come after sys/malloc.h */
53 #include <sys/mbuf.h>
54 #include <sys/mutex.h>
55 #include <sys/proc.h>
56 #include <sys/protosw.h>
57 #include <sys/signal.h>
58 #include <sys/signalvar.h>
59 #include <sys/socket.h>
60 #include <sys/socketvar.h>
61 #include <sys/stat.h>
62 #include <sys/syscallsubr.h>
63 #include <sys/sysproto.h>
64 #include <sys/uio.h>
65 #include <sys/ktrace.h>         /* Must come after sys/uio.h */
66 #include <sys/un.h>
67
68 #include <netinet/in.h>
69
70 #include <compat/svr4/svr4.h>
71 #include <compat/svr4/svr4_types.h>
72 #include <compat/svr4/svr4_util.h>
73 #include <compat/svr4/svr4_signal.h>
74 #include <compat/svr4/svr4_proto.h>
75 #include <compat/svr4/svr4_stropts.h>
76 #include <compat/svr4/svr4_timod.h>
77 #include <compat/svr4/svr4_sockmod.h>
78 #include <compat/svr4/svr4_ioctl.h>
79 #include <compat/svr4/svr4_socket.h>
80
81 /* Utils */
82 static int clean_pipe(struct thread *, char *);
83 static void getparm(struct file *, struct svr4_si_sockparms *);
84 static int svr4_do_putmsg(struct thread *, struct svr4_sys_putmsg_args *,
85                                struct file *);
86 static int svr4_do_getmsg(struct thread *, struct svr4_sys_getmsg_args *,
87                                struct file *);
88
89 /* Address Conversions */
90 static void sockaddr_to_netaddr_in(struct svr4_strmcmd *,
91                                         const struct sockaddr_in *);
92 static void sockaddr_to_netaddr_un(struct svr4_strmcmd *,
93                                         const struct sockaddr_un *);
94 static void netaddr_to_sockaddr_in(struct sockaddr_in *,
95                                         const struct svr4_strmcmd *);
96 static void netaddr_to_sockaddr_un(struct sockaddr_un *,
97                                         const struct svr4_strmcmd *);
98
99 /* stream ioctls */
100 static int i_nread(struct file *, struct thread *, register_t *, int,
101                         u_long, caddr_t);
102 static int i_fdinsert(struct file *, struct thread *, register_t *, int,
103                            u_long, caddr_t);
104 static int i_str(struct file *, struct thread *, register_t *, int,
105                         u_long, caddr_t);
106 static int i_setsig(struct file *, struct thread *, register_t *, int,
107                         u_long, caddr_t);
108 static int i_getsig(struct file *, struct thread *, register_t *, int,
109                         u_long, caddr_t);
110 static int _i_bind_rsvd(struct file *, struct thread *, register_t *, int,
111                              u_long, caddr_t);
112 static int _i_rele_rsvd(struct file *, struct thread *, register_t *, int,
113                              u_long, caddr_t);
114
115 /* i_str sockmod calls */
116 static int sockmod(struct file *, int, struct svr4_strioctl *,
117                               struct thread *);
118 static int si_listen(struct file *, int, struct svr4_strioctl *,
119                               struct thread *);
120 static int si_ogetudata(struct file *, int, struct svr4_strioctl *,
121                               struct thread *);
122 static int si_sockparams(struct file *, int, struct svr4_strioctl *,
123                               struct thread *);
124 static int si_shutdown  (struct file *, int, struct svr4_strioctl *,
125                               struct thread *);
126 static int si_getudata(struct file *, int, struct svr4_strioctl *,
127                               struct thread *);
128
129 /* i_str timod calls */
130 static int timod(struct file *, int, struct svr4_strioctl *, struct thread *);
131 static int ti_getinfo(struct file *, int, struct svr4_strioctl *,
132                               struct thread *);
133 static int ti_bind(struct file *, int, struct svr4_strioctl *, struct thread *);
134
135 #ifdef DEBUG_SVR4
136 static void bufprint(u_char *, size_t);
137 static int show_ioc(const char *, struct svr4_strioctl *);
138 static int show_strbuf(struct svr4_strbuf *);
139 static void show_msg(const char *, int, struct svr4_strbuf *, 
140                           struct svr4_strbuf *, int);
141
142 static void
143 bufprint(buf, len)
144         u_char *buf;
145         size_t len;
146 {
147         size_t i;
148
149         uprintf("\n\t");
150         for (i = 0; i < len; i++) {
151                 uprintf("%x ", buf[i]);
152                 if (i && (i % 16) == 0) 
153                         uprintf("\n\t");
154         }
155 }
156
157 static int
158 show_ioc(str, ioc)
159         const char              *str;
160         struct svr4_strioctl    *ioc;
161 {
162         u_char *ptr = NULL;
163         int len;
164         int error;
165
166         len = ioc->len;
167         if (len > 1024)
168                 len = 1024;
169
170         if (len > 0) {
171                 ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK);
172                 if ((error = copyin(ioc->buf, ptr, len)) != 0) {
173                         free((char *) ptr, M_TEMP);
174                         return error;
175                 }
176         }
177
178         uprintf("%s cmd = %ld, timeout = %d, len = %d, buf = %p { ",
179             str, ioc->cmd, ioc->timeout, ioc->len, ioc->buf);
180
181         if (ptr != NULL)
182                 bufprint(ptr, len);
183
184         uprintf("}\n");
185
186         if (ptr != NULL)
187                 free((char *) ptr, M_TEMP);
188         return 0;
189 }
190
191
192 static int
193 show_strbuf(str)
194         struct svr4_strbuf *str;
195 {
196         int error;
197         u_char *ptr = NULL;
198         int maxlen = str->maxlen;
199         int len = str->len;
200
201         if (maxlen > 8192)
202                 maxlen = 8192;
203
204         if (maxlen < 0)
205                 maxlen = 0;
206
207         if (len >= maxlen)
208                 len = maxlen;
209
210         if (len > 0) {
211             ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK);
212
213             if ((error = copyin(str->buf, ptr, len)) != 0) {
214                     free((char *) ptr, M_TEMP);
215                     return error;
216             }
217         }
218
219         uprintf(", { %d, %d, %p=[ ", str->maxlen, str->len, str->buf);
220
221         if (ptr)
222                 bufprint(ptr, len);
223
224         uprintf("]}");
225
226         if (ptr)
227                 free((char *) ptr, M_TEMP);
228
229         return 0;
230 }
231
232
233 static void
234 show_msg(str, fd, ctl, dat, flags)
235         const char              *str;
236         int                      fd;
237         struct svr4_strbuf      *ctl;
238         struct svr4_strbuf      *dat;
239         int                      flags;
240 {
241         struct svr4_strbuf      buf;
242         int error;
243
244         uprintf("%s(%d", str, fd);
245         if (ctl != NULL) {
246                 if ((error = copyin(ctl, &buf, sizeof(buf))) != 0)
247                         return;
248                 show_strbuf(&buf);
249         }
250         else 
251                 uprintf(", NULL");
252
253         if (dat != NULL) {
254                 if ((error = copyin(dat, &buf, sizeof(buf))) != 0)
255                         return;
256                 show_strbuf(&buf);
257         }
258         else 
259                 uprintf(", NULL");
260
261         uprintf(", %x);\n", flags);
262 }
263
264 #endif /* DEBUG_SVR4 */
265
266 /*
267  * We are faced with an interesting situation. On svr4 unix sockets
268  * are really pipes. But we really have sockets, and we might as
269  * well use them. At the point where svr4 calls TI_BIND, it has
270  * already created a named pipe for the socket using mknod(2).
271  * We need to create a socket with the same name when we bind,
272  * so we need to remove the pipe before, otherwise we'll get address
273  * already in use. So we *carefully* remove the pipe, to avoid
274  * using this as a random file removal tool. We use system calls
275  * to avoid code duplication.
276  */
277 static int
278 clean_pipe(td, path)
279         struct thread *td;
280         char *path;
281 {
282         struct stat st;
283         int error;
284
285         error = kern_lstat(td, path, UIO_SYSSPACE, &st);
286
287         /*
288          * Make sure we are dealing with a mode 0 named pipe.
289          */
290         if ((st.st_mode & S_IFMT) != S_IFIFO)
291                 return (0);
292
293         if ((st.st_mode & ALLPERMS) != 0)
294                 return (0);
295
296         error = kern_unlink(td, path, UIO_SYSSPACE);
297         if (error)
298                 DPRINTF(("clean_pipe: unlink failed %d\n", error));
299         return (error);
300 }
301
302
303 static void
304 sockaddr_to_netaddr_in(sc, sain)
305         struct svr4_strmcmd *sc;
306         const struct sockaddr_in *sain;
307 {
308         struct svr4_netaddr_in *na;
309         na = SVR4_ADDROF(sc);
310
311         na->family = sain->sin_family;
312         na->port = sain->sin_port;
313         na->addr = sain->sin_addr.s_addr;
314         DPRINTF(("sockaddr_in -> netaddr %d %d %lx\n", na->family, na->port,
315                  na->addr));
316 }
317
318
319 static void
320 sockaddr_to_netaddr_un(sc, saun)
321         struct svr4_strmcmd *sc;
322         const struct sockaddr_un *saun;
323 {
324         struct svr4_netaddr_un *na;
325         char *dst, *edst = ((char *) sc) + sc->offs + sizeof(na->family) + 1  -
326             sizeof(*sc);
327         const char *src;
328
329         na = SVR4_ADDROF(sc);
330         na->family = saun->sun_family;
331         for (src = saun->sun_path, dst = na->path; (*dst++ = *src++) != '\0'; )
332                 if (dst == edst)
333                         break;
334         DPRINTF(("sockaddr_un -> netaddr %d %s\n", na->family, na->path));
335 }
336
337
338 static void
339 netaddr_to_sockaddr_in(sain, sc)
340         struct sockaddr_in *sain;
341         const struct svr4_strmcmd *sc;
342 {
343         const struct svr4_netaddr_in *na;
344
345
346         na = SVR4_C_ADDROF(sc);
347         memset(sain, 0, sizeof(*sain));
348         sain->sin_len = sizeof(*sain);
349         sain->sin_family = na->family;
350         sain->sin_port = na->port;
351         sain->sin_addr.s_addr = na->addr;
352         DPRINTF(("netaddr -> sockaddr_in %d %d %x\n", sain->sin_family,
353                  sain->sin_port, sain->sin_addr.s_addr));
354 }
355
356
357 static void
358 netaddr_to_sockaddr_un(saun, sc)
359         struct sockaddr_un *saun;
360         const struct svr4_strmcmd *sc;
361 {
362         const struct svr4_netaddr_un *na;
363         char *dst, *edst = &saun->sun_path[sizeof(saun->sun_path) - 1];
364         const char *src;
365
366         na = SVR4_C_ADDROF(sc);
367         memset(saun, 0, sizeof(*saun));
368         saun->sun_family = na->family;
369         for (src = na->path, dst = saun->sun_path; (*dst++ = *src++) != '\0'; )
370                 if (dst == edst)
371                         break;
372         saun->sun_len = dst - saun->sun_path;
373         DPRINTF(("netaddr -> sockaddr_un %d %s\n", saun->sun_family,
374                  saun->sun_path));
375 }
376
377
378 static void
379 getparm(fp, pa)
380         struct file *fp;
381         struct svr4_si_sockparms *pa;
382 {
383         struct svr4_strm *st;
384         struct socket *so;
385
386         st = svr4_stream_get(fp);
387         if (st == NULL)
388                 return;
389
390         so = fp->f_data;
391
392         pa->family = st->s_family;
393
394         switch (so->so_type) {
395         case SOCK_DGRAM:
396                 pa->type = SVR4_T_CLTS;
397                 pa->protocol = IPPROTO_UDP;
398                 DPRINTF(("getparm(dgram)\n"));
399                 return;
400
401         case SOCK_STREAM:
402                 pa->type = SVR4_T_COTS;  /* What about T_COTS_ORD? XXX */
403                 pa->protocol = IPPROTO_IP;
404                 DPRINTF(("getparm(stream)\n"));
405                 return;
406
407         case SOCK_RAW:
408                 pa->type = SVR4_T_CLTS;
409                 pa->protocol = IPPROTO_RAW;
410                 DPRINTF(("getparm(raw)\n"));
411                 return;
412
413         default:
414                 pa->type = 0;
415                 pa->protocol = 0;
416                 DPRINTF(("getparm(type %d?)\n", so->so_type));
417                 return;
418         }
419 }
420
421
422 static int
423 si_ogetudata(fp, fd, ioc, td)
424         struct file             *fp;
425         int                      fd;
426         struct svr4_strioctl    *ioc;
427         struct thread           *td;
428 {
429         int error;
430         struct svr4_si_oudata ud;
431         struct svr4_si_sockparms pa;
432
433         if (ioc->len != sizeof(ud) && ioc->len != sizeof(ud) - sizeof(int)) {
434                 DPRINTF(("SI_OGETUDATA: Wrong size %d != %d\n",
435                          sizeof(ud), ioc->len));
436                 return EINVAL;
437         }
438
439         if ((error = copyin(ioc->buf, &ud, sizeof(ud))) != 0)
440                 return error;
441
442         getparm(fp, &pa);
443
444         switch (pa.family) {
445         case AF_INET:
446             ud.tidusize = 16384;
447             ud.addrsize = sizeof(struct svr4_sockaddr_in);
448             if (pa.type == SVR4_SOCK_STREAM) 
449                     ud.etsdusize = 1;
450             else
451                     ud.etsdusize = 0;
452             break;
453
454         case AF_LOCAL:
455             ud.tidusize = 65536;
456             ud.addrsize = 128;
457             ud.etsdusize = 128;
458             break;
459
460         default:
461             DPRINTF(("SI_OGETUDATA: Unsupported address family %d\n",
462                      pa.family));
463             return ENOSYS;
464         }
465
466         /* I have no idea what these should be! */
467         ud.optsize = 128;
468         ud.tsdusize = 128;
469
470         ud.servtype = pa.type;
471
472         /* XXX: Fixme */
473         ud.so_state = 0;
474         ud.so_options = 0;
475         return copyout(&ud, ioc->buf, ioc->len);
476 }
477
478
479 static int
480 si_sockparams(fp, fd, ioc, td)
481         struct file             *fp;
482         int                      fd;
483         struct svr4_strioctl    *ioc;
484         struct thread           *td;
485 {
486         struct svr4_si_sockparms pa;
487
488         getparm(fp, &pa);
489         return copyout(&pa, ioc->buf, sizeof(pa));
490 }
491
492
493 static int
494 si_listen(fp, fd, ioc, td)
495         struct file             *fp;
496         int                      fd;
497         struct svr4_strioctl    *ioc;
498         struct thread           *td;
499 {
500         int error;
501         struct svr4_strm *st = svr4_stream_get(fp);
502         struct svr4_strmcmd lst;
503         struct listen_args la;
504
505         if (st == NULL)
506                 return EINVAL;
507
508         if (ioc->len < 0 || ioc->len > sizeof(lst))
509                 return EINVAL;
510
511         if ((error = copyin(ioc->buf, &lst, ioc->len)) != 0)
512                 return error;
513
514         if (lst.cmd != SVR4_TI_OLD_BIND_REQUEST) {
515                 DPRINTF(("si_listen: bad request %ld\n", lst.cmd));
516                 return EINVAL;
517         }
518
519         /*
520          * We are making assumptions again...
521          */
522         la.s = fd;
523         DPRINTF(("SI_LISTEN: fileno %d backlog = %d\n", fd, 5));
524         la.backlog = 5;
525
526         if ((error = sys_listen(td, &la)) != 0) {
527                 DPRINTF(("SI_LISTEN: listen failed %d\n", error));
528                 return error;
529         }
530
531         st->s_cmd = SVR4_TI__ACCEPT_WAIT;
532         lst.cmd = SVR4_TI_BIND_REPLY;
533
534         switch (st->s_family) {
535         case AF_INET:
536                 /* XXX: Fill the length here */
537                 break;
538
539         case AF_LOCAL:
540                 lst.len = 140;
541                 lst.pad[28] = 0x00000000;       /* magic again */
542                 lst.pad[29] = 0x00000800;       /* magic again */
543                 lst.pad[30] = 0x80001400;       /* magic again */
544                 break;
545
546         default:
547                 DPRINTF(("SI_LISTEN: Unsupported address family %d\n",
548                     st->s_family));
549                 return ENOSYS;
550         }
551
552
553         if ((error = copyout(&lst, ioc->buf, ioc->len)) != 0)
554                 return error;
555
556         return 0;
557 }
558
559
560 static int
561 si_getudata(fp, fd, ioc, td)
562         struct file             *fp;
563         int                      fd;
564         struct svr4_strioctl    *ioc;
565         struct thread           *td;
566 {
567         int error;
568         struct svr4_si_udata ud;
569
570         if (sizeof(ud) != ioc->len) {
571                 DPRINTF(("SI_GETUDATA: Wrong size %d != %d\n",
572                          sizeof(ud), ioc->len));
573                 return EINVAL;
574         }
575
576         if ((error = copyin(ioc->buf, &ud, sizeof(ud))) != 0)
577                 return error;
578
579         getparm(fp, &ud.sockparms);
580
581         switch (ud.sockparms.family) {
582         case AF_INET:
583             DPRINTF(("getudata_inet\n"));
584             ud.tidusize = 16384;
585             ud.tsdusize = 16384;
586             ud.addrsize = sizeof(struct svr4_sockaddr_in);
587             if (ud.sockparms.type == SVR4_SOCK_STREAM) 
588                     ud.etsdusize = 1;
589             else
590                     ud.etsdusize = 0;
591             ud.optsize = 0;
592             break;
593
594         case AF_LOCAL:
595             DPRINTF(("getudata_local\n"));
596             ud.tidusize = 65536;
597             ud.tsdusize = 128;
598             ud.addrsize = 128;
599             ud.etsdusize = 128;
600             ud.optsize = 128;
601             break;
602
603         default:
604             DPRINTF(("SI_GETUDATA: Unsupported address family %d\n",
605                      ud.sockparms.family));
606             return ENOSYS;
607         }
608
609
610         ud.servtype = ud.sockparms.type;
611         DPRINTF(("ud.servtype = %d\n", ud.servtype));
612         /* XXX: Fixme */
613         ud.so_state = 0;
614         ud.so_options = 0;
615         return copyout(&ud, ioc->buf, sizeof(ud));
616 }
617
618
619 static int
620 si_shutdown(fp, fd, ioc, td)
621         struct file             *fp;
622         int                      fd;
623         struct svr4_strioctl    *ioc;
624         struct thread           *td;
625 {
626         int error;
627         struct shutdown_args ap;
628
629         if (ioc->len != sizeof(ap.how)) {
630                 DPRINTF(("SI_SHUTDOWN: Wrong size %d != %d\n",
631                          sizeof(ap.how), ioc->len));
632                 return EINVAL;
633         }
634
635         if ((error = copyin(ioc->buf, &ap.how, ioc->len)) != 0)
636                 return error;
637
638         ap.s = fd;
639
640         return sys_shutdown(td, &ap);
641 }
642
643
644 static int
645 sockmod(fp, fd, ioc, td)
646         struct file             *fp;
647         int                      fd;
648         struct svr4_strioctl    *ioc;
649         struct thread           *td;
650 {
651         switch (ioc->cmd) {
652         case SVR4_SI_OGETUDATA:
653                 DPRINTF(("SI_OGETUDATA\n"));
654                 return si_ogetudata(fp, fd, ioc, td);
655
656         case SVR4_SI_SHUTDOWN:
657                 DPRINTF(("SI_SHUTDOWN\n"));
658                 return si_shutdown(fp, fd, ioc, td);
659
660         case SVR4_SI_LISTEN:
661                 DPRINTF(("SI_LISTEN\n"));
662                 return si_listen(fp, fd, ioc, td);
663
664         case SVR4_SI_SETMYNAME:
665                 DPRINTF(("SI_SETMYNAME\n"));
666                 return 0;
667
668         case SVR4_SI_SETPEERNAME:
669                 DPRINTF(("SI_SETPEERNAME\n"));
670                 return 0;
671
672         case SVR4_SI_GETINTRANSIT:
673                 DPRINTF(("SI_GETINTRANSIT\n"));
674                 return 0;
675
676         case SVR4_SI_TCL_LINK:
677                 DPRINTF(("SI_TCL_LINK\n"));
678                 return 0;
679
680         case SVR4_SI_TCL_UNLINK:
681                 DPRINTF(("SI_TCL_UNLINK\n"));
682                 return 0;
683
684         case SVR4_SI_SOCKPARAMS:
685                 DPRINTF(("SI_SOCKPARAMS\n"));
686                 return si_sockparams(fp, fd, ioc, td);
687
688         case SVR4_SI_GETUDATA:
689                 DPRINTF(("SI_GETUDATA\n"));
690                 return si_getudata(fp, fd, ioc, td);
691
692         default:
693                 DPRINTF(("Unknown sockmod ioctl %lx\n", ioc->cmd));
694                 return 0;
695
696         }
697 }
698
699
700 static int
701 ti_getinfo(fp, fd, ioc, td)
702         struct file             *fp;
703         int                      fd;
704         struct svr4_strioctl    *ioc;
705         struct thread           *td;
706 {
707         int error;
708         struct svr4_infocmd info;
709
710         memset(&info, 0, sizeof(info));
711
712         if (ioc->len < 0 || ioc->len > sizeof(info))
713                 return EINVAL;
714
715         if ((error = copyin(ioc->buf, &info, ioc->len)) != 0)
716                 return error;
717
718         if (info.cmd != SVR4_TI_INFO_REQUEST)
719                 return EINVAL;
720
721         info.cmd = SVR4_TI_INFO_REPLY;
722         info.tsdu = 0;
723         info.etsdu = 1;
724         info.cdata = -2;
725         info.ddata = -2;
726         info.addr = 16;
727         info.opt = -1;
728         info.tidu = 16384;
729         info.serv = 2;
730         info.current = 0;
731         info.provider = 2;
732
733         ioc->len = sizeof(info);
734         if ((error = copyout(&info, ioc->buf, ioc->len)) != 0)
735                 return error;
736
737         return 0;
738 }
739
740
741 static int
742 ti_bind(fp, fd, ioc, td)
743         struct file             *fp;
744         int                      fd;
745         struct svr4_strioctl    *ioc;
746         struct thread           *td;
747 {
748         int error;
749         struct svr4_strm *st = svr4_stream_get(fp);
750         struct sockaddr_in sain;
751         struct sockaddr_un saun;
752         struct sockaddr *skp;
753         int sasize;
754         struct svr4_strmcmd bnd;
755
756         if (st == NULL) {
757                 DPRINTF(("ti_bind: bad file descriptor\n"));
758                 return EINVAL;
759         }
760
761         if (ioc->len < 0 || ioc->len > sizeof(bnd))
762                 return EINVAL;
763
764         if ((error = copyin(ioc->buf, &bnd, ioc->len)) != 0)
765                 return error;
766
767         if (bnd.cmd != SVR4_TI_OLD_BIND_REQUEST) {
768                 DPRINTF(("ti_bind: bad request %ld\n", bnd.cmd));
769                 return EINVAL;
770         }
771
772         switch (st->s_family) {
773         case AF_INET:
774                 skp = (struct sockaddr *)&sain;
775                 sasize = sizeof(sain);
776
777                 if (bnd.offs == 0)
778                         goto error;
779
780                 netaddr_to_sockaddr_in(&sain, &bnd);
781
782                 DPRINTF(("TI_BIND: fam %d, port %d, addr %x\n",
783                          sain.sin_family, sain.sin_port,
784                          sain.sin_addr.s_addr));
785                 break;
786
787         case AF_LOCAL:
788                 skp = (struct sockaddr *)&saun;
789                 sasize = sizeof(saun);
790                 if (bnd.offs == 0)
791                         goto error;
792
793                 netaddr_to_sockaddr_un(&saun, &bnd);
794
795                 if (saun.sun_path[0] == '\0')
796                         goto error;
797
798                 DPRINTF(("TI_BIND: fam %d, path %s\n",
799                          saun.sun_family, saun.sun_path));
800
801                 if ((error = clean_pipe(td, saun.sun_path)) != 0)
802                         return error;
803
804                 bnd.pad[28] = 0x00001000;       /* magic again */
805                 break;
806
807         default:
808                 DPRINTF(("TI_BIND: Unsupported address family %d\n",
809                          st->s_family));
810                 return ENOSYS;
811         }
812
813         DPRINTF(("TI_BIND: fileno %d\n", fd));
814
815         if ((error = kern_bind(td, fd, skp)) != 0) {
816                 DPRINTF(("TI_BIND: bind failed %d\n", error));
817                 return error;
818         }
819         goto reply;
820
821 error:
822         memset(&bnd, 0, sizeof(bnd));
823         bnd.len = sasize + 4;
824         bnd.offs = 0x10;        /* XXX */
825
826 reply:
827         bnd.cmd = SVR4_TI_BIND_REPLY;
828
829         if ((error = copyout(&bnd, ioc->buf, ioc->len)) != 0)
830                 return error;
831
832         return 0;
833 }
834
835
836 static int
837 timod(fp, fd, ioc, td)
838         struct file             *fp;
839         int                      fd;
840         struct svr4_strioctl    *ioc;
841         struct thread           *td;
842 {
843         switch (ioc->cmd) {
844         case SVR4_TI_GETINFO:
845                 DPRINTF(("TI_GETINFO\n"));
846                 return ti_getinfo(fp, fd, ioc, td);
847
848         case SVR4_TI_OPTMGMT:
849                 DPRINTF(("TI_OPTMGMT\n"));
850                 return 0;
851
852         case SVR4_TI_BIND:
853                 DPRINTF(("TI_BIND\n"));
854                 return ti_bind(fp, fd, ioc, td);
855
856         case SVR4_TI_UNBIND:
857                 DPRINTF(("TI_UNBIND\n"));
858                 return 0;
859
860         default:
861                 DPRINTF(("Unknown timod ioctl %lx\n", ioc->cmd));
862                 return 0;
863         }
864 }
865
866
867 int
868 svr4_stream_ti_ioctl(fp, td, retval, fd, cmd, dat)
869         struct file *fp;
870         struct thread *td;
871         register_t *retval;
872         int fd;
873         u_long cmd;
874         caddr_t dat;
875 {
876         struct svr4_strbuf skb, *sub = (struct svr4_strbuf *) dat;
877         struct svr4_strm *st = svr4_stream_get(fp);
878         int error;
879         struct sockaddr *sa;
880         socklen_t sasize, oldsasize;
881         struct svr4_strmcmd sc;
882
883         DPRINTF(("svr4_stream_ti_ioctl\n"));
884
885         if (st == NULL)
886                 return EINVAL;
887
888         sc.offs = 0x10;
889         
890         if ((error = copyin(sub, &skb, sizeof(skb))) != 0) {
891                 DPRINTF(("ti_ioctl: error copying in strbuf\n"));
892                 return error;
893         }
894
895         switch (st->s_family) {
896         case AF_INET:
897                 sasize = sizeof(struct sockaddr_in);
898                 break;
899
900         case AF_LOCAL:
901                 sasize = sizeof(struct sockaddr_un);
902                 break;
903
904         default:
905                 DPRINTF(("ti_ioctl: Unsupported address family %d\n",
906                          st->s_family));
907                 return ENOSYS;
908         }
909         oldsasize = sasize;
910
911         switch (cmd) {
912         case SVR4_TI_GETMYNAME:
913                 DPRINTF(("TI_GETMYNAME\n"));
914                 {
915                         error = kern_getsockname(td, fd, &sa, &sasize);
916                         if (error) {
917                                 DPRINTF(("ti_ioctl: getsockname error\n"));
918                                 return error;
919                         }
920                 }
921                 break;
922
923         case SVR4_TI_GETPEERNAME:
924                 DPRINTF(("TI_GETPEERNAME\n"));
925                 {
926                         error = kern_getpeername(td, fd, &sa, &sasize);
927                         if (error) {
928                                 DPRINTF(("ti_ioctl: getpeername error\n"));
929                                 return error;
930                         }
931                 }
932                 break;
933
934         case SVR4_TI_SETMYNAME:
935                 DPRINTF(("TI_SETMYNAME\n"));
936                 return 0;
937
938         case SVR4_TI_SETPEERNAME:
939                 DPRINTF(("TI_SETPEERNAME\n"));
940                 return 0;
941         default:
942                 DPRINTF(("ti_ioctl: Unknown ioctl %lx\n", cmd));
943                 return ENOSYS;
944         }
945
946         if (sasize < 0 || sasize > oldsasize) {
947                 free(sa, M_SONAME);
948                 return EINVAL;
949         }
950
951         switch (st->s_family) {
952         case AF_INET:
953                 sockaddr_to_netaddr_in(&sc, (struct sockaddr_in *)sa);
954                 skb.len = sasize;
955                 break;
956
957         case AF_LOCAL:
958                 sockaddr_to_netaddr_un(&sc, (struct sockaddr_un *)sa);
959                 skb.len = sasize + 4;
960                 break;
961
962         default:
963                 free(sa, M_SONAME);
964                 return ENOSYS;
965         }
966         free(sa, M_SONAME);
967
968         if ((error = copyout(SVR4_ADDROF(&sc), skb.buf, sasize)) != 0) {
969                 DPRINTF(("ti_ioctl: error copying out socket data\n"));
970                 return error;
971         }
972
973
974         if ((error = copyout(&skb, sub, sizeof(skb))) != 0) {
975                 DPRINTF(("ti_ioctl: error copying out strbuf\n"));
976                 return error;
977         }
978
979         return error;
980 }
981
982
983
984
985 static int
986 i_nread(fp, td, retval, fd, cmd, dat)
987         struct file *fp;
988         struct thread *td;
989         register_t *retval;
990         int fd;
991         u_long cmd;
992         caddr_t dat;
993 {
994         int error;
995         int nread = 0;  
996
997         /*
998          * We are supposed to return the message length in nread, and the
999          * number of messages in retval. We don't have the notion of number
1000          * of stream messages, so we just find out if we have any bytes waiting
1001          * for us, and if we do, then we assume that we have at least one
1002          * message waiting for us.
1003          */
1004         if ((error = fo_ioctl(fp, FIONREAD, (caddr_t) &nread, td->td_ucred,
1005             td)) != 0)
1006                 return error;
1007
1008         if (nread != 0)
1009                 *retval = 1;
1010         else
1011                 *retval = 0;
1012
1013         return copyout(&nread, dat, sizeof(nread));
1014 }
1015
1016 static int
1017 i_fdinsert(fp, td, retval, fd, cmd, dat)
1018         struct file *fp;
1019         struct thread *td;
1020         register_t *retval;
1021         int fd;
1022         u_long cmd;
1023         caddr_t dat;
1024 {
1025         /*
1026          * Major hack again here. We assume that we are using this to
1027          * implement accept(2). If that is the case, we have already
1028          * called accept, and we have stored the file descriptor in
1029          * afd. We find the file descriptor that the code wants to use
1030          * in fd insert, and then we dup2() our accepted file descriptor
1031          * to it.
1032          */
1033         int error;
1034         struct svr4_strm *st = svr4_stream_get(fp);
1035         struct svr4_strfdinsert fdi;
1036         struct dup2_args d2p;
1037
1038         if (st == NULL) {
1039                 DPRINTF(("fdinsert: bad file type\n"));
1040                 return EINVAL;
1041         }
1042
1043         mtx_lock(&Giant);
1044         if (st->s_afd == -1) {
1045                 DPRINTF(("fdinsert: accept fd not found\n"));
1046                 mtx_unlock(&Giant);
1047                 return ENOENT;
1048         }
1049
1050         if ((error = copyin(dat, &fdi, sizeof(fdi))) != 0) {
1051                 DPRINTF(("fdinsert: copyin failed %d\n", error));
1052                 mtx_unlock(&Giant);
1053                 return error;
1054         }
1055
1056         d2p.from = st->s_afd;
1057         d2p.to = fdi.fd;
1058
1059         if ((error = sys_dup2(td, &d2p)) != 0) {
1060                 DPRINTF(("fdinsert: dup2(%d, %d) failed %d\n", 
1061                     st->s_afd, fdi.fd, error));
1062                 mtx_unlock(&Giant);
1063                 return error;
1064         }
1065
1066         if ((error = kern_close(td, st->s_afd)) != 0) {
1067                 DPRINTF(("fdinsert: close(%d) failed %d\n", 
1068                     st->s_afd, error));
1069                 mtx_unlock(&Giant);
1070                 return error;
1071         }
1072
1073         st->s_afd = -1;
1074         mtx_unlock(&Giant);
1075
1076         *retval = 0;
1077         return 0;
1078 }
1079
1080
1081 static int
1082 _i_bind_rsvd(fp, td, retval, fd, cmd, dat)
1083         struct file *fp;
1084         struct thread *td;
1085         register_t *retval;
1086         int fd;
1087         u_long cmd;
1088         caddr_t dat;
1089 {
1090         struct mkfifo_args ap;
1091
1092         /*
1093          * This is a supposed to be a kernel and library only ioctl.
1094          * It gets called before ti_bind, when we have a unix 
1095          * socket, to physically create the socket transport and
1096          * ``reserve'' it. I don't know how this get reserved inside
1097          * the kernel, but we are going to create it nevertheless.
1098          */
1099         ap.path = dat;
1100         ap.mode = S_IFIFO;
1101
1102         return sys_mkfifo(td, &ap);
1103 }
1104
1105 static int
1106 _i_rele_rsvd(fp, td, retval, fd, cmd, dat)
1107         struct file *fp;
1108         struct thread *td;
1109         register_t *retval;
1110         int fd;
1111         u_long cmd;
1112         caddr_t dat;
1113 {
1114         struct unlink_args ap;
1115
1116         /*
1117          * This is a supposed to be a kernel and library only ioctl.
1118          * I guess it is supposed to release the socket.
1119          */
1120         ap.path = dat;
1121
1122         return sys_unlink(td, &ap);
1123 }
1124
1125 static int
1126 i_str(fp, td, retval, fd, cmd, dat)
1127         struct file *fp;
1128         struct thread *td;
1129         register_t *retval;
1130         int fd;
1131         u_long cmd;
1132         caddr_t dat;
1133 {
1134         int                      error;
1135         struct svr4_strioctl     ioc;
1136
1137         if ((error = copyin(dat, &ioc, sizeof(ioc))) != 0)
1138                 return error;
1139
1140 #ifdef DEBUG_SVR4
1141         if ((error = show_ioc(">", &ioc)) != 0)
1142                 return error;
1143 #endif /* DEBUG_SVR4 */
1144
1145         switch (ioc.cmd & 0xff00) {
1146         case SVR4_SIMOD:
1147                 if ((error = sockmod(fp, fd, &ioc, td)) != 0)
1148                         return error;
1149                 break;
1150
1151         case SVR4_TIMOD:
1152                 if ((error = timod(fp, fd, &ioc, td)) != 0)
1153                         return error;
1154                 break;
1155
1156         default:
1157                 DPRINTF(("Unimplemented module %c %ld\n",
1158                          (char) (cmd >> 8), cmd & 0xff));
1159                 return 0;
1160         }
1161
1162 #ifdef DEBUG_SVR4
1163         if ((error = show_ioc("<", &ioc)) != 0)
1164                 return error;
1165 #endif /* DEBUG_SVR4 */
1166         return copyout(&ioc, dat, sizeof(ioc));
1167 }
1168
1169 static int
1170 i_setsig(fp, td, retval, fd, cmd, dat)
1171         struct file *fp;
1172         struct thread *td;
1173         register_t *retval;
1174         int fd;
1175         u_long cmd;
1176         caddr_t dat;
1177 {
1178         /* 
1179          * This is the best we can do for now; we cannot generate
1180          * signals only for specific events so the signal mask gets
1181          * ignored; we save it just to pass it to a possible I_GETSIG...
1182          *
1183          * We alse have to fix the O_ASYNC fcntl bit, so the
1184          * process will get SIGPOLLs.
1185          */
1186         int error;
1187         register_t oflags, flags;
1188         struct svr4_strm *st = svr4_stream_get(fp);
1189
1190         if (st == NULL) {
1191                 DPRINTF(("i_setsig: bad file descriptor\n"));
1192                 return EINVAL;
1193         }
1194         /* get old status flags */
1195         error = kern_fcntl(td, fd, F_GETFL, 0);
1196         if (error)
1197                 return (error);
1198
1199         oflags = td->td_retval[0];
1200
1201         /* update the flags */
1202         mtx_lock(&Giant);
1203         if (dat != NULL) {
1204                 int mask;
1205
1206                 flags = oflags | O_ASYNC;
1207                 if ((error = copyin(dat, &mask, sizeof(mask))) != 0) {
1208                           DPRINTF(("i_setsig: bad eventmask pointer\n"));
1209                           return error;
1210                 }
1211                 if (mask & SVR4_S_ALLMASK) {
1212                           DPRINTF(("i_setsig: bad eventmask data %x\n", mask));
1213                           return EINVAL;
1214                 }
1215                 st->s_eventmask = mask;
1216         }
1217         else {
1218                 flags = oflags & ~O_ASYNC;
1219                 st->s_eventmask = 0;
1220         }
1221         mtx_unlock(&Giant);
1222
1223         /* set the new flags, if changed */
1224         if (flags != oflags) {
1225                 error = kern_fcntl(td, fd, F_SETFL, flags);
1226                 if (error)
1227                         return (error);
1228                 flags = td->td_retval[0];
1229         }
1230
1231         /* set up SIGIO receiver if needed */
1232         if (dat != NULL)
1233                 return (kern_fcntl(td, fd, F_SETOWN, td->td_proc->p_pid));
1234         return 0;
1235 }
1236
1237 static int
1238 i_getsig(fp, td, retval, fd, cmd, dat)
1239         struct file *fp;
1240         struct thread *td;
1241         register_t *retval;
1242         int fd;
1243         u_long cmd;
1244         caddr_t dat;
1245 {
1246         int error, eventmask;
1247
1248         if (dat != NULL) {
1249                 struct svr4_strm *st = svr4_stream_get(fp);
1250
1251                 if (st == NULL) {
1252                         DPRINTF(("i_getsig: bad file descriptor\n"));
1253                         return EINVAL;
1254                 }
1255                 mtx_lock(&Giant);
1256                 eventmask = st->s_eventmask;
1257                 mtx_unlock(&Giant);             
1258                 if ((error = copyout(&eventmask, dat,
1259                                      sizeof(eventmask))) != 0) {
1260                         DPRINTF(("i_getsig: bad eventmask pointer\n"));
1261                         return error;
1262                 }
1263         }
1264         return 0;
1265 }
1266
1267 int
1268 svr4_stream_ioctl(fp, td, retval, fd, cmd, dat)
1269         struct file *fp;
1270         struct thread *td;
1271         register_t *retval;
1272         int fd;
1273         u_long cmd;
1274         caddr_t dat;
1275 {
1276         *retval = 0;
1277
1278         /*
1279          * All the following stuff assumes "sockmod" is pushed...
1280          */
1281         switch (cmd) {
1282         case SVR4_I_NREAD:
1283                 DPRINTF(("I_NREAD\n"));
1284                 return i_nread(fp, td, retval, fd, cmd, dat);
1285
1286         case SVR4_I_PUSH:
1287                 DPRINTF(("I_PUSH %p\n", dat));
1288 #if defined(DEBUG_SVR4)
1289                 show_strbuf((struct svr4_strbuf *)dat);
1290 #endif
1291                 return 0;
1292
1293         case SVR4_I_POP:
1294                 DPRINTF(("I_POP\n"));
1295                 return 0;
1296
1297         case SVR4_I_LOOK:
1298                 DPRINTF(("I_LOOK\n"));
1299                 return 0;
1300
1301         case SVR4_I_FLUSH:
1302                 DPRINTF(("I_FLUSH\n"));
1303                 return 0;
1304
1305         case SVR4_I_SRDOPT:
1306                 DPRINTF(("I_SRDOPT\n"));
1307                 return 0;
1308
1309         case SVR4_I_GRDOPT:
1310                 DPRINTF(("I_GRDOPT\n"));
1311                 return 0;
1312
1313         case SVR4_I_STR:
1314                 DPRINTF(("I_STR\n"));
1315                 return i_str(fp, td, retval, fd, cmd, dat);
1316
1317         case SVR4_I_SETSIG:
1318                 DPRINTF(("I_SETSIG\n"));
1319                 return i_setsig(fp, td, retval, fd, cmd, dat);
1320
1321         case SVR4_I_GETSIG:
1322                 DPRINTF(("I_GETSIG\n"));
1323                 return i_getsig(fp, td, retval, fd, cmd, dat);
1324
1325         case SVR4_I_FIND:
1326                 DPRINTF(("I_FIND\n"));
1327                 /*
1328                  * Here we are not pushing modules really, we just
1329                  * pretend all are present
1330                  */
1331                 *retval = 0;
1332                 return 0;
1333
1334         case SVR4_I_LINK:
1335                 DPRINTF(("I_LINK\n"));
1336                 return 0;
1337
1338         case SVR4_I_UNLINK:
1339                 DPRINTF(("I_UNLINK\n"));
1340                 return 0;
1341
1342         case SVR4_I_ERECVFD:
1343                 DPRINTF(("I_ERECVFD\n"));
1344                 return 0;
1345
1346         case SVR4_I_PEEK:
1347                 DPRINTF(("I_PEEK\n"));
1348                 return 0;
1349
1350         case SVR4_I_FDINSERT:
1351                 DPRINTF(("I_FDINSERT\n"));
1352                 return i_fdinsert(fp, td, retval, fd, cmd, dat);
1353
1354         case SVR4_I_SENDFD:
1355                 DPRINTF(("I_SENDFD\n"));
1356                 return 0;
1357
1358         case SVR4_I_RECVFD:
1359                 DPRINTF(("I_RECVFD\n"));
1360                 return 0;
1361
1362         case SVR4_I_SWROPT:
1363                 DPRINTF(("I_SWROPT\n"));
1364                 return 0;
1365
1366         case SVR4_I_GWROPT:
1367                 DPRINTF(("I_GWROPT\n"));
1368                 return 0;
1369
1370         case SVR4_I_LIST:
1371                 DPRINTF(("I_LIST\n"));
1372                 return 0;
1373
1374         case SVR4_I_PLINK:
1375                 DPRINTF(("I_PLINK\n"));
1376                 return 0;
1377
1378         case SVR4_I_PUNLINK:
1379                 DPRINTF(("I_PUNLINK\n"));
1380                 return 0;
1381
1382         case SVR4_I_SETEV:
1383                 DPRINTF(("I_SETEV\n"));
1384                 return 0;
1385
1386         case SVR4_I_GETEV:
1387                 DPRINTF(("I_GETEV\n"));
1388                 return 0;
1389
1390         case SVR4_I_STREV:
1391                 DPRINTF(("I_STREV\n"));
1392                 return 0;
1393
1394         case SVR4_I_UNSTREV:
1395                 DPRINTF(("I_UNSTREV\n"));
1396                 return 0;
1397
1398         case SVR4_I_FLUSHBAND:
1399                 DPRINTF(("I_FLUSHBAND\n"));
1400                 return 0;
1401
1402         case SVR4_I_CKBAND:
1403                 DPRINTF(("I_CKBAND\n"));
1404                 return 0;
1405
1406         case SVR4_I_GETBAND:
1407                 DPRINTF(("I_GETBANK\n"));
1408                 return 0;
1409
1410         case SVR4_I_ATMARK:
1411                 DPRINTF(("I_ATMARK\n"));
1412                 return 0;
1413
1414         case SVR4_I_SETCLTIME:
1415                 DPRINTF(("I_SETCLTIME\n"));
1416                 return 0;
1417
1418         case SVR4_I_GETCLTIME:
1419                 DPRINTF(("I_GETCLTIME\n"));
1420                 return 0;
1421
1422         case SVR4_I_CANPUT:
1423                 DPRINTF(("I_CANPUT\n"));
1424                 return 0;
1425
1426         case SVR4__I_BIND_RSVD:
1427                 DPRINTF(("_I_BIND_RSVD\n"));
1428                 return _i_bind_rsvd(fp, td, retval, fd, cmd, dat);
1429
1430         case SVR4__I_RELE_RSVD:
1431                 DPRINTF(("_I_RELE_RSVD\n"));
1432                 return _i_rele_rsvd(fp, td, retval, fd, cmd, dat);
1433
1434         default:
1435                 DPRINTF(("unimpl cmd = %lx\n", cmd));
1436                 break;
1437         }
1438
1439         return 0;
1440 }
1441
1442
1443
1444 int
1445 svr4_sys_putmsg(td, uap)
1446         struct thread *td;
1447         struct svr4_sys_putmsg_args *uap;
1448 {
1449         cap_rights_t rights;
1450         struct file *fp;
1451         int error;
1452
1453         error = fget(td, uap->fd, cap_rights_init(&rights, CAP_SEND), &fp);
1454         if (error != 0) {
1455 #ifdef DEBUG_SVR4
1456                 uprintf("putmsg: bad fp\n");
1457 #endif
1458                 return EBADF;
1459         }
1460         error = svr4_do_putmsg(td, uap, fp);
1461         fdrop(fp, td);
1462         return (error);
1463 }
1464
1465 static int
1466 svr4_do_putmsg(td, uap, fp)
1467         struct thread *td;
1468         struct svr4_sys_putmsg_args *uap;
1469         struct file     *fp;
1470 {
1471         struct svr4_strbuf dat, ctl;
1472         struct svr4_strmcmd sc;
1473         struct sockaddr_in sain;
1474         struct sockaddr_un saun;
1475         struct sockaddr *sa;
1476         int sasize, *retval;
1477         struct svr4_strm *st;
1478         int error;
1479
1480         retval = td->td_retval;
1481
1482 #ifdef DEBUG_SVR4
1483         show_msg(">putmsg", uap->fd, uap->ctl,
1484                  uap->dat, uap->flags);
1485 #endif /* DEBUG_SVR4 */
1486
1487         if (uap->ctl != NULL) {
1488           if ((error = copyin(uap->ctl, &ctl, sizeof(ctl))) != 0) {
1489 #ifdef DEBUG_SVR4
1490             uprintf("putmsg: copyin(): %d\n", error);
1491 #endif
1492             return error;
1493           }
1494         }
1495         else
1496                 ctl.len = -1;
1497
1498         if (uap->dat != NULL) {
1499           if ((error = copyin(uap->dat, &dat, sizeof(dat))) != 0) {
1500 #ifdef DEBUG_SVR4
1501             uprintf("putmsg: copyin(): %d (2)\n", error);
1502 #endif
1503             return error;
1504           }
1505         }
1506         else
1507                 dat.len = -1;
1508
1509         /*
1510          * Only for sockets for now.
1511          */
1512         if ((st = svr4_stream_get(fp)) == NULL) {
1513                 DPRINTF(("putmsg: bad file type\n"));
1514                 return EINVAL;
1515         }
1516
1517         if (ctl.len < 0 || ctl.len > sizeof(sc)) {
1518                 DPRINTF(("putmsg: Bad control size %d != %d\n", ctl.len,
1519                          sizeof(struct svr4_strmcmd)));
1520                 return EINVAL;
1521         }
1522
1523         if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0)
1524                 return error;
1525
1526         switch (st->s_family) {
1527         case AF_INET:
1528                 if (sc.len != sizeof(sain)) {
1529                         if (sc.cmd == SVR4_TI_DATA_REQUEST) {
1530                                 struct write_args wa;
1531
1532                                 /* Solaris seems to use sc.cmd = 3 to
1533                                  * send "expedited" data.  telnet uses
1534                                  * this for options processing, sending EOF,
1535                                  * etc.  I'm sure other things use it too.
1536                                  * I don't have any documentation
1537                                  * on it, so I'm making a guess that this
1538                                  * is how it works. newton@atdot.dotat.org XXX
1539                                  */
1540                                 DPRINTF(("sending expedited data ??\n"));
1541                                 wa.fd = uap->fd;
1542                                 wa.buf = dat.buf;
1543                                 wa.nbyte = dat.len;
1544                                 return sys_write(td, &wa);
1545                         }
1546                         DPRINTF(("putmsg: Invalid inet length %ld\n", sc.len));
1547                         return EINVAL;
1548                 }
1549                 netaddr_to_sockaddr_in(&sain, &sc);
1550                 sa = (struct sockaddr *)&sain;
1551                 sasize = sizeof(sain);
1552                 if (sain.sin_family != st->s_family)
1553                         error = EINVAL;
1554                 break;
1555
1556         case AF_LOCAL:
1557                 if (ctl.len == 8) {
1558                         /* We are doing an accept; succeed */
1559                         DPRINTF(("putmsg: Do nothing\n"));
1560                         *retval = 0;
1561                         return 0;
1562                 }
1563                 else {
1564                         /* Maybe we've been given a device/inode pair */
1565                         dev_t *dev = SVR4_ADDROF(&sc);
1566                         ino_t *ino = (ino_t *) &dev[1];
1567                         if (svr4_find_socket(td, fp, *dev, *ino, &saun) != 0) {
1568                                 /* I guess we have it by name */
1569                                 netaddr_to_sockaddr_un(&saun, &sc);
1570                         }
1571                         sa = (struct sockaddr *)&saun;
1572                         sasize = sizeof(saun);
1573                 }
1574                 break;
1575
1576         default:
1577                 DPRINTF(("putmsg: Unsupported address family %d\n",
1578                          st->s_family));
1579                 return ENOSYS;
1580         }
1581
1582         mtx_lock(&Giant);
1583         st->s_cmd = sc.cmd;
1584         mtx_unlock(&Giant);
1585         switch (sc.cmd) {
1586         case SVR4_TI_CONNECT_REQUEST:   /* connect      */
1587                 {
1588
1589                         return (kern_connect(td, uap->fd, sa));
1590                 }
1591
1592         case SVR4_TI_SENDTO_REQUEST:    /* sendto       */
1593                 {
1594                         struct msghdr msg;
1595                         struct iovec aiov;
1596
1597                         msg.msg_name = sa;
1598                         msg.msg_namelen = sasize;
1599                         msg.msg_iov = &aiov;
1600                         msg.msg_iovlen = 1;
1601                         msg.msg_control = 0;
1602                         msg.msg_flags = 0;
1603                         aiov.iov_base = dat.buf;
1604                         aiov.iov_len = dat.len;
1605                         error = kern_sendit(td, uap->fd, &msg, uap->flags,
1606                             NULL, UIO_USERSPACE);
1607                         DPRINTF(("sendto_request error: %d\n", error));
1608                         *retval = 0;
1609                         return error;
1610                 }
1611
1612         default:
1613                 DPRINTF(("putmsg: Unimplemented command %lx\n", sc.cmd));
1614                 return ENOSYS;
1615         }
1616 }
1617
1618 int
1619 svr4_sys_getmsg(td, uap)
1620         struct thread *td;
1621         struct svr4_sys_getmsg_args *uap;
1622 {
1623         cap_rights_t rights;
1624         struct file *fp;
1625         int error;
1626
1627         error = fget(td, uap->fd, cap_rights_init(&rights, CAP_RECV), &fp);
1628         if (error != 0) {
1629 #ifdef DEBUG_SVR4
1630                 uprintf("getmsg: bad fp\n");
1631 #endif
1632                 return EBADF;
1633         }
1634         error = svr4_do_getmsg(td, uap, fp);
1635         fdrop(fp, td);
1636         return (error);
1637 }
1638
1639 int
1640 svr4_do_getmsg(td, uap, fp)
1641         struct thread *td;
1642         struct svr4_sys_getmsg_args *uap;
1643         struct file *fp;
1644 {
1645         struct svr4_strbuf dat, ctl;
1646         struct svr4_strmcmd sc;
1647         int error, *retval;
1648         struct msghdr msg;
1649         struct iovec aiov;
1650         struct sockaddr_in sain;
1651         struct sockaddr_un saun;
1652         struct sockaddr *sa;
1653         socklen_t sasize;
1654         struct svr4_strm *st;
1655         struct file *afp;
1656         int fl;
1657
1658         retval = td->td_retval;
1659         error = 0;
1660         afp = NULL;
1661
1662         memset(&sc, 0, sizeof(sc));
1663
1664 #ifdef DEBUG_SVR4
1665         show_msg(">getmsg", uap->fd, uap->ctl,
1666                  uap->dat, 0);
1667 #endif /* DEBUG_SVR4 */
1668
1669         if (uap->ctl != NULL) {
1670                 if ((error = copyin(uap->ctl, &ctl, sizeof(ctl))) != 0)
1671                         return error;
1672                 if (ctl.len < 0)
1673                         return EINVAL;
1674         }
1675         else {
1676                 ctl.len = -1;
1677                 ctl.maxlen = 0;
1678         }
1679
1680         if (uap->dat != NULL) {
1681                 if ((error = copyin(uap->dat, &dat, sizeof(dat))) != 0)
1682                         return error;
1683         }
1684         else {
1685                 dat.len = -1;
1686                 dat.maxlen = 0;
1687         }
1688
1689         /*
1690          * Only for sockets for now.
1691          */
1692         if ((st = svr4_stream_get(fp)) == NULL) {
1693                 DPRINTF(("getmsg: bad file type\n"));
1694                 return EINVAL;
1695         }
1696
1697         if (ctl.maxlen == -1 || dat.maxlen == -1) {
1698                 DPRINTF(("getmsg: Cannot handle -1 maxlen (yet)\n"));
1699                 return ENOSYS;
1700         }
1701
1702         switch (st->s_family) {
1703         case AF_INET:
1704                 sasize = sizeof(sain);
1705                 break;
1706
1707         case AF_LOCAL:
1708                 sasize = sizeof(saun);
1709                 break;
1710
1711         default:
1712                 DPRINTF(("getmsg: Unsupported address family %d\n",
1713                          st->s_family));
1714                 return ENOSYS;
1715         }
1716
1717         mtx_lock(&Giant);
1718         switch (st->s_cmd) {
1719         case SVR4_TI_CONNECT_REQUEST:
1720                 DPRINTF(("getmsg: TI_CONNECT_REQUEST\n"));
1721                 /*
1722                  * We do the connect in one step, so the putmsg should
1723                  * have gotten the error.
1724                  */
1725                 sc.cmd = SVR4_TI_OK_REPLY;
1726                 sc.len = 0;
1727
1728                 ctl.len = 8;
1729                 dat.len = -1;
1730                 fl = 1;
1731                 st->s_cmd = sc.cmd;
1732                 break;
1733
1734         case SVR4_TI_OK_REPLY:
1735                 DPRINTF(("getmsg: TI_OK_REPLY\n"));
1736                 /*
1737                  * We are immediately after a connect reply, so we send
1738                  * a connect verification.
1739                  */
1740
1741                 error = kern_getpeername(td, uap->fd, &sa, &sasize);
1742                 if (error) {
1743                         mtx_unlock(&Giant);
1744                         DPRINTF(("getmsg: getpeername failed %d\n", error));
1745                         return error;
1746                 }
1747
1748                 sc.cmd = SVR4_TI_CONNECT_REPLY;
1749                 sc.pad[0] = 0x4;
1750                 sc.offs = 0x18;
1751                 sc.pad[1] = 0x14;
1752                 sc.pad[2] = 0x04000402;
1753
1754                 switch (st->s_family) {
1755                 case AF_INET:
1756                         sc.len = sasize;
1757                         sockaddr_to_netaddr_in(&sc, (struct sockaddr_in *)sa);
1758                         break;
1759
1760                 case AF_LOCAL:
1761                         sc.len = sasize + 4;
1762                         sockaddr_to_netaddr_un(&sc, (struct sockaddr_un *)sa);
1763                         break;
1764
1765                 default:
1766                         mtx_unlock(&Giant);
1767                         free(sa, M_SONAME);
1768                         return ENOSYS;
1769                 }
1770                 free(sa, M_SONAME);
1771
1772                 ctl.len = 40;
1773                 dat.len = -1;
1774                 fl = 0;
1775                 st->s_cmd = sc.cmd;
1776                 break;
1777
1778         case SVR4_TI__ACCEPT_OK:
1779                 DPRINTF(("getmsg: TI__ACCEPT_OK\n"));
1780                 /*
1781                  * We do the connect in one step, so the putmsg should
1782                  * have gotten the error.
1783                  */
1784                 sc.cmd = SVR4_TI_OK_REPLY;
1785                 sc.len = 1;
1786
1787                 ctl.len = 8;
1788                 dat.len = -1;
1789                 fl = 1;
1790                 st->s_cmd = SVR4_TI__ACCEPT_WAIT;
1791                 break;
1792
1793         case SVR4_TI__ACCEPT_WAIT:
1794                 DPRINTF(("getmsg: TI__ACCEPT_WAIT\n"));
1795                 /*
1796                  * We are after a listen, so we try to accept...
1797                  */
1798
1799                 error = kern_accept(td, uap->fd, &sa, &sasize, &afp);
1800                 if (error) {
1801                         mtx_unlock(&Giant);
1802                         DPRINTF(("getmsg: accept failed %d\n", error));
1803                         return error;
1804                 }
1805
1806                 st->s_afd = *retval;
1807
1808                 DPRINTF(("getmsg: Accept fd = %d\n", st->s_afd));
1809
1810                 sc.cmd = SVR4_TI_ACCEPT_REPLY;
1811                 sc.offs = 0x18;
1812                 sc.pad[0] = 0x0;
1813
1814                 switch (st->s_family) {
1815                 case AF_INET:
1816                         sc.pad[1] = 0x28;
1817                         sockaddr_to_netaddr_in(&sc, (struct sockaddr_in *)&sa);
1818                         ctl.len = 40;
1819                         sc.len = sasize;
1820                         break;
1821
1822                 case AF_LOCAL:
1823                         sc.pad[1] = 0x00010000;
1824                         sc.pad[2] = 0xf6bcdaa0; /* I don't know what that is */
1825                         sc.pad[3] = 0x00010000;
1826                         ctl.len = 134;
1827                         sc.len = sasize + 4;
1828                         break;
1829
1830                 default:
1831                         fdclose(td->td_proc->p_fd, afp, st->s_afd, td);
1832                         fdrop(afp, td);
1833                         st->s_afd = -1;
1834                         mtx_unlock(&Giant);
1835                         free(sa, M_SONAME);
1836                         return ENOSYS;
1837                 }
1838                 free(sa, M_SONAME);
1839
1840                 dat.len = -1;
1841                 fl = 0;
1842                 st->s_cmd = SVR4_TI__ACCEPT_OK;
1843                 break;
1844
1845         case SVR4_TI_SENDTO_REQUEST:
1846                 DPRINTF(("getmsg: TI_SENDTO_REQUEST\n"));
1847                 if (ctl.maxlen > 36 && ctl.len < 36)
1848                     ctl.len = 36;
1849
1850                 if (ctl.len > sizeof(sc))
1851                         ctl.len = sizeof(sc);
1852
1853                 if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0) {
1854                         mtx_unlock(&Giant);
1855                         return error;
1856                 }
1857
1858                 switch (st->s_family) {
1859                 case AF_INET:
1860                         sa = (struct sockaddr *)&sain;
1861                         sockaddr_to_netaddr_in(&sc, &sain);
1862                         break;
1863
1864                 case AF_LOCAL:
1865                         sa = (struct sockaddr *)&saun;
1866                         sockaddr_to_netaddr_un(&sc, &saun);
1867                         break;
1868
1869                 default:
1870                         mtx_unlock(&Giant);
1871                         return ENOSYS;
1872                 }
1873
1874                 msg.msg_name = sa;
1875                 msg.msg_namelen = sasize;
1876                 msg.msg_iov = &aiov;
1877                 msg.msg_iovlen = 1;
1878                 msg.msg_control = 0;
1879                 aiov.iov_base = dat.buf;
1880                 aiov.iov_len = dat.maxlen;
1881                 msg.msg_flags = 0;
1882
1883                 error = kern_recvit(td, uap->fd, &msg, UIO_SYSSPACE, NULL);
1884
1885                 if (error) {
1886                         mtx_unlock(&Giant);
1887                         DPRINTF(("getmsg: recvit failed %d\n", error));
1888                         return error;
1889                 }
1890
1891                 sc.cmd = SVR4_TI_RECVFROM_IND;
1892
1893                 switch (st->s_family) {
1894                 case AF_INET:
1895                         sc.len = sasize;
1896                         sockaddr_to_netaddr_in(&sc, &sain);
1897                         break;
1898
1899                 case AF_LOCAL:
1900                         sc.len = sasize + 4;
1901                         sockaddr_to_netaddr_un(&sc, &saun);
1902                         break;
1903
1904                 default:
1905                         mtx_unlock(&Giant);
1906                         return ENOSYS;
1907                 }
1908
1909                 dat.len = *retval;
1910                 fl = 0;
1911                 st->s_cmd = sc.cmd;
1912                 break;
1913
1914         default:
1915                 st->s_cmd = sc.cmd;
1916                 if (st->s_cmd == SVR4_TI_CONNECT_REQUEST) {
1917                         struct read_args ra;
1918
1919                         /* More weirdness:  Again, I can't find documentation
1920                          * to back this up, but when a process does a generic
1921                          * "getmsg()" call it seems that the command field is
1922                          * zero and the length of the data area is zero.  I
1923                          * think processes expect getmsg() to fill in dat.len
1924                          * after reading at most dat.maxlen octets from the
1925                          * stream.  Since we're using sockets I can let 
1926                          * read() look after it and frob return values
1927                          * appropriately (or inappropriately :-)
1928                          *   -- newton@atdot.dotat.org        XXX
1929                          */
1930                         ra.fd = uap->fd;
1931                         ra.buf = dat.buf;
1932                         ra.nbyte = dat.maxlen;
1933                         if ((error = sys_read(td, &ra)) != 0) {
1934                                 mtx_unlock(&Giant);
1935                                 return error;
1936                         }
1937                         dat.len = *retval;
1938                         *retval = 0;
1939                         st->s_cmd = SVR4_TI_SENDTO_REQUEST;
1940                         break;
1941                 }
1942                 mtx_unlock(&Giant);
1943                 DPRINTF(("getmsg: Unknown state %x\n", st->s_cmd));
1944                 return EINVAL;
1945         }
1946
1947         if (uap->ctl) {
1948                 if (ctl.len > sizeof(sc))
1949                         ctl.len = sizeof(sc);
1950                 if (ctl.len != -1)
1951                         error = copyout(&sc, ctl.buf, ctl.len);
1952
1953                 if (error == 0)
1954                         error = copyout(&ctl, uap->ctl, sizeof(ctl));
1955         }
1956
1957         if (uap->dat) {
1958                 if (error == 0)
1959                         error = copyout(&dat, uap->dat, sizeof(dat));
1960         }
1961
1962         if (uap->flags) { /* XXX: Need translation */
1963                 if (error == 0)
1964                         error = copyout(&fl, uap->flags, sizeof(fl));
1965         }
1966
1967         if (error) {
1968                 if (afp) {
1969                         fdclose(td->td_proc->p_fd, afp, st->s_afd, td);
1970                         fdrop(afp, td);
1971                         st->s_afd = -1;
1972                 }
1973                 mtx_unlock(&Giant);
1974                 return (error);
1975         }
1976         mtx_unlock(&Giant);
1977         if (afp)
1978                 fdrop(afp, td);
1979
1980         *retval = 0;
1981
1982 #ifdef DEBUG_SVR4
1983         show_msg("<getmsg", uap->fd, uap->ctl,
1984                  uap->dat, fl);
1985 #endif /* DEBUG_SVR4 */
1986         return error;
1987 }
1988
1989 int svr4_sys_send(td, uap)
1990         struct thread *td;
1991         struct svr4_sys_send_args *uap;
1992 {
1993         struct sendto_args sta;
1994
1995         sta.s = uap->s;
1996         sta.buf = uap->buf;
1997         sta.len = uap->len;
1998         sta.flags = uap->flags;
1999         sta.to = NULL;
2000         sta.tolen = 0;
2001
2002         return (sys_sendto(td, &sta));
2003 }
2004
2005 int svr4_sys_recv(td, uap)
2006         struct thread *td;
2007         struct svr4_sys_recv_args *uap;
2008 {
2009         struct recvfrom_args rfa;
2010
2011         rfa.s = uap->s;
2012         rfa.buf = uap->buf;
2013         rfa.len = uap->len;
2014         rfa.flags = uap->flags;
2015         rfa.from = NULL;
2016         rfa.fromlenaddr = NULL;
2017
2018         return (sys_recvfrom(td, &rfa));
2019 }
2020
2021 /* 
2022  * XXX This isn't necessary, but it's handy for inserting debug code into
2023  * sendto().  Let's leave it here for now...
2024  */     
2025 int
2026 svr4_sys_sendto(td, uap)
2027         struct thread *td;
2028         struct svr4_sys_sendto_args *uap;
2029 {
2030         struct sendto_args sa;
2031
2032         sa.s = uap->s;
2033         sa.buf = uap->buf;
2034         sa.len = uap->len;
2035         sa.flags = uap->flags;
2036         sa.to = (caddr_t)uap->to;
2037         sa.tolen = uap->tolen;
2038
2039         DPRINTF(("calling sendto()\n"));
2040         return sys_sendto(td, &sa);
2041 }
2042