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