1 /* source: xioopts.h */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
3 /* Published under the GNU General Public License V.2, see file COPYING */
4 
5 #ifndef __xioopts_h_included
6 #define __xioopts_h_included 1
7 
8 #define ODESC_END ((void *)0)	/* indicates end of actual option array */
9 #define ODESC_DONE ((void *)-1)	/* indicates that option has been applied */
10 #define ODESC_ERROR ODESC_DONE	/* maybe later */
11 
12 #define XIO_OFFSETOF(x) ((size_t)&((xiosingle_t *)0)->x)
13 #define XIO_SIZEOF(x) (sizeof(((struct single *)0)->x))
14 
15 /* atomic structure for use in the option search table; keep compatible with
16    struct wordent! */
17 struct optname {
18    const char *name;
19    const struct optdesc *desc;
20 } ;
21 
22 /* keep consistent with xiohelp.c:optiontypenames[] ! */
23 enum e_types {
24    TYPE_CONST,		/* keyword means a fix value - implies int type */
25    TYPE_BIN,		/* raw binary data, length determined by data */
26    TYPE_BOOL,		/* value is 0 or 1 (no-value is interpreted as 1) */
27    TYPE_BYTE,		/* unsigned char */
28 
29    TYPE_INT,		/* int */
30    TYPE_LONG,		/* long */
31    TYPE_STRING,		/* char * */
32    TYPE_NAME = TYPE_STRING,
33    TYPE_FILENAME = TYPE_STRING,
34    TYPE_PTRDIFF,	/* ptrdiff_t */
35 
36    TYPE_SHORT,		/* short */
37    TYPE_SIZE_T,		/* size_t */
38    TYPE_SOCKADDR,	/* struct sockaddr * */
39    TYPE_UINT,		/* unsigned int */
40 
41    TYPE_ULONG,		/* unsigned long */
42    TYPE_USHORT,		/* unsigned short */
43    TYPE_2BYTE = TYPE_USHORT,
44    TYPE_MODET,		/* representation of mode_t */
45    TYPE_GIDT,		/* representation of gid_t */
46 
47    TYPE_UIDT,		/* representation of uid_t */
48    /*TYPE_FLAG,*/
49    TYPE_INT3,		/* int[3] */
50    TYPE_TIMEVAL,	/* struct timeval: {long;long;}, seconds and microsec. */
51    TYPE_TIMESPEC,	/* struct timespec: {time_t;long;}, seconds and nanosec. */
52 
53    TYPE_DOUBLE,		/* double */
54    TYPE_STRING_NULL,	/* char *; string or NULL */
55    TYPE_LONGLONG,	/* long long */
56    TYPE_OFF32,		/* off_t */
57 
58    TYPE_OFF64,		/* off64_t */
59    TYPE_INT_INT,	/* 2 parameters: first is int, second is int */
60    TYPE_INT_INTP,	/* 2 parameters: first is int, second is int* */
61    TYPE_INT_BIN,	/* 2 parameters: first is int, second is binary */
62 
63    TYPE_INT_STRING,	/* 2 parameters: first is int, second is req string */
64    TYPE_INT_INT_INT,	/* 3 params: first and second are int, 3rd is int */
65    TYPE_INT_INT_BIN,	/* 3 params: first and second are int, 3rd is binary */
66    TYPE_INT_INT_STRING,	/* 3 params: first and second are int, 3rd is string */
67    TYPE_INT_INT_GENERIC,	/* 3 params: first and second are int, 3rd is specified by value (dalan syntax) */
68 
69    TYPE_IP4NAME,	/* IPv4 hostname or address */
70 #if HAVE_STRUCT_LINGER
71    TYPE_LINGER,		/* struct linger */
72 #endif /* HAVE_STRUCT_LINGER */
73 #if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IP_MREQN
74    TYPE_IP_MREQN,	/* for  struct ip_mreq  or  struct ip_mreqn */
75 #endif
76 #if HAVE_STRUCT_IP_MREQ_SOURCE
77    TYPE_IP_MREQ_SOURCE,	/* for  struct ip_mreq_source */
78 #endif
79 
80    TYPE_GENERIC, 	/* type is determined from (text) data provided (dalan syntax) */
81 } ;
82 
83 enum e_func {
84    OFUNC_NONE,		/* no function - should not occur */
85    OFUNC_FLAG,		/* no function, but bitposition, only with bool; arg1 is mask */
86    OFUNC_FLAG_PATTERN,	/* no function, but bitpattern: arg1 is pattern, arg2 is mask */
87    OFUNC_SEEK32,	/* lseek(): arg1 is whence (SEEK_SET etc.) */
88    OFUNC_SEEK64,	/* lseek64(): arg1 is whence (SEEK_SET etc.) */
89    OFUNC_FCNTL,		/* fcntl(, ): arg1 is cmd */
90    OFUNC_IOCTL,		/* ioctl(): arg1 of option description is request, arg2
91 			   is int setrequest */
92    OFUNC_IOCTL_MASK_LONG,	/* arg1 is getrequest, arg2 is setrequest:
93 			   ioctl(arg1, ); |= arg3; ioctl(arg2, ); */
94    OFUNC_IOCTL_GENERIC,	/* generic ioctl() (request on cmdline) */
95    OFUNC_SOCKOPT,	/* setsockopt() */
96    OFUNC_SOCKOPT_APPEND,/* getsockopt(), append data, setsockopt() */
97    OFUNC_SOCKOPT_GENERIC,/* generic setsockopt() (level, optname on cmdline) */
98    OFUNC_FLOCK,		/* flock() */
99    OFUNC_TERMIO,	/* termio() ? */
100    OFUNC_SPEC,		/* special, i.e. no generalizable function call */
101    OFUNC_OFFSET,	/* put a value into xiofile struct; major is offset */
102    OFUNC_OFFSET_MASKS,	/* !!! */
103    /*OFUNC_APPL,*/	/* special, i.e. application must know which f. */
104    OFUNC_EXT,		/* with extended file descriptors only */
105    OFUNC_TERMIOS_FLAG,	/* a flag in struct termios: major..tcflag, minor..bit
106 			 */
107    OFUNC_TERMIOS_PATTERN, /* a multibit: major..tcflag, minor..pattern,
108 			    arg3..mask */
109    OFUNC_TERMIOS_VALUE,	/* a variable value: major..tcflag, minor..mask, arg3..shift */
110    OFUNC_TERMIOS_CHAR,	/* a termios functional character: major..c_cc index */
111    OFUNC_TERMIOS_SPEED,	/* termios c_ispeed etc on FreeBSD */
112    OFUNC_TERMIOS_SPEC,	/* termios combined modes */
113    OFUNC_SIGNAL,	/* a signal that should be passed to child process */
114    OFUNC_RESOLVER,	/* a bit position used on _res.options */
115    OFUNC_IFFLAG,	/* interface flag: locical-or a 1bit mask */
116 #  define ENABLE_OFUNC
117 #  include "xio-streams.h"	/* push a POSIX STREAMS module */
118 #  undef ENABLE_OFUNC
119 } ;
120 
121 /* for simpler handling of option-to-connection-type relations we define
122    groups. to keep the search for options simple, we allow each option to
123    belong to at most one group only. (we have a dummy GROUP_NONE for those
124    that don't want to belong to any...)
125    The caller of parseopts() specifies per bitpatter a set of groups where it
126    accepts options from.
127 */
128 
129 /*- the group bits are:
130 -   000ooooo 00000000 000000uf 0000ssss
131 -   ooooo: more detailed description to ssss (e.g., socket family)
132 -   ssss: the type of stream, as in stat.h: S_IF...
133 -   f: has a named entry in the file system
134 -   u: has user and group
135 */
136 /* keep consistent with xiohelp.c:addressgroupnames[] ! */
137 /* a dummy group */
138 #define GROUP_NONE	0x00000000
139 
140 #define GROUP_FD	0x00000001	/* everything applyable to a fd */
141 #define GROUP_FIFO	0x00000002
142 #define GROUP_CHR	0x00000004
143 #define GROUP_BLK	0x00000008
144 #define GROUP_REG	0x00000010
145 #define GROUP_FILE GROUP_REG
146 #define GROUP_SOCKET	0x00000020
147 #define GROUP_READLINE	0x00000040
148 
149 #define GROUP_NAMED	0x00000100	/* file system entry */
150 #define GROUP_OPEN	0x00000200	/* flags for open() */
151 #define GROUP_EXEC	0x00000400	/* program or script execution */
152 #define GROUP_FORK	0x00000800	/* communication with forked process */
153 
154 #define GROUP_LISTEN	0x00001000	/* socket in listening mode */
155 /*	0x00002000 */
156 #define GROUP_CHILD	0x00004000	/* autonom child process */
157 #define GROUP_RETRY	0x00008000	/* when open/connect etc. fails */
158 #define GROUP_TERMIOS	0x00010000
159 #define GROUP_RANGE	0x00020000	/* differs from GROUP_LISTEN */
160 #define GROUP_PTY	0x00040000	/* address pty or exec...,pty */
161 #define GROUP_PARENT	0x00080000	/* for parent of communicating child */
162 
163 #define GROUP_SOCK_UNIX	0x00100000
164 #define GROUP_SOCK_IP4	0x00200000
165 #define GROUP_SOCK_IP6	0x00400000
166 #define GROUP_SOCK_IP	(GROUP_SOCK_IP4|GROUP_SOCK_IP6)
167 #define GROUP_INTERFACE	0x00800000
168 #define GROUP_TUN       GROUP_INTERFACE
169 
170 #define GROUP_IP_UDP	0x01000000
171 #define GROUP_IP_TCP	0x02000000
172 #define GROUP_IPAPP	(GROUP_IP_UDP|GROUP_IP_TCP|GROUP_IP_SCTP)	/* true: indicates one of UDP, TCP, SCTP */
173 #define GROUP_IP_SOCKS4	0x04000000
174 #define GROUP_OPENSSL	0x08000000
175 
176 #define GROUP_PROCESS	0x10000000	/* a process related option */
177 #define GROUP_APPL	0x20000000	/* option handled by data loop */
178 #define GROUP_HTTP	0x40000000	/* any HTTP client */
179 #define GROUP_IP_SCTP	0x80000000
180 
181 #define GROUP_ANY	(GROUP_PROCESS|GROUP_APPL)
182 #define GROUP_ALL	0xffffffff
183 
184 
185 /* no IP multicasts, no error queue yet */
186 /* the only reason for keeping this enum sorted is to help detecting name
187    conflicts. */
188 /* optcode's */
189 enum e_optcode {
190    OPT_ADDRESS_FAMILY = 1,
191    /* these are not alphabetically, I know... */
192    OPT_B0,		/* termios.c_cflag */
193    OPT_B50,		/* termios.c_cflag */
194    OPT_B75,		/* termios.c_cflag */
195    OPT_B110,		/* termios.c_cflag */
196    OPT_B134,		/* termios.c_cflag */
197    OPT_B150,		/* termios.c_cflag */
198    OPT_B200,		/* termios.c_cflag */
199    OPT_B300,		/* termios.c_cflag */
200    OPT_B600,		/* termios.c_cflag */
201    OPT_B900,		/* termios.c_cflag - HP-UX */
202    OPT_B1200,		/* termios.c_cflag */
203    OPT_B1800,		/* termios.c_cflag */
204    OPT_B2400,		/* termios.c_cflag */
205    OPT_B3600,		/* termios.c_cflag - HP-UX */
206    OPT_B4800,		/* termios.c_cflag */
207    OPT_B7200,		/* termios.c_cflag - HP-UX */
208    OPT_B9600,		/* termios.c_cflag */
209    OPT_B19200,		/* termios.c_cflag */
210    OPT_B38400,		/* termios.c_cflag */
211    OPT_B57600,		/* termios.c_cflag */
212    OPT_B115200,		/* termios.c_cflag */
213    OPT_B230400,		/* termios.c_cflag */
214    OPT_B460800,		/* termios.c_cflag */
215    OPT_B500000,		/* termios.c_cflag */
216    OPT_B576000,		/* termios.c_cflag */
217    OPT_B921600,		/* termios.c_cflag */
218    OPT_B1000000,	/* termios.c_cflag */
219    OPT_B1152000,	/* termios.c_cflag */
220    OPT_B1500000,	/* termios.c_cflag */
221    OPT_B2000000,	/* termios.c_cflag */
222    OPT_B2500000,	/* termios.c_cflag */
223    OPT_B3000000,	/* termios.c_cflag */
224    OPT_B3500000,	/* termios.c_cflag */
225    OPT_B4000000,	/* termios.c_cflag */
226    OPT_BACKLOG,
227    OPT_BIND,	/* a socket address as character string */
228    OPT_BRKINT,		/* termios.c_iflag */
229 #ifdef BSDLY
230 #  ifdef BS0
231    OPT_BS0,		/* termios.c_oflag */
232 #  endif
233 #  ifdef BS1
234    OPT_BS1,		/* termios.c_oflag */
235 #  endif
236    OPT_BSDLY,		/* termios.c_oflag */
237 #endif
238    OPT_CHROOT,		/* chroot() past file system access */
239    OPT_CHROOT_EARLY,	/* chroot() before file system access */
240    /*OPT_CIBAUD,*/		/* termios.c_cflag */
241    OPT_CLOCAL,		/* termios.c_cflag */
242    OPT_CLOEXEC,
243    OPT_CONNECT_TIMEOUT,	/* socket connect */
244    OPT_COOL_WRITE,
245    OPT_CR,		/* customized */
246 #ifdef CR0
247    OPT_CR0,		/* termios.c_oflag */
248 #endif
249 #ifdef CR1
250    OPT_CR1,		/* termios.c_oflag */
251 #endif
252 #ifdef CR2
253    OPT_CR2,		/* termios.c_oflag */
254 #endif
255 #ifdef CR3
256    OPT_CR3,		/* termios.c_oflag */
257 #endif
258 #ifdef CRDLY
259    OPT_CRDLY,		/* termios.c_oflag */
260 #endif
261    OPT_CREAD,		/* termios.c_cflag */
262    OPT_CRNL,		/* customized */
263 #ifdef CRTSCTS
264    OPT_CRTSCTS,		/* termios.c_cflag */
265 #endif
266    OPT_CS5,		/* termios.c_cflag */
267    OPT_CS6,		/* termios.c_cflag */
268    OPT_CS7,		/* termios.c_cflag */
269    OPT_CS8,		/* termios.c_cflag */
270    OPT_CSIZE,		/* termios.c_cflag */
271    OPT_CSTOPB,		/* termios.c_cflag */
272    OPT_DASH,		/* exec() */
273    OPT_ECHO,		/* termios.c_lflag */
274    OPT_ECHOCTL,		/* termios.c_lflag */
275    OPT_ECHOE,		/* termios.c_lflag */
276    OPT_ECHOK,		/* termios.c_lflag */
277    OPT_ECHOKE,		/* termios.c_lflag */
278    OPT_ECHONL,		/* termios.c_lflag */
279 #ifdef ECHOPRT
280    OPT_ECHOPRT,		/* termios.c_lflag */
281 #endif
282    OPT_END_CLOSE,	/* xfd.stream.howtoend = END_CLOSE */
283    OPT_ESCAPE,
284    OPT_FDIN,
285    OPT_FDOUT,
286 #ifdef FFDLY
287 #  ifdef FF0
288    OPT_FF0,		/* termios.c_oflag */
289 #  endif
290 #  ifdef FF1
291    OPT_FF1,		/* termios.c_oflag */
292 #  endif
293    OPT_FFDLY,		/* termios.c_oflag */
294 #endif
295 #ifdef FIOSETOWN
296    OPT_FIOSETOWN,	/* asm/sockios.h */
297 #endif
298    OPT_FLOCK_EX,	/* flock(fd, LOCK_EX) */
299    OPT_FLOCK_EX_NB,	/* flock(fd, LOCK_EX|LOCK_NB) */
300    OPT_FLOCK_SH,	/* flock(fd, LOCK_SH) */
301    OPT_FLOCK_SH_NB,	/* flock(fd, LOCK_SH|LOCK_NB) */
302    OPT_FLUSHO,		/* termios.c_lflag */
303    /*0 OPT_FORCE,*/
304    OPT_FOREVER,
305    OPT_FORK,
306    OPT_FS_APPEND,
307    OPT_FS_COMPR,
308    OPT_FS_DIRSYNC,
309    OPT_FS_IMMUTABLE,
310    OPT_FS_JOURNAL_DATA,
311    OPT_FS_NOATIME,
312    OPT_FS_NODUMP,
313    OPT_FS_NOTAIL,
314    OPT_FS_SECRM,
315    OPT_FS_SYNC,
316    OPT_FS_TOPDIR,
317    OPT_FS_UNRM,
318    OPT_FTRUNCATE32,	/* ftruncate() */
319    OPT_FTRUNCATE64,	/* ftruncate64() */
320    OPT_F_SETLKW_RD,	/* fcntl with struct flock - read-lock, wait */
321    OPT_F_SETLKW_WR,	/* fcntl with struct flock - write-lock, wait */
322    OPT_F_SETLK_RD,	/* fcntl with struct flock - read-lock */
323    OPT_F_SETLK_WR,	/* fcntl with struct flock - write-lock */
324    OPT_GROUP,
325    OPT_GROUP_EARLY,
326    OPT_GROUP_LATE,
327    OPT_HISTORY_FILE,	/* readline history file */
328    OPT_HUPCL,		/* termios.c_cflag */
329    OPT_ICANON,		/* termios.c_lflag */
330    OPT_ICRNL,		/* termios.c_iflag */
331    OPT_IEXTEN,		/* termios.c_lflag */
332    OPT_IFF_ALLMULTI,	/* struct ifreq.ifr_flags */
333    OPT_IFF_AUTOMEDIA,	/* struct ifreq.ifr_flags */
334    OPT_IFF_BROADCAST,	/* struct ifreq.ifr_flags */
335    OPT_IFF_DEBUG,	/* struct ifreq.ifr_flags */
336    /*OPT_IFF_DYNAMIC,*/	/* struct ifreq.ifr_flags */
337    OPT_IFF_LOOPBACK,	/* struct ifreq.ifr_flags */
338    OPT_IFF_MASTER,	/* struct ifreq.ifr_flags */
339    OPT_IFF_MULTICAST,	/* struct ifreq.ifr_flags */
340    OPT_IFF_NOARP,	/* struct ifreq.ifr_flags */
341    OPT_IFF_NOTRAILERS,	/* struct ifreq.ifr_flags */
342    OPT_IFF_NO_PI,	/* tun: IFF_NO_PI */
343    OPT_IFF_PORTSEL,	/* struct ifreq.ifr_flags */
344    OPT_IFF_POINTOPOINT,	/* struct ifreq.ifr_flags */
345    OPT_IFF_PROMISC,	/* struct ifreq.ifr_flags */
346    OPT_IFF_RUNNING,	/* struct ifreq.ifr_flags */
347    OPT_IFF_SLAVE,	/* struct ifreq.ifr_flags */
348    OPT_IFF_UP,		/* struct ifreq.ifr_flags */
349    OPT_IGNBRK,		/* termios.c_iflag */
350    OPT_IGNCR,		/* termios.c_iflag */
351    OPT_IGNORECR,	/* HTTP */
352    OPT_IGNOREEOF,	/* customized */
353    OPT_IGNPAR,		/* termios.c_iflag */
354    OPT_IMAXBEL,		/* termios.c_iflag */
355    OPT_INLCR,		/* termios.c_iflag */
356    OPT_INPCK,		/* termios.c_iflag */
357    OPT_INTERVALL,
358    OPT_IPV6_AUTHHDR,
359    OPT_IPV6_DSTOPTS,
360    OPT_IPV6_FLOWINFO,
361    OPT_IPV6_HOPLIMIT,
362    OPT_IPV6_HOPOPTS,
363    OPT_IPV6_JOIN_GROUP,
364    OPT_IPV6_PKTINFO,
365    OPT_IPV6_RECVDSTOPTS,
366    OPT_IPV6_RECVERR,
367    OPT_IPV6_RECVHOPLIMIT,
368    OPT_IPV6_RECVHOPOPTS,
369    OPT_IPV6_RECVPATHMTU,
370    OPT_IPV6_RECVPKTINFO,
371    OPT_IPV6_RECVRTHDR,
372    OPT_IPV6_RECVTCLASS,
373    OPT_IPV6_RTHDR,
374    OPT_IPV6_TCLASS,
375    OPT_IPV6_UNICAST_HOPS,
376    OPT_IPV6_V6ONLY,
377 #if 0	/* see Linux: man 7 netlink; probably not what we need yet */
378    OPT_IO_SIOCGIFNAME,
379 #endif
380    OPT_IOCTL_BIN,	/* generic ioctl with binary value (pointed to) */
381    OPT_IOCTL_INT,	/* generic ioctl with integer value */
382    OPT_IOCTL_INTP,	/* generic ioctl with integer value (pointed to) */
383    OPT_IOCTL_STRING,	/* generic ioctl with integer value (pointed to) */
384    OPT_IOCTL_VOID,	/* generic ioctl without value */
385    OPT_IP_ADD_MEMBERSHIP,
386    OPT_IP_ADD_SOURCE_MEMBERSHIP,
387 #ifdef IP_HDRINCL
388    OPT_IP_HDRINCL,
389 #endif
390 #ifdef IP_FREEBIND
391    OPT_IP_FREEBIND,
392 #endif
393 #ifdef IP_MTU
394    OPT_IP_MTU,
395 #endif
396 #ifdef IP_MTU_DISCOVER
397    OPT_IP_MTU_DISCOVER,
398 #endif
399    OPT_IP_MULTICAST_IF,
400    OPT_IP_MULTICAST_LOOP,
401    OPT_IP_MULTICAST_TTL,
402    OPT_IP_OPTIONS,
403 #ifdef IP_PKTINFO
404    OPT_IP_PKTINFO,
405 #endif
406 #ifdef IP_PKTOPTIONS
407    OPT_IP_PKTOPTIONS,
408 #endif
409    OPT_IP_RECVDSTADDR,
410 #ifdef IP_RECVERR
411    OPT_IP_RECVERR,
412 #endif
413    OPT_IP_RECVIF,
414 #ifdef IP_RECVOPTS
415    OPT_IP_RECVOPTS,
416 #endif
417 #ifdef IP_RECVTOS
418    OPT_IP_RECVTOS,
419 #endif
420 #ifdef IP_RECVTTL
421    OPT_IP_RECVTTL,
422 #endif
423 #ifdef IP_RETOPTS
424    OPT_IP_RETOPTS,
425 #endif
426 #ifdef IP_ROUTER_ALERT
427    OPT_IP_ROUTER_ALERT,
428 #endif
429    OPT_IP_TOS,
430 #ifdef IP_TRANSPARENT
431    OPT_IP_TRANSPARENT,
432 #endif
433    OPT_IP_TTL,
434    OPT_ISIG,		/* termios.c_lflag */
435    OPT_ISPEED,		/* termios.c_ispeed */
436    OPT_ISTRIP,		/* termios.c_iflag */
437 #ifdef IUCLC
438    OPT_IUCLC,		/* termios.c_iflag */
439 #endif
440    OPT_IXANY,		/* termios.c_iflag */
441    OPT_IXOFF,		/* termios.c_iflag */
442    OPT_IXON,		/* termios.c_iflag */
443    OPT_ACCEPT_TIMEOUT,	/* listening socket */
444    OPT_LOCKFILE,
445    OPT_LOWPORT,
446    OPT_MAX_CHILDREN,
447 #ifdef NLDLY
448 #  ifdef NL0
449    OPT_NL0,		/* termios.c_oflag */
450 #  endif
451 #  ifdef NL0
452    OPT_NL1,		/* termios.c_oflag */
453 #  endif
454    OPT_NLDLY,		/* termios.c_oflag */
455 #endif
456    OPT_NOECHO,		/* readline */
457    OPT_NOFLSH,		/* termios.c_lflag */
458    OPT_NOFORK,		/* exec, system */
459    OPT_NOPROMPT,	/* readline */
460    OPT_NULL_EOF,	/* receiving empty packet triggers EOF */
461 #ifdef OCRNL
462    OPT_OCRNL,		/* termios.c_oflag */
463 #endif
464 #ifdef OFDEL
465    OPT_OFDEL,		/* termios.c_oflag */
466 #endif
467 #ifdef OFILL
468    OPT_OFILL,		/* termios.c_oflag */
469 #endif
470 #ifdef OLCUC
471    OPT_OLCUC,		/* termios.c_oflag */
472 #endif
473    OPT_ONLCR,		/* termios.c_oflag */
474 #ifdef ONLRET
475    OPT_ONLRET,		/* termios.c_oflag */
476 #endif
477 #ifdef ONOCR
478    OPT_ONOCR,		/* termios.c_oflag */
479 #endif
480 #if HAVE_OPENPTY
481    OPT_OPENPTY,
482 #endif
483    OPT_OPENSSL_CAFILE,
484    OPT_OPENSSL_CAPATH,
485    OPT_OPENSSL_CERTIFICATE,
486    OPT_OPENSSL_CIPHERLIST,
487    OPT_OPENSSL_COMMONNAME,
488 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
489    OPT_OPENSSL_COMPRESS,
490 #endif
491    OPT_OPENSSL_DHPARAM,
492    OPT_OPENSSL_EGD,
493    OPT_OPENSSL_FIPS,
494    OPT_OPENSSL_KEY,
495    OPT_OPENSSL_MAX_PROTO_VERSION,
496    OPT_OPENSSL_METHOD,
497    OPT_OPENSSL_MIN_PROTO_VERSION,
498    OPT_OPENSSL_NO_SNI,
499    OPT_OPENSSL_PSEUDO,
500    OPT_OPENSSL_SNIHOST,
501    OPT_OPENSSL_VERIFY,
502    OPT_OPOST,		/* termios.c_oflag */
503    OPT_OSPEED,		/* termios.c_ospeed */
504    OPT_O_APPEND,
505 #ifdef O_ASYNC
506    OPT_O_ASYNC,
507 #endif
508    OPT_O_BINARY,		/* Cygwin */
509    OPT_O_CREATE,
510 #ifdef O_DEFER
511    OPT_O_DEFER,
512 #endif
513 #ifdef O_DELAY
514    OPT_O_DELAY,
515 #endif
516 #ifdef O_DIRECT
517    OPT_O_DIRECT,
518 #endif
519 #ifdef O_DIRECTORY
520    OPT_O_DIRECTORY,
521 #endif
522 #ifdef O_DSYNC
523    OPT_O_DSYNC,
524 #endif
525    OPT_O_EXCL,
526 #ifdef O_LARGEFILE
527    OPT_O_LARGEFILE,
528 #endif
529 #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK)
530    OPT_O_NDELAY,
531 #endif
532    OPT_O_NOATIME,
533    OPT_O_NOCTTY,
534 #ifdef O_NOFOLLOW
535    OPT_O_NOFOLLOW,
536 #endif
537    OPT_O_NOINHERIT,		/* Cygwin */
538    OPT_O_NONBLOCK,
539 #ifdef O_NSHARE
540    OPT_O_NSHARE,
541 #endif
542 #ifdef O_PRIV
543    OPT_O_PRIV,
544 #endif
545    OPT_O_RDONLY,		/* open() */
546    OPT_O_RDWR,		/* open() */
547 #ifdef O_RSHARE
548    OPT_O_RSHARE,
549 #endif
550 #ifdef O_RSYNC
551    OPT_O_RSYNC,
552 #endif
553 #ifdef O_SYNC
554    OPT_O_SYNC,
555 #endif
556    OPT_O_TEXT,			/* Cygwin */
557    OPT_O_TRUNC,			/* open(): O_TRUNC */
558    OPT_O_WRONLY,		/* open() */
559    OPT_PARENB,		/* termios.c_cflag */
560    OPT_PARMRK,		/* termios.c_iflag */
561    OPT_PARODD,		/* termios.c_cflag */
562    OPT_PATH,
563 #ifdef PENDIN
564    OPT_PENDIN,		/* termios.c_lflag */
565 #endif
566    OPT_PERM,
567    OPT_PERM_EARLY,
568    OPT_PERM_LATE,
569    OPT_PIPES,
570    /*OPT_PORT,*/
571    OPT_PROMPT,		/* readline */
572    OPT_PROTOCOL,	/* 6=TCP, 17=UDP */
573    OPT_PROTOCOL_FAMILY,	/* 1=PF_UNIX, 2=PF_INET, 10=PF_INET6 */
574    OPT_PROXYPORT,
575    OPT_PROXY_AUTHORIZATION,
576    OPT_PROXY_AUTHORIZATION_FILE,
577    OPT_PROXY_RESOLVE,
578 #if HAVE_DEV_PTMX || HAVE_DEV_PTC
579    OPT_PTMX,
580 #endif
581    OPT_PTY,
582    OPT_PTY_INTERVALL,
583    OPT_PTY_WAIT_SLAVE,
584    OPT_RANGE,		/* restrict client socket address */
585    OPT_RAW,		/* termios */
586    OPT_READBYTES,
587    OPT_RES_AAONLY,	/* resolver(3) */
588    OPT_RES_DEBUG,	/* resolver(3) */
589    OPT_RES_DEFNAMES,	/* resolver(3) */
590    OPT_RES_DNSRCH,	/* resolver(3) */
591    OPT_RES_IGNTC,	/* resolver(3) */
592    OPT_RES_PRIMARY,	/* resolver(3) */
593    OPT_RES_RECURSE,	/* resolver(3) */
594    OPT_RES_STAYOPEN,	/* resolver(3) */
595    OPT_RES_USEVC,	/* resolver(3) */
596    OPT_RETRY,
597    OPT_SANE,		/* termios */
598    OPT_SCTP_MAXSEG,
599    OPT_SCTP_MAXSEG_LATE,
600    OPT_SCTP_NODELAY,
601    OPT_SEEK32_CUR,
602    OPT_SEEK32_END,
603    OPT_SEEK32_SET,
604    OPT_SEEK64_CUR,
605    OPT_SEEK64_END,
606    OPT_SEEK64_SET,
607    OPT_SETGID,
608    OPT_SETGID_EARLY,
609    OPT_SETPGID,
610    OPT_SETSID,
611    OPT_SETSOCKOPT_BIN,
612    OPT_SETSOCKOPT_INT,
613    OPT_SETSOCKOPT_LISTEN,
614    OPT_SETSOCKOPT_STRING,
615    OPT_SETUID,
616    OPT_SETUID_EARLY,
617    OPT_SHUT_CLOSE,
618    OPT_SHUT_DOWN,
619    OPT_SHUT_NONE,
620    OPT_SHUT_NULL,	/* send 0 bytes on shutdown */
621    OPT_SIGHUP,
622    OPT_SIGINT,
623    OPT_SIGQUIT,
624 #ifdef SIOCSPGRP
625    OPT_SIOCSPGRP,
626 #endif
627 #ifdef SO_ACCEPTCONN
628    OPT_SO_ACCEPTCONN,
629 #endif /* SO_ACCEPTCONN */
630 #ifdef SO_ATTACH_FILTER
631    OPT_SO_ATTACH_FILTER,
632 #endif
633 #ifdef SO_AUDIT	/* AIX 4.3.3 */
634    OPT_SO_AUDIT,
635 #endif /* SO_AUDIT */
636 #ifdef SO_BINDTODEVICE
637    OPT_SO_BINDTODEVICE,
638 #endif
639    OPT_SO_BROADCAST,
640 #ifdef SO_BSDCOMPAT
641    OPT_SO_BSDCOMPAT,
642 #endif
643 #ifdef SO_CKSUMRECV
644    OPT_SO_CKSUMRECV,
645 #endif /* SO_CKSUMRECV */
646    OPT_SO_DEBUG,
647 #ifdef SO_DETACH_FILTER
648    OPT_SO_DETACH_FILTER,
649 #endif
650 #ifdef SO_DGRAM_ERRIND
651    OPT_SO_DGRAM_ERRIND,
652 #endif
653 #ifdef SO_DONTLINGER
654    OPT_SO_DONTLINGER,
655 #endif
656    OPT_SO_DONTROUTE,
657    OPT_SO_ERROR,
658    OPT_SO_KEEPALIVE,
659 #ifdef SO_KERNACCEPT	/* AIX 4.3.3 */
660    OPT_SO_KERNACCEPT,
661 #endif /* SO_KERNACCEPT */
662    OPT_SO_LINGER,
663 #ifdef SO_NO_CHECK
664    OPT_SO_NO_CHECK,
665 #endif
666 #ifdef SO_NOREUSEADDR	/* AIX 4.3.3 */
667    OPT_SO_NOREUSEADDR,
668 #endif /* SO_NOREUSEADDR */
669    OPT_SO_OOBINLINE,
670 #ifdef SO_PASSCRED
671    OPT_SO_PASSCRED,
672 #endif
673 #ifdef SO_PEERCRED
674    OPT_SO_PEERCRED,
675 #endif
676 #ifdef SO_PRIORITY
677    OPT_SO_PRIORITY,
678 #endif
679    OPT_SO_PROTOTYPE,
680    OPT_SO_RCVBUF,
681    OPT_SO_RCVBUF_LATE,
682 #ifdef SO_RCVLOWAT
683    OPT_SO_RCVLOWAT,
684 #endif
685    OPT_SO_REUSEADDR,
686 #ifdef SO_REUSEPORT
687    OPT_SO_REUSEPORT,
688 #endif /* defined(SO_REUSEPORT) */
689 #ifdef SO_SECURITY_AUTHENTICATION
690    OPT_SO_SECURITY_AUTHENTICATION,
691 #endif
692 #ifdef SO_SECURITY_ENCRYPTION_NETWORK
693    OPT_SO_SECURITY_ENCRYPTION_NETWORK,
694 #endif
695 #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
696    OPT_SO_SECURITY_ENCRYPTION_TRANSPORT,
697 #endif
698    OPT_SO_SNDBUF,
699    OPT_SO_SNDBUF_LATE,
700 #ifdef SO_SNDLOWAT
701    OPT_SO_SNDLOWAT,
702 #endif
703    OPT_SO_TIMESTAMP,	/* Linux */
704    OPT_SO_TYPE,
705 #ifdef SO_USELOOPBACK
706    OPT_SO_USELOOPBACK,
707 #endif /* SO_USELOOPBACK */
708 #ifdef SO_USE_IFBUFS
709    OPT_SO_USE_IFBUFS,
710 #endif /* SO_USE_IFBUFS */
711 #if 1 || defined(WITH_SOCKS4)
712    OPT_SOCKSPORT,
713    OPT_SOCKSUSER,
714 #endif
715    OPT_SOURCEPORT,
716    OPT_STDERR,		/* with exec, system */
717 #  define ENABLE_OPTCODE
718 #  include "xio-streams.h"
719 #  undef ENABLE_OPTCODE
720    OPT_SUBSTUSER_EARLY,
721    OPT_SUBSTUSER,
722 #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
723    OPT_SUBSTUSER_DELAYED,
724 #endif
725    OPT_SYMBOLIC_LINK,	/* with pty */
726 #ifdef TABDLY
727 #  ifdef TAB0
728    OPT_TAB0,		/* termios.c_oflag */
729 #  endif
730 #  ifdef TAB1
731    OPT_TAB1,		/* termios.c_oflag */
732 #  endif
733 #  ifdef TAB2
734    OPT_TAB2,		/* termios.c_oflag */
735 #  endif
736 #  ifdef TAB3
737    OPT_TAB3,		/* termios.c_oflag */
738 #  endif
739    OPT_TABDLY,		/* termios.c_oflag */
740 #endif
741    OPT_TCPWRAPPERS,	/* libwrap */
742    OPT_TCPWRAP_ETC,	/* libwrap */
743    OPT_TCPWRAP_HOSTS_ALLOW_TABLE,	/* libwrap */
744    OPT_TCPWRAP_HOSTS_DENY_TABLE,	/* libwrap */
745    OPT_TCP_ABORT_THRESHOLD,	/* HP-UX */
746    OPT_TCP_CONN_ABORT_THRESHOLD,	/* HP-UX */
747 #ifdef TCP_CORK
748    OPT_TCP_CORK,
749 #endif
750 #ifdef TCP_DEFER_ACCEPT
751    OPT_TCP_DEFER_ACCEPT,	/* Linux 2.4.0 */
752 #endif
753 #ifdef TCP_INFO
754    OPT_TCP_INFO,	/* Linux 2.4.0 */
755 #endif
756 #ifdef TCP_KEEPCNT
757    OPT_TCP_KEEPCNT,	/* Linux 2.4.0 */
758 #endif
759 #ifdef TCP_KEEPIDLE
760    OPT_TCP_KEEPIDLE,	/* Linux 2.4.0 */
761 #endif
762    OPT_TCP_KEEPINIT,	/* OSF1 */
763 #ifdef TCP_KEEPINTVL
764    OPT_TCP_KEEPINTVL,	/* Linux 2.4.0 */
765 #endif
766 #ifdef TCP_LINGER2
767    OPT_TCP_LINGER2,	/* Linux 2.4.0 */
768 #endif
769 #ifdef TCP_MAXSEG
770    OPT_TCP_MAXSEG,
771    OPT_TCP_MAXSEG_LATE,
772 #endif
773    OPT_TCP_MD5SIG,	/* FreeBSD */
774 #ifdef TCP_NODELAY
775    OPT_TCP_NODELAY,
776 #endif
777    OPT_TCP_NOOPT,	/* FreeBSD */
778    OPT_TCP_NOPUSH,	/* FreeBSD */
779    OPT_TCP_PAWS,	/* OSF1 */
780 #ifdef TCP_QUICKACK
781    OPT_TCP_QUICKACK,	/* Linux 2.4 */
782 #endif
783 #ifdef TCP_RFC1323
784    OPT_TCP_RFC1323,	/* AIX 4.3.3 */
785 #endif
786    OPT_TCP_SACKENA,	/* OSF1 */
787    OPT_TCP_SACK_DISABLE,	/* OpenBSD */
788    OPT_TCP_SIGNATURE_ENABLE,	/* OpenBSD */
789 #ifdef TCP_STDURG
790    OPT_TCP_STDURG,	/* AIX 4.3.3; Linux: see man 7 tcp */
791 #endif
792 #ifdef TCP_SYNCNT
793    OPT_TCP_SYNCNT,	/* Linux 2.4.0 */
794 #endif
795    OPT_TCP_TSOPTENA,	/* OSF1 */
796 #ifdef TCP_WINDOW_CLAMP
797    OPT_TCP_WINDOW_CLAMP,	/* Linux 2.4.0 */
798 #endif
799    OPT_TERMIOS_CFMAKERAW,	/* termios.cfmakeraw() */
800    OPT_TERMIOS_RAWER,
801    OPT_TIOCSCTTY,
802    OPT_TOSTOP,		/* termios.c_lflag */
803    OPT_TUN_DEVICE,	/* tun: /dev/net/tun ... */
804    OPT_TUN_NAME,	/* tun: tun0 */
805    OPT_TUN_TYPE,	/* tun: tun|tap */
806    OPT_UMASK,
807    OPT_UNIX_TIGHTSOCKLEN,	/* UNIX domain sockets */
808    OPT_UNLINK,
809    OPT_UNLINK_CLOSE,
810    OPT_UNLINK_EARLY,
811    OPT_UNLINK_LATE,
812    OPT_USER,
813    OPT_USER_EARLY,
814    OPT_USER_LATE,
815 #ifdef VDISCARD
816    OPT_VDISCARD,	/* termios.c_cc */
817 #endif
818    OPT_VDSUSP,		/* termios.c_cc - HP-UX */
819    OPT_VEOF,		/* termios.c_cc */
820    OPT_VEOL,		/* termios.c_cc */
821    OPT_VEOL2,		/* termios.c_cc */
822    OPT_VERASE,		/* termios.c_cc */
823    OPT_VINTR,		/* termios.c_cc */
824    OPT_VKILL,		/* termios.c_cc */
825    OPT_VLNEXT,		/* termios.c_cc */
826    OPT_VMIN, 		/* termios.c_cc */
827    OPT_VQUIT,		/* termios.c_cc */
828    OPT_VREPRINT,	/* termios.c_cc */
829    OPT_VSTART,		/* termios.c_cc */
830    OPT_VSTOP,		/* termios.c_cc */
831    OPT_VSUSP,		/* termios.c_cc */
832    OPT_VSWTC,		/* termios.c_cc */
833    OPT_VTIME,		/* termios.c_cc */
834 #ifdef VTDLY
835 #  ifdef VT0
836    OPT_VT0,		/* termios.c_oflag */
837 #  endif
838 #  ifdef VT1
839    OPT_VT1,		/* termios.c_oflag */
840 #  endif
841    OPT_VTDLY,		/* termios.c_oflag */
842 #endif
843 #ifdef VWERASE
844    OPT_VWERASE,		/* termios.c_cc */
845 #endif
846    OPT_WAITLOCK,
847 #ifdef XCASE
848    OPT_XCASE,		/* termios.c_lflag */
849 #endif
850 #if defined(TABDLY) && defined(XTABS)
851    OPT_XTABS,		/* termios.c_oflag */
852 #endif
853    OPT_nocomma		/* make aix xlc happy, no trailing comma */
854 } ;
855 
856 /* keep consistent with xiohelp.c:optionphasenames ! */
857 enum e_phase {
858    PH_ALL,		/* not for option definitions; use in apply funcs to
859 			   say "all phases" */
860    PH_INIT,		/* retrieving info from original state */
861    PH_EARLY,		/* before any other processing */
862    PH_PREOPEN,		/* before file descriptor is created/opened */
863    PH_OPEN,		/* during filesystem entry creation/open */
864    PH_PASTOPEN,		/* past filesystem entry creation/open */
865    PH_PRESOCKET,	/* before socket call */
866    PH_SOCKET,		/* for socket call */
867    PH_PASTSOCKET,	/* after socket call */
868    PH_PREBIGEN,		/* before socketpair() pipe() openpty() */
869    PH_BIGEN,		/* during socketpair() pipe() openpty() */
870    PH_PASTBIGEN,	/* past socketpair() pipe() openpty() */
871    PH_FD,		/* soon after FD creation or identification */
872    PH_PREBIND,		/* before socket bind() */
873    PH_BIND,		/* during socket bind() ? */
874    PH_PASTBIND,		/* past socket bind() - for client and server sockets! */
875    PH_PRELISTEN,	/* before socket listen() */
876    PH_LISTEN,		/* during socket listen() ? */
877    PH_PASTLISTEN,	/* after socket listen() */
878    PH_PRECONNECT,	/* before socket connect() */
879    PH_CONNECT,		/* during socket connect() ? */
880    PH_PASTCONNECT,	/* after socket connect() */
881    PH_PREACCEPT,	/* before socket accept() */
882    PH_ACCEPT,		/* during socket accept() ? */
883    PH_PASTACCEPT,	/* after socket accept() */
884    PH_CONNECTED,	/* for sockets, after connect() or accept() */
885    PH_PREFORK,		/* before fork() (with both listen and exec!) */
886    PH_FORK,		/* during fork() (with both listen and exec!) */
887    PH_PASTFORK,		/* after fork() (with both listen and exec!) */
888    PH_LATE,		/* FD is ready, before start of data loop */
889    PH_LATE2,		/* FD is ready, dropping privileges */
890    PH_PREEXEC,		/* before exec() or system() */
891    PH_EXEC,		/* during exec() or system() */
892    PH_SPEC		/* specific to situation, not fix */
893 } ;
894 
895 /* atomic structure to describe the syntax and more important semantics of an
896    option */
897 struct optdesc {
898    const char *defname;		/* default name */
899    const char *nickname;	/* usual name */
900    enum e_optcode optcode;	/* short form of option name */
901    unsigned int group;
902    enum e_phase phase;		/* when this option is to be used */
903    enum e_types type;	/* the data type as expected on input, and stored */
904    enum e_func  func;	/* which function can apply this option, e.g. ioctl(),
905 			   getsockopt(), or just a bit pattern */
906    int  major;		/* major id for func: level (SOL_...) for setsockopt(),
907 			   request for ioctl() */
908    int  minor;	/* minor id for func: SO_..., IP_..., */
909    long arg3;
910 } ;
911 
912 extern bool xioopts_ignoregroups;
913 extern const struct optname optionnames[];
914 
915 
916 extern int retropt_bool(struct opt *opts, int optcode, bool *result);
917 extern int retropt_short(struct opt *opts, int optcode, short *result);
918 extern int retropt_ushort(struct opt *opts, int optcode, unsigned short *result);
919 extern int retropt_int(struct opt *opts, int optcode, int *result);
920 extern int retropt_uint(struct opt *opts, int optcode, unsigned int *result);
921 extern int retropt_long(struct opt *opts, int optcode, long *result);
922 extern int retropt_ulong(struct opt *opts, int optcode, unsigned long *result);
923 extern int retropt_flag(struct opt *opts, int optcode, flags_t *result);
924 extern int retropt_string(struct opt *opts, int optcode, char **result);
925 extern int retropt_timespec(struct opt *opts, int optcode, struct timespec *result);
926 extern int retropt_bind(struct opt *opts,
927 		 int af,
928 		 int socktype,
929 		 int ipproto,
930 		 struct sockaddr *sa,
931 		 socklen_t *salen,
932 		 int feats,	/* TCP etc: 1..address allowed,
933 				   3..address and port allowed */
934 		 unsigned long res_opts0, unsigned long res_opts1);
935 extern int applyopts(int fd, struct opt *opts, enum e_phase phase);
936 extern int applyopts2(int fd, struct opt *opts, unsigned int from,
937 		      unsigned int to);
938 extern int applyopts_flags(struct opt *opts, int group, flags_t *result);
939 extern int applyopts_cloexec(int fd, struct opt *opts);
940 extern int applyopts_early(const char *path, struct opt *opts);
941 extern int applyopts_fchown(int fd, struct opt *opts);
942 extern int applyopts_single(struct single *fd, struct opt *opts, enum e_phase phase);
943 extern int applyopts_offset(struct single *xfd, struct opt *opts);
944 extern int applyopts_signal(struct single *xfd, struct opt *opts);
945 extern int _xio_openlate(struct single *fd, struct opt *opts);
946 extern int parseopts(const char **a, unsigned int groups, struct opt **opts);
947 extern int parseopts_table(const char **a, unsigned int groups,
948 			   struct opt **opts,
949 			 const struct optname optionnames[], size_t optionnum);
950 extern const struct opt *searchopt(const struct opt *opts, unsigned int groups, enum e_phase from, enum e_phase to,
951 				   enum e_func func);
952 extern struct opt *copyopts(const struct opt *opts, unsigned int groups);
953 extern struct opt *moveopts(struct opt *opts, unsigned int groups);
954 extern int leftopts(const struct opt *opts);
955 extern int showleft(const struct opt *opts);
956 extern int groupbits(int fd);
957 extern int _groupbits(mode_t mode);
958 extern int dropopts(struct opt *opts, unsigned int phase);
959 extern int dropopts2(struct opt *opts, unsigned int from, unsigned int to);
960 
961 #if HAVE_BASIC_UID_T==1
962 #  define retropt_uid(o,c,r) retropt_short(o,c,r)
963 #elif HAVE_BASIC_UID_T==2
964 #  define retropt_uid(o,c,r) retropt_ushort(o,c,r)
965 #elif HAVE_BASIC_UID_T==3
966 #  define retropt_uid(o,c,r) retropt_int(o,c,r)
967 #elif HAVE_BASIC_UID_T==4
968 #  define retropt_uid(o,c,r) retropt_uint(o,c,r)
969 #elif HAVE_BASIC_UID_T==5
970 #  define retropt_uid(o,c,r) retropt_long(o,c,r)
971 #elif HAVE_BASIC_UID_T==6
972 #  define retropt_uid(o,c,r) retropt_ulong(o,c,r)
973 #else
974 #  error "HAVE_BASIC_UID_T is out of range: " HAVE_BASIC_UID_T
975 #endif
976 
977 #if HAVE_BASIC_GID_T==1
978 #  define retropt_gid(o,c,r) retropt_short(o,c,r)
979 #elif HAVE_BASIC_GID_T==2
980 #  define retropt_gid(o,c,r) retropt_ushort(o,c,r)
981 #elif HAVE_BASIC_GID_T==3
982 #  define retropt_gid(o,c,r) retropt_int(o,c,r)
983 #elif HAVE_BASIC_GID_T==4
984 #  define retropt_gid(o,c,r) retropt_uint(o,c,r)
985 #elif HAVE_BASIC_GID_T==5
986 #  define retropt_gid(o,c,r) retropt_long(o,c,r)
987 #elif HAVE_BASIC_GID_T==6
988 #  define retropt_gid(o,c,r) retropt_ulong(o,c,r)
989 #else
990 #  error "HAVE_BASIC_GID_T is out of range: " HAVE_BASIC_GID_T
991 #endif
992 
993 #if HAVE_BASIC_MODE_T==1
994 #  define retropt_mode(o,c,r) retropt_short(o,c,r)
995 #elif HAVE_BASIC_MODE_T==2
996 #  define retropt_mode(o,c,r) retropt_ushort(o,c,r)
997 #elif HAVE_BASIC_MODE_T==3
998 #  define retropt_mode(o,c,r) retropt_int(o,c,r)
999 #elif HAVE_BASIC_MODE_T==4
1000 #  define retropt_mode(o,c,r) retropt_uint(o,c,r)
1001 #elif HAVE_BASIC_MODE_T==5
1002 #  define retropt_mode(o,c,r) retropt_long(o,c,r)
1003 #elif HAVE_BASIC_MODE_T==6
1004 #  define retropt_mode(o,c,r) retropt_ulong(o,c,r)
1005 #else
1006 #  error "HAVE_BASIC_MODE_T is out of range: " HAVE_BASIC_MODE_T
1007 #endif
1008 
1009 #endif /* !defined(__xioopts_h_included) */
1010