Home | History | Annotate | Line # | Download | only in ultrix
ultrix_ioctl.c revision 1.1
      1  1.1  jonathan /*	$NetBSD: ultrix_ioctl.c,v 1.1 1995/12/26 04:44:39 jonathan Exp $ */
      2  1.1  jonathan /*	from : NetBSD: sunos_ioctl.c,v 1.21 1995/10/07 06:27:31 mycroft Exp */
      3  1.1  jonathan 
      4  1.1  jonathan /*
      5  1.1  jonathan  * Copyright (c) 1993 Markus Wild.
      6  1.1  jonathan  * All rights reserved.
      7  1.1  jonathan  *
      8  1.1  jonathan  * Redistribution and use in source and binary forms, with or without
      9  1.1  jonathan  * modification, are permitted provided that the following conditions
     10  1.1  jonathan  * are met:
     11  1.1  jonathan  * 1. Redistributions of source code must retain the above copyright
     12  1.1  jonathan  *    notice, this list of conditions and the following disclaimer.
     13  1.1  jonathan  * 2. The name of the author may not be used to endorse or promote products
     14  1.1  jonathan  *    derived from this software without specific prior written permission
     15  1.1  jonathan  *
     16  1.1  jonathan  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  1.1  jonathan  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  1.1  jonathan  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  1.1  jonathan  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  1.1  jonathan  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  1.1  jonathan  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  1.1  jonathan  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  1.1  jonathan  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  1.1  jonathan  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  1.1  jonathan  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  1.1  jonathan  *
     27  1.1  jonathan  * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp
     28  1.1  jonathan  */
     29  1.1  jonathan 
     30  1.1  jonathan #include <sys/param.h>
     31  1.1  jonathan #include <sys/proc.h>
     32  1.1  jonathan #include <sys/systm.h>
     33  1.1  jonathan #include <sys/file.h>
     34  1.1  jonathan #include <sys/filedesc.h>
     35  1.1  jonathan #include <sys/ioctl.h>
     36  1.1  jonathan #include <sys/termios.h>
     37  1.1  jonathan #include <sys/tty.h>
     38  1.1  jonathan #include <sys/socket.h>
     39  1.1  jonathan #include <sys/audioio.h>
     40  1.1  jonathan #include <net/if.h>
     41  1.1  jonathan 
     42  1.1  jonathan #include <sys/mount.h>
     43  1.1  jonathan 
     44  1.1  jonathan #include <compat/ultrix/ultrix_syscallargs.h>
     45  1.1  jonathan #include <sys/syscallargs.h>
     46  1.1  jonathan 
     47  1.1  jonathan #include <compat/sunos/sunos.h>
     48  1.1  jonathan 
     49  1.1  jonathan #include "ultrix_tty.h"
     50  1.1  jonathan 
     51  1.1  jonathan 
     52  1.1  jonathan /*
     53  1.1  jonathan  * SunOS ioctl calls.
     54  1.1  jonathan  * This file is something of a hodge-podge.
     55  1.1  jonathan  * Support gets added as things turn up....
     56  1.1  jonathan  */
     57  1.1  jonathan 
     58  1.1  jonathan static struct speedtab sptab[] = {
     59  1.1  jonathan 	{ 0, 0 },
     60  1.1  jonathan 	{ 50, 1 },
     61  1.1  jonathan 	{ 75, 2 },
     62  1.1  jonathan 	{ 110, 3 },
     63  1.1  jonathan 	{ 134, 4 },
     64  1.1  jonathan 	{ 135, 4 },
     65  1.1  jonathan 	{ 150, 5 },
     66  1.1  jonathan 	{ 200, 6 },
     67  1.1  jonathan 	{ 300, 7 },
     68  1.1  jonathan 	{ 600, 8 },
     69  1.1  jonathan 	{ 1200, 9 },
     70  1.1  jonathan 	{ 1800, 10 },
     71  1.1  jonathan 	{ 2400, 11 },
     72  1.1  jonathan 	{ 4800, 12 },
     73  1.1  jonathan 	{ 9600, 13 },
     74  1.1  jonathan 	{ 19200, 14 },
     75  1.1  jonathan 	{ 38400, 15 },
     76  1.1  jonathan 	{ -1, -1 }
     77  1.1  jonathan };
     78  1.1  jonathan 
     79  1.1  jonathan static u_long s2btab[] = {
     80  1.1  jonathan 	0,
     81  1.1  jonathan 	50,
     82  1.1  jonathan 	75,
     83  1.1  jonathan 	110,
     84  1.1  jonathan 	134,
     85  1.1  jonathan 	150,
     86  1.1  jonathan 	200,
     87  1.1  jonathan 	300,
     88  1.1  jonathan 	600,
     89  1.1  jonathan 	1200,
     90  1.1  jonathan 	1800,
     91  1.1  jonathan 	2400,
     92  1.1  jonathan 	4800,
     93  1.1  jonathan 	9600,
     94  1.1  jonathan 	19200,
     95  1.1  jonathan 	38400,
     96  1.1  jonathan };
     97  1.1  jonathan 
     98  1.1  jonathan /*
     99  1.1  jonathan  * these two conversion functions have mostly been done
    100  1.1  jonathan  * with some perl cut&paste, then handedited to comment
    101  1.1  jonathan  * out what doesn't exist under NetBSD.
    102  1.1  jonathan  * A note from Markus's code:
    103  1.1  jonathan  *	(l & BITMASK1) / BITMASK1 * BITMASK2  is translated
    104  1.1  jonathan  *	optimally by gcc m68k, much better than any ?: stuff.
    105  1.1  jonathan  *	Code may vary with different architectures of course.
    106  1.1  jonathan  *
    107  1.1  jonathan  * I don't know what optimizer you used, but seeing divu's and
    108  1.1  jonathan  * bfextu's in the m68k assembly output did not encourage me...
    109  1.1  jonathan  * as well, gcc on the sparc definately generates much better
    110  1.1  jonathan  * code with ?:.
    111  1.1  jonathan  */
    112  1.1  jonathan 
    113  1.1  jonathan static void
    114  1.1  jonathan stios2btios(st, bt)
    115  1.1  jonathan 	struct sunos_termios *st;
    116  1.1  jonathan 	struct termios *bt;
    117  1.1  jonathan {
    118  1.1  jonathan 	register u_long l, r;
    119  1.1  jonathan 
    120  1.1  jonathan 	l = st->c_iflag;
    121  1.1  jonathan 	r = 	((l & 0x00000001) ? IGNBRK	: 0);
    122  1.1  jonathan 	r |=	((l & 0x00000002) ? BRKINT	: 0);
    123  1.1  jonathan 	r |=	((l & 0x00000004) ? IGNPAR	: 0);
    124  1.1  jonathan 	r |=	((l & 0x00000008) ? PARMRK	: 0);
    125  1.1  jonathan 	r |=	((l & 0x00000010) ? INPCK	: 0);
    126  1.1  jonathan 	r |=	((l & 0x00000020) ? ISTRIP	: 0);
    127  1.1  jonathan 	r |= 	((l & 0x00000040) ? INLCR	: 0);
    128  1.1  jonathan 	r |=	((l & 0x00000080) ? IGNCR	: 0);
    129  1.1  jonathan 	r |=	((l & 0x00000100) ? ICRNL	: 0);
    130  1.1  jonathan 	/*	((l & 0x00000200) ? IUCLC	: 0) */
    131  1.1  jonathan 	r |=	((l & 0x00000400) ? IXON	: 0);
    132  1.1  jonathan 	r |=	((l & 0x00000800) ? IXANY	: 0);
    133  1.1  jonathan 	r |=	((l & 0x00001000) ? IXOFF	: 0);
    134  1.1  jonathan 	r |=	((l & 0x00002000) ? IMAXBEL	: 0);
    135  1.1  jonathan 	bt->c_iflag = r;
    136  1.1  jonathan 
    137  1.1  jonathan 	l = st->c_oflag;
    138  1.1  jonathan 	r = 	((l & 0x00000001) ? OPOST	: 0);
    139  1.1  jonathan 	/*	((l & 0x00000002) ? OLCUC	: 0) */
    140  1.1  jonathan 	r |=	((l & 0x00000004) ? ONLCR	: 0);
    141  1.1  jonathan 	/*	((l & 0x00000008) ? OCRNL	: 0) */
    142  1.1  jonathan 	/*	((l & 0x00000010) ? ONOCR	: 0) */
    143  1.1  jonathan 	/*	((l & 0x00000020) ? ONLRET	: 0) */
    144  1.1  jonathan 	/*	((l & 0x00000040) ? OFILL	: 0) */
    145  1.1  jonathan 	/*	((l & 0x00000080) ? OFDEL	: 0) */
    146  1.1  jonathan 	/*	((l & 0x00000100) ? NLDLY	: 0) */
    147  1.1  jonathan 	/*	((l & 0x00000100) ? NL1		: 0) */
    148  1.1  jonathan 	/*	((l & 0x00000600) ? CRDLY	: 0) */
    149  1.1  jonathan 	/*	((l & 0x00000200) ? CR1		: 0) */
    150  1.1  jonathan 	/*	((l & 0x00000400) ? CR2		: 0) */
    151  1.1  jonathan 	/*	((l & 0x00000600) ? CR3		: 0) */
    152  1.1  jonathan 	/*	((l & 0x00001800) ? TABDLY	: 0) */
    153  1.1  jonathan 	/*	((l & 0x00000800) ? TAB1	: 0) */
    154  1.1  jonathan 	/*	((l & 0x00001000) ? TAB2	: 0) */
    155  1.1  jonathan 	r |=	((l & 0x00001800) ? OXTABS	: 0);
    156  1.1  jonathan 	/*	((l & 0x00002000) ? BSDLY	: 0) */
    157  1.1  jonathan 	/*	((l & 0x00002000) ? BS1		: 0) */
    158  1.1  jonathan 	/*	((l & 0x00004000) ? VTDLY	: 0) */
    159  1.1  jonathan 	/*	((l & 0x00004000) ? VT1		: 0) */
    160  1.1  jonathan 	/*	((l & 0x00008000) ? FFDLY	: 0) */
    161  1.1  jonathan 	/*	((l & 0x00008000) ? FF1		: 0) */
    162  1.1  jonathan 	/*	((l & 0x00010000) ? PAGEOUT	: 0) */
    163  1.1  jonathan 	/*	((l & 0x00020000) ? WRAP	: 0) */
    164  1.1  jonathan 	bt->c_oflag = r;
    165  1.1  jonathan 
    166  1.1  jonathan 	l = st->c_cflag;
    167  1.1  jonathan 	switch (l & 0x00000030) {
    168  1.1  jonathan 	case 0:
    169  1.1  jonathan 		r = CS5;
    170  1.1  jonathan 		break;
    171  1.1  jonathan 	case 0x00000010:
    172  1.1  jonathan 		r = CS6;
    173  1.1  jonathan 		break;
    174  1.1  jonathan 	case 0x00000020:
    175  1.1  jonathan 		r = CS7;
    176  1.1  jonathan 		break;
    177  1.1  jonathan 	case 0x00000030:
    178  1.1  jonathan 		r = CS8;
    179  1.1  jonathan 		break;
    180  1.1  jonathan 	}
    181  1.1  jonathan 	r |=	((l & 0x00000040) ? CSTOPB	: 0);
    182  1.1  jonathan 	r |=	((l & 0x00000080) ? CREAD	: 0);
    183  1.1  jonathan 	r |= 	((l & 0x00000100) ? PARENB	: 0);
    184  1.1  jonathan 	r |=	((l & 0x00000200) ? PARODD	: 0);
    185  1.1  jonathan 	r |=	((l & 0x00000400) ? HUPCL	: 0);
    186  1.1  jonathan 	r |=	((l & 0x00000800) ? CLOCAL	: 0);
    187  1.1  jonathan 	/*	((l & 0x00001000) ? LOBLK	: 0) */
    188  1.1  jonathan 	r |=	((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0);
    189  1.1  jonathan 	bt->c_cflag = r;
    190  1.1  jonathan 
    191  1.1  jonathan 	bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
    192  1.1  jonathan 
    193  1.1  jonathan 	l = st->c_lflag;
    194  1.1  jonathan 	r = 	((l & 0x00000001) ? ISIG	: 0);
    195  1.1  jonathan 	r |=	((l & 0x00000002) ? ICANON	: 0);
    196  1.1  jonathan 	/*	((l & 0x00000004) ? XCASE	: 0) */
    197  1.1  jonathan 	r |=	((l & 0x00000008) ? ECHO	: 0);
    198  1.1  jonathan 	r |=	((l & 0x00000010) ? ECHOE	: 0);
    199  1.1  jonathan 	r |=	((l & 0x00000020) ? ECHOK	: 0);
    200  1.1  jonathan 	r |=	((l & 0x00000040) ? ECHONL	: 0);
    201  1.1  jonathan 	r |= 	((l & 0x00000080) ? NOFLSH	: 0);
    202  1.1  jonathan 	r |=	((l & 0x00000100) ? TOSTOP	: 0);
    203  1.1  jonathan 	r |=	((l & 0x00000200) ? ECHOCTL	: 0);
    204  1.1  jonathan 	r |=	((l & 0x00000400) ? ECHOPRT	: 0);
    205  1.1  jonathan 	r |=	((l & 0x00000800) ? ECHOKE	: 0);
    206  1.1  jonathan 	/*	((l & 0x00001000) ? DEFECHO	: 0) */
    207  1.1  jonathan 	r |=	((l & 0x00002000) ? FLUSHO	: 0);
    208  1.1  jonathan 	r |=	((l & 0x00004000) ? PENDIN	: 0);
    209  1.1  jonathan 	bt->c_lflag = r;
    210  1.1  jonathan 
    211  1.1  jonathan 	bt->c_cc[VINTR]    = st->c_cc[0]  ? st->c_cc[0]  : _POSIX_VDISABLE;
    212  1.1  jonathan 	bt->c_cc[VQUIT]    = st->c_cc[1]  ? st->c_cc[1]  : _POSIX_VDISABLE;
    213  1.1  jonathan 	bt->c_cc[VERASE]   = st->c_cc[2]  ? st->c_cc[2]  : _POSIX_VDISABLE;
    214  1.1  jonathan 	bt->c_cc[VKILL]    = st->c_cc[3]  ? st->c_cc[3]  : _POSIX_VDISABLE;
    215  1.1  jonathan 	bt->c_cc[VEOF]     = st->c_cc[4]  ? st->c_cc[4]  : _POSIX_VDISABLE;
    216  1.1  jonathan 	bt->c_cc[VEOL]     = st->c_cc[5]  ? st->c_cc[5]  : _POSIX_VDISABLE;
    217  1.1  jonathan 	bt->c_cc[VEOL2]    = st->c_cc[6]  ? st->c_cc[6]  : _POSIX_VDISABLE;
    218  1.1  jonathan     /*	bt->c_cc[VSWTCH]   = st->c_cc[7]  ? st->c_cc[7]  : _POSIX_VDISABLE; */
    219  1.1  jonathan 	bt->c_cc[VSTART]   = st->c_cc[8]  ? st->c_cc[8]  : _POSIX_VDISABLE;
    220  1.1  jonathan 	bt->c_cc[VSTOP]    = st->c_cc[9]  ? st->c_cc[9]  : _POSIX_VDISABLE;
    221  1.1  jonathan 	bt->c_cc[VSUSP]    = st->c_cc[10] ? st->c_cc[10] : _POSIX_VDISABLE;
    222  1.1  jonathan 	bt->c_cc[VDSUSP]   = st->c_cc[11] ? st->c_cc[11] : _POSIX_VDISABLE;
    223  1.1  jonathan 	bt->c_cc[VREPRINT] = st->c_cc[12] ? st->c_cc[12] : _POSIX_VDISABLE;
    224  1.1  jonathan 	bt->c_cc[VDISCARD] = st->c_cc[13] ? st->c_cc[13] : _POSIX_VDISABLE;
    225  1.1  jonathan 	bt->c_cc[VWERASE]  = st->c_cc[14] ? st->c_cc[14] : _POSIX_VDISABLE;
    226  1.1  jonathan 	bt->c_cc[VLNEXT]   = st->c_cc[15] ? st->c_cc[15] : _POSIX_VDISABLE;
    227  1.1  jonathan 	bt->c_cc[VSTATUS]  = st->c_cc[16] ? st->c_cc[16] : _POSIX_VDISABLE;
    228  1.1  jonathan 
    229  1.1  jonathan 	/* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */
    230  1.1  jonathan 	bt->c_cc[VMIN]	   = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOF];
    231  1.1  jonathan 	bt->c_cc[VTIME]	   = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOL];
    232  1.1  jonathan }
    233  1.1  jonathan 
    234  1.1  jonathan 
    235  1.1  jonathan static void
    236  1.1  jonathan btios2stios(bt, st)
    237  1.1  jonathan 	struct termios *bt;
    238  1.1  jonathan 	struct sunos_termios *st;
    239  1.1  jonathan {
    240  1.1  jonathan 	register u_long l, r;
    241  1.1  jonathan 
    242  1.1  jonathan 	l = bt->c_iflag;
    243  1.1  jonathan 	r = 	((l &  IGNBRK) ? 0x00000001	: 0);
    244  1.1  jonathan 	r |=	((l &  BRKINT) ? 0x00000002	: 0);
    245  1.1  jonathan 	r |=	((l &  IGNPAR) ? 0x00000004	: 0);
    246  1.1  jonathan 	r |=	((l &  PARMRK) ? 0x00000008	: 0);
    247  1.1  jonathan 	r |=	((l &   INPCK) ? 0x00000010	: 0);
    248  1.1  jonathan 	r |=	((l &  ISTRIP) ? 0x00000020	: 0);
    249  1.1  jonathan 	r |=	((l &   INLCR) ? 0x00000040	: 0);
    250  1.1  jonathan 	r |=	((l &   IGNCR) ? 0x00000080	: 0);
    251  1.1  jonathan 	r |=	((l &   ICRNL) ? 0x00000100	: 0);
    252  1.1  jonathan 	/*	((l &   IUCLC) ? 0x00000200	: 0) */
    253  1.1  jonathan 	r |=	((l &    IXON) ? 0x00000400	: 0);
    254  1.1  jonathan 	r |=	((l &   IXANY) ? 0x00000800	: 0);
    255  1.1  jonathan 	r |=	((l &   IXOFF) ? 0x00001000	: 0);
    256  1.1  jonathan 	r |=	((l & IMAXBEL) ? 0x00002000	: 0);
    257  1.1  jonathan 	st->c_iflag = r;
    258  1.1  jonathan 
    259  1.1  jonathan 	l = bt->c_oflag;
    260  1.1  jonathan 	r =	((l &   OPOST) ? 0x00000001	: 0);
    261  1.1  jonathan 	/*	((l &   OLCUC) ? 0x00000002	: 0) */
    262  1.1  jonathan 	r |=	((l &   ONLCR) ? 0x00000004	: 0);
    263  1.1  jonathan 	/*	((l &   OCRNL) ? 0x00000008	: 0) */
    264  1.1  jonathan 	/*	((l &   ONOCR) ? 0x00000010	: 0) */
    265  1.1  jonathan 	/*	((l &  ONLRET) ? 0x00000020	: 0) */
    266  1.1  jonathan 	/*	((l &   OFILL) ? 0x00000040	: 0) */
    267  1.1  jonathan 	/*	((l &   OFDEL) ? 0x00000080	: 0) */
    268  1.1  jonathan 	/*	((l &   NLDLY) ? 0x00000100	: 0) */
    269  1.1  jonathan 	/*	((l &     NL1) ? 0x00000100	: 0) */
    270  1.1  jonathan 	/*	((l &   CRDLY) ? 0x00000600	: 0) */
    271  1.1  jonathan 	/*	((l &     CR1) ? 0x00000200	: 0) */
    272  1.1  jonathan 	/*	((l &     CR2) ? 0x00000400	: 0) */
    273  1.1  jonathan 	/*	((l &     CR3) ? 0x00000600	: 0) */
    274  1.1  jonathan 	/*	((l &  TABDLY) ? 0x00001800	: 0) */
    275  1.1  jonathan 	/*	((l &    TAB1) ? 0x00000800	: 0) */
    276  1.1  jonathan 	/*	((l &    TAB2) ? 0x00001000	: 0) */
    277  1.1  jonathan 	r |=	((l &  OXTABS) ? 0x00001800	: 0);
    278  1.1  jonathan 	/*	((l &   BSDLY) ? 0x00002000	: 0) */
    279  1.1  jonathan 	/*	((l &     BS1) ? 0x00002000	: 0) */
    280  1.1  jonathan 	/*	((l &   VTDLY) ? 0x00004000	: 0) */
    281  1.1  jonathan 	/*	((l &     VT1) ? 0x00004000	: 0) */
    282  1.1  jonathan 	/*	((l &   FFDLY) ? 0x00008000	: 0) */
    283  1.1  jonathan 	/*	((l &     FF1) ? 0x00008000	: 0) */
    284  1.1  jonathan 	/*	((l & PAGEOUT) ? 0x00010000	: 0) */
    285  1.1  jonathan 	/*	((l &    WRAP) ? 0x00020000	: 0) */
    286  1.1  jonathan 	st->c_oflag = r;
    287  1.1  jonathan 
    288  1.1  jonathan 	l = bt->c_cflag;
    289  1.1  jonathan 	switch (l & CSIZE) {
    290  1.1  jonathan 	case CS5:
    291  1.1  jonathan 		r = 0;
    292  1.1  jonathan 		break;
    293  1.1  jonathan 	case CS6:
    294  1.1  jonathan 		r = 0x00000010;
    295  1.1  jonathan 		break;
    296  1.1  jonathan 	case CS7:
    297  1.1  jonathan 		r = 0x00000020;
    298  1.1  jonathan 		break;
    299  1.1  jonathan 	case CS8:
    300  1.1  jonathan 		r = 0x00000030;
    301  1.1  jonathan 		break;
    302  1.1  jonathan 	}
    303  1.1  jonathan 	r |=	((l &  CSTOPB) ? 0x00000040	: 0);
    304  1.1  jonathan 	r |=	((l &   CREAD) ? 0x00000080	: 0);
    305  1.1  jonathan 	r |=	((l &  PARENB) ? 0x00000100	: 0);
    306  1.1  jonathan 	r |=	((l &  PARODD) ? 0x00000200	: 0);
    307  1.1  jonathan 	r |=	((l &   HUPCL) ? 0x00000400	: 0);
    308  1.1  jonathan 	r |=	((l &  CLOCAL) ? 0x00000800	: 0);
    309  1.1  jonathan 	/*	((l &   LOBLK) ? 0x00001000	: 0) */
    310  1.1  jonathan 	r |=	((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0);
    311  1.1  jonathan 	st->c_cflag = r;
    312  1.1  jonathan 
    313  1.1  jonathan 	l = bt->c_lflag;
    314  1.1  jonathan 	r =	((l &    ISIG) ? 0x00000001	: 0);
    315  1.1  jonathan 	r |=	((l &  ICANON) ? 0x00000002	: 0);
    316  1.1  jonathan 	/*	((l &   XCASE) ? 0x00000004	: 0) */
    317  1.1  jonathan 	r |=	((l &    ECHO) ? 0x00000008	: 0);
    318  1.1  jonathan 	r |=	((l &   ECHOE) ? 0x00000010	: 0);
    319  1.1  jonathan 	r |=	((l &   ECHOK) ? 0x00000020	: 0);
    320  1.1  jonathan 	r |=	((l &  ECHONL) ? 0x00000040	: 0);
    321  1.1  jonathan 	r |=	((l &  NOFLSH) ? 0x00000080	: 0);
    322  1.1  jonathan 	r |=	((l &  TOSTOP) ? 0x00000100	: 0);
    323  1.1  jonathan 	r |=	((l & ECHOCTL) ? 0x00000200	: 0);
    324  1.1  jonathan 	r |=	((l & ECHOPRT) ? 0x00000400	: 0);
    325  1.1  jonathan 	r |=	((l &  ECHOKE) ? 0x00000800	: 0);
    326  1.1  jonathan 	/*	((l & DEFECHO) ? 0x00001000	: 0) */
    327  1.1  jonathan 	r |=	((l &  FLUSHO) ? 0x00002000	: 0);
    328  1.1  jonathan 	r |=	((l &  PENDIN) ? 0x00004000	: 0);
    329  1.1  jonathan 	st->c_lflag = r;
    330  1.1  jonathan 
    331  1.1  jonathan 	l = ttspeedtab(bt->c_ospeed, sptab);
    332  1.1  jonathan 	if (l >= 0)
    333  1.1  jonathan 		st->c_cflag |= l;
    334  1.1  jonathan 
    335  1.1  jonathan 	st->c_cc[0] = bt->c_cc[VINTR]   != _POSIX_VDISABLE? bt->c_cc[VINTR]:0;
    336  1.1  jonathan 	st->c_cc[1] = bt->c_cc[VQUIT]   != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0;
    337  1.1  jonathan 	st->c_cc[2] = bt->c_cc[VERASE]  != _POSIX_VDISABLE? bt->c_cc[VERASE]:0;
    338  1.1  jonathan 	st->c_cc[3] = bt->c_cc[VKILL]   != _POSIX_VDISABLE? bt->c_cc[VKILL]:0;
    339  1.1  jonathan 	st->c_cc[4] = bt->c_cc[VEOF]    != _POSIX_VDISABLE? bt->c_cc[VEOF]:0;
    340  1.1  jonathan 	st->c_cc[5] = bt->c_cc[VEOL]    != _POSIX_VDISABLE? bt->c_cc[VEOL]:0;
    341  1.1  jonathan 	st->c_cc[6] = bt->c_cc[VEOL2]   != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0;
    342  1.1  jonathan 	st->c_cc[7] = 0;
    343  1.1  jonathan 		/*    bt->c_cc[VSWTCH]  != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */
    344  1.1  jonathan 	st->c_cc[8] = bt->c_cc[VSTART]  != _POSIX_VDISABLE? bt->c_cc[VSTART]:0;
    345  1.1  jonathan 	st->c_cc[9] = bt->c_cc[VSTOP]   != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0;
    346  1.1  jonathan 	st->c_cc[10]= bt->c_cc[VSUSP]   != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0;
    347  1.1  jonathan 	st->c_cc[11]= bt->c_cc[VDSUSP]  != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0;
    348  1.1  jonathan 	st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0;
    349  1.1  jonathan 	st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0;
    350  1.1  jonathan 	st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0;
    351  1.1  jonathan 	st->c_cc[15]= bt->c_cc[VLNEXT]  != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0;
    352  1.1  jonathan 	st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0;
    353  1.1  jonathan 
    354  1.1  jonathan 	if (!(bt->c_lflag & ICANON)) {
    355  1.1  jonathan 		/* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */
    356  1.1  jonathan 		st->c_cc[4] = bt->c_cc[VMIN];
    357  1.1  jonathan 		st->c_cc[5] = bt->c_cc[VTIME];
    358  1.1  jonathan 	}
    359  1.1  jonathan 
    360  1.1  jonathan 	st->c_line = 0;
    361  1.1  jonathan }
    362  1.1  jonathan 
    363  1.1  jonathan static void
    364  1.1  jonathan stios2stio(ts, t)
    365  1.1  jonathan 	struct sunos_termios *ts;
    366  1.1  jonathan 	struct sunos_termio *t;
    367  1.1  jonathan {
    368  1.1  jonathan 	t->c_iflag = ts->c_iflag;
    369  1.1  jonathan 	t->c_oflag = ts->c_oflag;
    370  1.1  jonathan 	t->c_cflag = ts->c_cflag;
    371  1.1  jonathan 	t->c_lflag = ts->c_lflag;
    372  1.1  jonathan 	t->c_line  = ts->c_line;
    373  1.1  jonathan 	bcopy(ts->c_cc, t->c_cc, 8);
    374  1.1  jonathan }
    375  1.1  jonathan 
    376  1.1  jonathan static void
    377  1.1  jonathan stio2stios(t, ts)
    378  1.1  jonathan 	struct sunos_termio *t;
    379  1.1  jonathan 	struct sunos_termios *ts;
    380  1.1  jonathan {
    381  1.1  jonathan 	ts->c_iflag = t->c_iflag;
    382  1.1  jonathan 	ts->c_oflag = t->c_oflag;
    383  1.1  jonathan 	ts->c_cflag = t->c_cflag;
    384  1.1  jonathan 	ts->c_lflag = t->c_lflag;
    385  1.1  jonathan 	ts->c_line  = t->c_line;
    386  1.1  jonathan 	bcopy(t->c_cc, ts->c_cc, 8); /* don't touch the upper fields! */
    387  1.1  jonathan }
    388  1.1  jonathan 
    389  1.1  jonathan int
    390  1.1  jonathan ultrix_sys_ioctl(p, v, retval)
    391  1.1  jonathan 	register struct proc *p;
    392  1.1  jonathan 	void *v;
    393  1.1  jonathan 	register_t *retval;
    394  1.1  jonathan {
    395  1.1  jonathan 	struct ultrix_sys_ioctl_args *uap = v;
    396  1.1  jonathan 	register struct filedesc *fdp = p->p_fd;
    397  1.1  jonathan 	register struct file *fp;
    398  1.1  jonathan 	register int (*ctl)();
    399  1.1  jonathan 	int error;
    400  1.1  jonathan 
    401  1.1  jonathan 	if ( (unsigned)SCARG(uap, fd) >= fdp->fd_nfiles ||
    402  1.1  jonathan 	    (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
    403  1.1  jonathan 		return EBADF;
    404  1.1  jonathan 
    405  1.1  jonathan 	if ((fp->f_flag & (FREAD|FWRITE)) == 0)
    406  1.1  jonathan 		return EBADF;
    407  1.1  jonathan 
    408  1.1  jonathan 	ctl = fp->f_ops->fo_ioctl;
    409  1.1  jonathan 
    410  1.1  jonathan 	switch (SCARG(uap, com)) {
    411  1.1  jonathan 	case _IOR('t', 0, int):
    412  1.1  jonathan 		SCARG(uap, com) = TIOCGETD;
    413  1.1  jonathan 		break;
    414  1.1  jonathan 	case _IOW('t', 1, int):
    415  1.1  jonathan 	    {
    416  1.1  jonathan 		int disc;
    417  1.1  jonathan 
    418  1.1  jonathan 		if ((error = copyin(SCARG(uap, data), (caddr_t)&disc,
    419  1.1  jonathan 		    sizeof disc)) != 0)
    420  1.1  jonathan 			return error;
    421  1.1  jonathan 
    422  1.1  jonathan 		/* map SunOS NTTYDISC into our termios discipline */
    423  1.1  jonathan 		if (disc == 2)
    424  1.1  jonathan 			disc = 0;
    425  1.1  jonathan 		/* all other disciplines are not supported by NetBSD */
    426  1.1  jonathan 		if (disc)
    427  1.1  jonathan 			return ENXIO;
    428  1.1  jonathan 
    429  1.1  jonathan 		return (*ctl)(fp, TIOCSETD, (caddr_t)&disc, p);
    430  1.1  jonathan 	    }
    431  1.1  jonathan 	case _IOW('t', 101, int):	/* sun SUNOS_TIOCSSOFTCAR */
    432  1.1  jonathan 	    {
    433  1.1  jonathan 		int x;	/* unused */
    434  1.1  jonathan 
    435  1.1  jonathan 		return copyin((caddr_t)&x, SCARG(uap, data), sizeof x);
    436  1.1  jonathan 	    }
    437  1.1  jonathan 	case _IOR('t', 100, int):	/* sun SUNOS_TIOCSSOFTCAR */
    438  1.1  jonathan 	    {
    439  1.1  jonathan 		int x = 0;
    440  1.1  jonathan 
    441  1.1  jonathan 		return copyout((caddr_t)&x, SCARG(uap, data), sizeof x);
    442  1.1  jonathan 	    }
    443  1.1  jonathan 	case _IO('t', 36): 		/* sun TIOCCONS, no parameters */
    444  1.1  jonathan 	    {
    445  1.1  jonathan 		int on = 1;
    446  1.1  jonathan 		return (*ctl)(fp, TIOCCONS, (caddr_t)&on, p);
    447  1.1  jonathan 	    }
    448  1.1  jonathan 	case _IOW('t', 37, struct sunos_ttysize):
    449  1.1  jonathan 	    {
    450  1.1  jonathan 		struct winsize ws;
    451  1.1  jonathan 		struct sunos_ttysize ss;
    452  1.1  jonathan 
    453  1.1  jonathan 		if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
    454  1.1  jonathan 			return (error);
    455  1.1  jonathan 
    456  1.1  jonathan 		if ((error = copyin (SCARG(uap, data), &ss, sizeof (ss))) != 0)
    457  1.1  jonathan 			return error;
    458  1.1  jonathan 
    459  1.1  jonathan 		ws.ws_row = ss.ts_row;
    460  1.1  jonathan 		ws.ws_col = ss.ts_col;
    461  1.1  jonathan 
    462  1.1  jonathan 		return ((*ctl)(fp, TIOCSWINSZ, (caddr_t)&ws, p));
    463  1.1  jonathan 	    }
    464  1.1  jonathan 	case _IOW('t', 38, struct sunos_ttysize):
    465  1.1  jonathan 	    {
    466  1.1  jonathan 		struct winsize ws;
    467  1.1  jonathan 		struct sunos_ttysize ss;
    468  1.1  jonathan 
    469  1.1  jonathan 		if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
    470  1.1  jonathan 			return (error);
    471  1.1  jonathan 
    472  1.1  jonathan 		ss.ts_row = ws.ws_row;
    473  1.1  jonathan 		ss.ts_col = ws.ws_col;
    474  1.1  jonathan 
    475  1.1  jonathan 		return copyout ((caddr_t)&ss, SCARG(uap, data), sizeof (ss));
    476  1.1  jonathan 	    }
    477  1.1  jonathan 	case _IOW('t', 130, int):
    478  1.1  jonathan 		SCARG(uap, com) = TIOCSPGRP;
    479  1.1  jonathan 		break;
    480  1.1  jonathan 	case _IOR('t', 131, int):
    481  1.1  jonathan 		SCARG(uap, com) = TIOCGPGRP;
    482  1.1  jonathan 		break;
    483  1.1  jonathan 	case _IO('t', 132):
    484  1.1  jonathan 		SCARG(uap, com) = TIOCSCTTY;
    485  1.1  jonathan 		break;
    486  1.1  jonathan 	case ULTRIX_TCGETA:
    487  1.1  jonathan 	case ULTRIX_TCGETS:
    488  1.1  jonathan 	    {
    489  1.1  jonathan 		struct termios bts;
    490  1.1  jonathan 		struct ultrix_termios sts;
    491  1.1  jonathan 		struct ultrix_termio st;
    492  1.1  jonathan 
    493  1.1  jonathan 		if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
    494  1.1  jonathan 			return error;
    495  1.1  jonathan 
    496  1.1  jonathan 		btios2stios (&bts, &sts);
    497  1.1  jonathan 		if (SCARG(uap, com) == ULTRIX_TCGETA) {
    498  1.1  jonathan 			stios2stio (&sts, &st);
    499  1.1  jonathan 			return copyout((caddr_t)&st, SCARG(uap, data),
    500  1.1  jonathan 			    sizeof (st));
    501  1.1  jonathan 		} else
    502  1.1  jonathan 			return copyout((caddr_t)&sts, SCARG(uap, data),
    503  1.1  jonathan 			    sizeof (sts));
    504  1.1  jonathan 		/*NOTREACHED*/
    505  1.1  jonathan 	    }
    506  1.1  jonathan 	case ULTRIX_TCSETA:
    507  1.1  jonathan 	case ULTRIX_TCSETAW:
    508  1.1  jonathan 	case ULTRIX_TCSETAF:
    509  1.1  jonathan 	    {
    510  1.1  jonathan 		struct termios bts;
    511  1.1  jonathan 		struct ultrix_termios sts;
    512  1.1  jonathan 		struct ultrix_termio st;
    513  1.1  jonathan 		int result;
    514  1.1  jonathan 
    515  1.1  jonathan 		if ((error = copyin(SCARG(uap, data), (caddr_t)&st,
    516  1.1  jonathan 		    sizeof (st))) != 0)
    517  1.1  jonathan 			return error;
    518  1.1  jonathan 
    519  1.1  jonathan 		/* get full BSD termios so we don't lose information */
    520  1.1  jonathan 		if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
    521  1.1  jonathan 			return error;
    522  1.1  jonathan 
    523  1.1  jonathan 		/*
    524  1.1  jonathan 		 * convert to sun termios, copy in information from
    525  1.1  jonathan 		 * termio, and convert back, then set new values.
    526  1.1  jonathan 		 */
    527  1.1  jonathan 		btios2stios(&bts, &sts);
    528  1.1  jonathan 		stio2stios(&st, &sts);
    529  1.1  jonathan 		stios2btios(&sts, &bts);
    530  1.1  jonathan 
    531  1.1  jonathan 		/*
    532  1.1  jonathan 		 * map ioctl code: ultrix tcsets are numbered in reverse order
    533  1.1  jonathan 		 */
    534  1.1  jonathan #ifdef notyet
    535  1.1  jonathan 		return (*ctl)(fp, ULTRIX_TCSETA - SCARG(uap, com) + TIOCSETA,
    536  1.1  jonathan 		    (caddr_t)&bts, p);
    537  1.1  jonathan #else
    538  1.1  jonathan 		result= (*ctl)(fp, ULTRIX_TCSETA -  SCARG(uap, com) + TIOCSETA,
    539  1.1  jonathan 		    (caddr_t)&bts, p);
    540  1.1  jonathan 		printf("ultrix TCSETA %x returns %d\n",
    541  1.1  jonathan 		       ULTRIX_TCSETA - SCARG(uap, com), result);
    542  1.1  jonathan 		return result;
    543  1.1  jonathan #endif
    544  1.1  jonathan 
    545  1.1  jonathan 	    }
    546  1.1  jonathan 	case ULTRIX_TCSETS:
    547  1.1  jonathan 	case ULTRIX_TCSETSW:
    548  1.1  jonathan 	case ULTRIX_TCSETSF:
    549  1.1  jonathan 	    {
    550  1.1  jonathan 		struct termios bts;
    551  1.1  jonathan 		struct ultrix_termios sts;
    552  1.1  jonathan 		int result;
    553  1.1  jonathan 
    554  1.1  jonathan 		if ((error = copyin (SCARG(uap, data), (caddr_t)&sts,
    555  1.1  jonathan 		    sizeof (sts))) != 0)
    556  1.1  jonathan 			return error;
    557  1.1  jonathan 		stios2btios (&sts, &bts);
    558  1.1  jonathan #ifndef DEBUG
    559  1.1  jonathan 		return (*ctl)(fp, ULTRIX_TCSETS - SCARG(uap, com) + TIOCSETA,
    560  1.1  jonathan 		    (caddr_t)&bts, p);
    561  1.1  jonathan #else
    562  1.1  jonathan 		result = (*ctl)(fp, ULTRIX_TCSETS - SCARG(uap, com) + TIOCSETA,
    563  1.1  jonathan 		    (caddr_t)&bts, p);
    564  1.1  jonathan 	printf("ultrix TCSETS %x returns %d\n",
    565  1.1  jonathan 	       ULTRIX_TCSETS - SCARG(uap, com), result);
    566  1.1  jonathan 		return result;
    567  1.1  jonathan #endif
    568  1.1  jonathan 	    }
    569  1.1  jonathan /*
    570  1.1  jonathan  * Pseudo-tty ioctl translations.
    571  1.1  jonathan  */
    572  1.1  jonathan 	case _IOW('t', 32, int): {	/* TIOCTCNTL */
    573  1.1  jonathan 		int error, on;
    574  1.1  jonathan 
    575  1.1  jonathan 		if (error = copyin (SCARG(uap, data), (caddr_t)&on, sizeof (on)))
    576  1.1  jonathan 			return error;
    577  1.1  jonathan 		return (*ctl)(fp, TIOCUCNTL, (caddr_t)&on, p);
    578  1.1  jonathan 	}
    579  1.1  jonathan 	case _IOW('t', 33, int): {	/* TIOCSIGNAL */
    580  1.1  jonathan 		int error, sig;
    581  1.1  jonathan 
    582  1.1  jonathan 		if (error = copyin (SCARG(uap, data), (caddr_t)&sig, sizeof (sig)))
    583  1.1  jonathan 			return error;
    584  1.1  jonathan 		return (*ctl)(fp, TIOCSIG, (caddr_t)&sig, p);
    585  1.1  jonathan 	}
    586  1.1  jonathan 
    587  1.1  jonathan /*
    588  1.1  jonathan  * Socket ioctl translations.
    589  1.1  jonathan  */
    590  1.1  jonathan #define IFREQ_IN(a) { \
    591  1.1  jonathan 	struct ifreq ifreq; \
    592  1.1  jonathan 	if (error = copyin (SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq))) \
    593  1.1  jonathan 		return error; \
    594  1.1  jonathan 	return (*ctl)(fp, a, (caddr_t)&ifreq, p); \
    595  1.1  jonathan }
    596  1.1  jonathan #define IFREQ_INOUT(a) { \
    597  1.1  jonathan 	struct ifreq ifreq; \
    598  1.1  jonathan 	if (error = copyin (SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq))) \
    599  1.1  jonathan 		return error; \
    600  1.1  jonathan 	if (error = (*ctl)(fp, a, (caddr_t)&ifreq, p)) \
    601  1.1  jonathan 		return error; \
    602  1.1  jonathan 	return copyout ((caddr_t)&ifreq, SCARG(uap, data), sizeof (ifreq)); \
    603  1.1  jonathan }
    604  1.1  jonathan 
    605  1.1  jonathan 	case _IOW('i', 12, struct ifreq):
    606  1.1  jonathan 		/* SIOCSIFADDR */
    607  1.1  jonathan 		break;
    608  1.1  jonathan 
    609  1.1  jonathan 	case _IOWR('i', 13, struct ifreq):
    610  1.1  jonathan 		IFREQ_INOUT(OSIOCGIFADDR);
    611  1.1  jonathan 
    612  1.1  jonathan 	case _IOW('i', 14, struct ifreq):
    613  1.1  jonathan 		/* SIOCSIFDSTADDR */
    614  1.1  jonathan 		break;
    615  1.1  jonathan 
    616  1.1  jonathan 	case _IOWR('i', 15, struct ifreq):
    617  1.1  jonathan 		IFREQ_INOUT(OSIOCGIFDSTADDR);
    618  1.1  jonathan 
    619  1.1  jonathan 	case _IOW('i', 16, struct ifreq):
    620  1.1  jonathan 		/* SIOCSIFFLAGS */
    621  1.1  jonathan 		break;
    622  1.1  jonathan 
    623  1.1  jonathan 	case _IOWR('i', 17, struct ifreq):
    624  1.1  jonathan 		/* SIOCGIFFLAGS */
    625  1.1  jonathan 		break;
    626  1.1  jonathan 
    627  1.1  jonathan 	case _IOW('i', 21, struct ifreq):
    628  1.1  jonathan 		IFREQ_IN(SIOCSIFMTU);
    629  1.1  jonathan 
    630  1.1  jonathan 	case _IOWR('i', 22, struct ifreq):
    631  1.1  jonathan 		IFREQ_INOUT(SIOCGIFMTU);
    632  1.1  jonathan 
    633  1.1  jonathan 	case _IOWR('i', 23, struct ifreq):
    634  1.1  jonathan 		IFREQ_INOUT(SIOCGIFBRDADDR);
    635  1.1  jonathan 
    636  1.1  jonathan 	case _IOW('i', 24, struct ifreq):
    637  1.1  jonathan 		IFREQ_IN(SIOCSIFBRDADDR);
    638  1.1  jonathan 
    639  1.1  jonathan 	case _IOWR('i', 25, struct ifreq):
    640  1.1  jonathan 		IFREQ_INOUT(OSIOCGIFNETMASK);
    641  1.1  jonathan 
    642  1.1  jonathan 	case _IOW('i', 26, struct ifreq):
    643  1.1  jonathan 		IFREQ_IN(SIOCSIFNETMASK);
    644  1.1  jonathan 
    645  1.1  jonathan 	case _IOWR('i', 27, struct ifreq):
    646  1.1  jonathan 		IFREQ_INOUT(SIOCGIFMETRIC);
    647  1.1  jonathan 
    648  1.1  jonathan 	case _IOWR('i', 28, struct ifreq):
    649  1.1  jonathan 		IFREQ_IN(SIOCSIFMETRIC);
    650  1.1  jonathan 
    651  1.1  jonathan 	case _IOW('i', 30, struct arpreq):
    652  1.1  jonathan 		/* SIOCSARP */
    653  1.1  jonathan 		break;
    654  1.1  jonathan 
    655  1.1  jonathan 	case _IOWR('i', 31, struct arpreq):
    656  1.1  jonathan 		/* SIOCGARP */
    657  1.1  jonathan 		break;
    658  1.1  jonathan 
    659  1.1  jonathan 	case _IOW('i', 32, struct arpreq):
    660  1.1  jonathan 		/* SIOCDARP */
    661  1.1  jonathan 		break;
    662  1.1  jonathan 
    663  1.1  jonathan 	case _IOW('i', 18, struct ifreq):	/* SIOCSIFMEM */
    664  1.1  jonathan 	case _IOWR('i', 19, struct ifreq):	/* SIOCGIFMEM */
    665  1.1  jonathan 	case _IOW('i', 40, struct ifreq):	/* SIOCUPPER */
    666  1.1  jonathan 	case _IOW('i', 41, struct ifreq):	/* SIOCLOWER */
    667  1.1  jonathan 	case _IOW('i', 44, struct ifreq):	/* SIOCSETSYNC */
    668  1.1  jonathan 	case _IOWR('i', 45, struct ifreq):	/* SIOCGETSYNC */
    669  1.1  jonathan 	case _IOWR('i', 46, struct ifreq):	/* SIOCSDSTATS */
    670  1.1  jonathan 	case _IOWR('i', 47, struct ifreq):	/* SIOCSESTATS */
    671  1.1  jonathan 	case _IOW('i', 48, int):		/* SIOCSPROMISC */
    672  1.1  jonathan 	case _IOW('i', 49, struct ifreq):	/* SIOCADDMULTI */
    673  1.1  jonathan 	case _IOW('i', 50, struct ifreq):	/* SIOCDELMULTI */
    674  1.1  jonathan 		return EOPNOTSUPP;
    675  1.1  jonathan 
    676  1.1  jonathan 	case _IOWR('i', 20, struct ifconf):	/* SIOCGIFCONF */
    677  1.1  jonathan 	    {
    678  1.1  jonathan 		struct ifconf ifconf;
    679  1.1  jonathan 
    680  1.1  jonathan 		/*
    681  1.1  jonathan 		 * XXX: two more problems
    682  1.1  jonathan 		 * 1. our sockaddr's are variable length, not always sizeof(sockaddr)
    683  1.1  jonathan 		 * 2. this returns a name per protocol, ie. it returns two "lo0"'s
    684  1.1  jonathan 		 */
    685  1.1  jonathan 		if (error = copyin (SCARG(uap, data), (caddr_t)&ifconf,
    686  1.1  jonathan 		    sizeof (ifconf)))
    687  1.1  jonathan 			return error;
    688  1.1  jonathan 		if (error = (*ctl)(fp, OSIOCGIFCONF, (caddr_t)&ifconf, p))
    689  1.1  jonathan 			return error;
    690  1.1  jonathan 		return copyout ((caddr_t)&ifconf, SCARG(uap, data),
    691  1.1  jonathan 		    sizeof (ifconf));
    692  1.1  jonathan 	    }
    693  1.1  jonathan 
    694  1.1  jonathan 	}
    695  1.1  jonathan 	return (sys_ioctl(p, uap, retval));
    696  1.1  jonathan }
    697