1 /* source: xioopts.c */
2 /* Copyright Gerhard Rieger */
3 /* Published under the GNU General Public License V.2, see file COPYING */
5 /* this file contains the source for address options handling */
7 #include "xiosysincludes.h"
12 #include "xiolockfile.h"
15 bool xioopts_ignoregroups
;
17 #define IF_ANY(a,b) {a,b},
20 # define IF_NAMED(a,b) {a,b},
22 # define IF_NAMED(a,b)
25 #if WITH_PIPE || WITH_GOPEN
26 # define IF_OPEN(a,b) {a,b},
32 # define IF_TERMIOS(a,b) {a,b},
34 # define IF_TERMIOS(a,b)
38 # define IF_EXEC(a,b) {a,b},
44 # define IF_SOCKET(a,b) {a,b},
46 # define IF_SOCKET(a,b)
50 # define IF_LISTEN(a,b) {a,b},
52 # define IF_LISTEN(a,b)
55 #if (WITH_UDP || WITH_TCP) && WITH_LISTEN
56 # define IF_RANGE(a,b) {a,b},
58 # define IF_RANGE(a,b)
61 #if WITH_IP4 || WITH_IP6
62 # define IF_IP(a,b) {a,b},
68 # define IF_IP6(a,b) {a,b},
74 # define IF_IPAPP(a,b) {a,b},
76 # define IF_IPAPP(a,b)
80 # define IF_TCP(a,b) {a,b},
86 # define IF_SCTP(a,b) {a,b},
92 # define IF_SOCKS4(a,b) {a,b},
94 # define IF_SOCKS4(a,b)
98 # define IF_PROXY(a,b) {a,b},
100 # define IF_PROXY(a,b)
104 # define IF_READLINE(a,b) {a,b},
106 # define IF_READLINE(a,b)
110 # define IF_PTY(a,b) {a,b},
116 # define IF_OPENSSL(a,b) {a,b},
118 # define IF_OPENSSL(a,b)
122 # define IF_TUN(a,b) {a,b},
128 # define IF_UNIX(a,b) {a,b},
130 # define IF_UNIX(a,b)
134 # define IF_RETRY(a,b) {a,b},
136 # define IF_RETRY(a,b)
140 static int applyopt_offset(struct single
*xfd
, struct opt
*opt
);
143 /* address options - keep this array strictly alphabetically sorted for
145 /* NULL terminated */
146 const struct optname optionnames
[] = {
148 IF_IP ("aaonly", &opt_res_aaonly
)
149 #endif /* HAVE_RESOLV_H */
150 #ifdef TCP_ABORT_THRESHOLD /* HP_UX */
151 IF_TCP ("abort-threshold", &opt_tcp_abort_threshold
)
153 #ifdef SO_ACCEPTCONN /* AIX433 */
154 IF_SOCKET ("acceptconn", &opt_so_acceptconn
)
155 #endif /* SO_ACCEPTCONN */
156 #ifdef IP_ADD_MEMBERSHIP
157 IF_IP ("add-membership", &opt_ip_add_membership
)
159 IF_TUN ("allmulti", &opt_iff_allmulti
)
160 #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE)
161 IF_IPAPP ("allow-table", &opt_tcpwrap_hosts_allow_table
)
163 IF_ANY ("append", &opt_append
)
165 IF_ANY ("async", &opt_async
)
167 #ifdef SO_ATTACH_FILTER
168 IF_SOCKET ("attach-filter", &opt_so_attach_filter
)
169 IF_SOCKET ("attachfilter", &opt_so_attach_filter
)
171 #ifdef SO_AUDIT /* AIX 4.3.3 */
172 IF_SOCKET ("audit", &opt_so_audit
)
173 #endif /* SO_AUDIT */
175 IF_IP6 ("authhdr", &opt_ipv6_authhdr
)
177 IF_TUN ("automedia", &opt_iff_automedia
)
179 IF_TERMIOS("b0", &opt_b0
)
181 IF_TERMIOS("b1000000", &opt_b1000000
)
183 IF_TERMIOS("b110", &opt_b110
)
185 IF_TERMIOS("b115200", &opt_b115200
)
188 IF_TERMIOS("b1152000", &opt_b1152000
)
190 IF_TERMIOS("b1200", &opt_b1200
)
191 IF_TERMIOS("b134", &opt_b134
)
192 IF_TERMIOS("b150", &opt_b150
)
194 IF_TERMIOS("b1500000", &opt_b1500000
)
196 IF_TERMIOS("b1800", &opt_b1800
)
197 IF_TERMIOS("b19200", &opt_b19200
)
198 IF_TERMIOS("b200", &opt_b200
)
200 IF_TERMIOS("b2000000", &opt_b2000000
)
203 IF_TERMIOS("b230400", &opt_b230400
)
205 IF_TERMIOS("b2400", &opt_b2400
)
207 IF_TERMIOS("b2500000", &opt_b2500000
)
209 IF_TERMIOS("b300", &opt_b300
)
211 IF_TERMIOS("b3000000", &opt_b3000000
)
214 IF_TERMIOS("b3500000", &opt_b3500000
)
216 #ifdef B3600 /* HP-UX */
217 IF_TERMIOS("b3600", &opt_b3600
)
219 IF_TERMIOS("b38400", &opt_b38400
)
221 IF_TERMIOS("b4000000", &opt_b4000000
)
224 IF_TERMIOS("b460800", &opt_b460800
)
226 IF_TERMIOS("b4800", &opt_b4800
)
227 IF_TERMIOS("b50", &opt_b50
)
229 IF_TERMIOS("b500000", &opt_b500000
)
232 IF_TERMIOS("b57600", &opt_b57600
)
235 IF_TERMIOS("b576000", &opt_b576000
)
237 IF_TERMIOS("b600", &opt_b600
)
238 #ifdef B7200 /* HP-UX */
239 IF_TERMIOS("b7200", &opt_b7200
)
241 IF_TERMIOS("b75", &opt_b75
)
242 #ifdef B900 /* HP-UX */
243 IF_TERMIOS("b900", &opt_b900
)
246 IF_TERMIOS("b921600", &opt_b921600
)
248 IF_TERMIOS("b9600", &opt_b9600
)
249 #endif /* defined(CBAUD) */
250 IF_LISTEN ("backlog", &opt_backlog
)
252 IF_OPEN ("bin", &opt_o_binary
)
253 IF_OPEN ("binary", &opt_o_binary
)
255 IF_SOCKET ("bind", &opt_bind
)
256 #ifdef SO_BINDTODEVICE
257 IF_SOCKET ("bindtodevice", &opt_so_bindtodevice
)
259 IF_TERMIOS("brkint", &opt_brkint
)
260 IF_SOCKET ("broadcast", &opt_so_broadcast
)
263 IF_TERMIOS("bs0", &opt_bs0
)
266 IF_TERMIOS("bs1", &opt_bs1
)
270 IF_SOCKET ("bsdcompat", &opt_so_bsdcompat
)
273 IF_TERMIOS("bsdly", &opt_bsdly
)
275 IF_ANY ("bytes", &opt_readbytes
)
276 IF_OPENSSL("cafile", &opt_openssl_cafile
)
277 IF_OPENSSL("capath", &opt_openssl_capath
)
278 IF_OPENSSL("cert", &opt_openssl_certificate
)
279 IF_OPENSSL("certificate", &opt_openssl_certificate
)
280 IF_TERMIOS("cfmakeraw", &opt_termios_cfmakeraw
)
281 IF_ANY ("chroot", &opt_chroot
)
282 IF_ANY ("chroot-early", &opt_chroot_early
)
283 /*IF_TERMIOS("cibaud", &opt_cibaud)*/
284 IF_OPENSSL("cipher", &opt_openssl_cipherlist
)
285 IF_OPENSSL("cipherlist", &opt_openssl_cipherlist
)
286 IF_OPENSSL("ciphers", &opt_openssl_cipherlist
)
288 IF_SOCKET ("cksumrecv", &opt_so_cksumrecv
)
289 #endif /* SO_CKSUMRECV */
290 /*IF_NAMED ("cleanup", &opt_cleanup)*/
291 IF_TERMIOS("clocal", &opt_clocal
)
292 IF_ANY ("cloexec", &opt_cloexec
)
293 IF_ANY ("close", &opt_end_close
)
294 IF_OPENSSL("cn", &opt_openssl_commonname
)
295 IF_OPENSSL("commonname", &opt_openssl_commonname
)
296 #if WITH_EXT2 && defined(EXT2_COMPR_FL)
297 IF_ANY ("compr", &opt_ext2_compr
)
299 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
300 IF_OPENSSL("compress", &opt_openssl_compress
)
302 #ifdef TCP_CONN_ABORT_THRESHOLD /* HP_UX */
303 IF_TCP ("conn-abort-threshold", &opt_tcp_conn_abort_threshold
)
305 IF_SOCKET ("connect-timeout", &opt_connect_timeout
)
306 IF_LISTEN ("cool-write", &opt_cool_write
)
307 IF_LISTEN ("coolwrite", &opt_cool_write
)
309 IF_TCP ("cork", &opt_tcp_cork
)
311 IF_ANY ("cr", &opt_cr
)
314 IF_TERMIOS("cr0", &opt_cr0
)
317 IF_TERMIOS("cr1", &opt_cr1
)
320 IF_TERMIOS("cr2", &opt_cr2
)
323 IF_TERMIOS("cr3", &opt_cr3
)
325 # if CRDLY_SHIFT >= 0
326 IF_TERMIOS("crdly", &opt_crdly
)
328 #endif /* defined(CRDLY) */
329 IF_TERMIOS("cread", &opt_cread
)
330 IF_OPEN ("creat", &opt_o_create
)
331 IF_OPEN ("create", &opt_o_create
)
332 IF_ANY ("crlf", &opt_crnl
)
333 IF_ANY ("crnl", &opt_crnl
)
334 IF_TERMIOS("crterase", &opt_echoe
)
335 IF_TERMIOS("crtkill", &opt_echoke
)
337 IF_TERMIOS("crtscts", &opt_crtscts
)
339 IF_TERMIOS("cs5", &opt_cs5
)
340 IF_TERMIOS("cs6", &opt_cs6
)
341 IF_TERMIOS("cs7", &opt_cs7
)
342 IF_TERMIOS("cs8", &opt_cs8
)
344 IF_TERMIOS("csize", &opt_csize
)
346 IF_TERMIOS("cstopb", &opt_cstopb
)
347 IF_TERMIOS("ctlecho", &opt_echoctl
)
348 IF_TERMIOS("ctty", &opt_tiocsctty
)
349 IF_EXEC ("dash", &opt_dash
)
350 IF_SOCKET ("debug", &opt_so_debug
)
351 /*IF_IP ("debug", &opt_res_debug)*/
353 IF_OPEN ("defer", &opt_o_defer
)
355 #ifdef TCP_DEFER_ACCEPT /* Linux 2.4.0 */
356 IF_TCP ("defer-accept", &opt_tcp_defer_accept
)
359 IF_IP ("defnames", &opt_res_defnames
)
360 #endif /* HAVE_RESOLV_H */
362 IF_OPEN ("delay", &opt_o_delay
)
364 IF_NAMED ("delete", &opt_unlink
)
365 #if WITH_LIBWRAP && defined(HAVE_HOSTS_DENY_TABLE)
366 IF_IPAPP ("deny-table", &opt_tcpwrap_hosts_deny_table
)
368 #ifdef SO_DETACH_FILTER
369 IF_SOCKET ("detach-filter", &opt_so_detach_filter
)
370 IF_SOCKET ("detachfilter", &opt_so_detach_filter
)
372 #ifdef SO_DGRAM_ERRIND
373 IF_SOCKET ("dgram-errind", &opt_so_dgram_errind
)
374 IF_SOCKET ("dgramerrind", &opt_so_dgram_errind
)
376 IF_OPENSSL("dh", &opt_openssl_dhparam
)
377 IF_OPENSSL("dhparam", &opt_openssl_dhparam
)
379 IF_OPEN ("direct", &opt_o_direct
)
382 IF_OPEN ("directory", &opt_o_directory
)
384 #if WITH_EXT2 && defined(EXT2_DIRSYNC_FL)
385 IF_ANY ("dirsync", &opt_ext2_dirsync
)
388 IF_TERMIOS("discard", &opt_vdiscard
)
391 IF_IP ("dnsrch", &opt_res_dnsrch
)
392 #endif /* HAVE_RESOLV_H */
394 IF_SOCKET ("dontlinger", &opt_so_dontlinger
)
396 IF_SOCKET ("dontroute", &opt_so_dontroute
)
398 IF_IP6 ("dstopts", &opt_ipv6_dstopts
)
400 #ifdef VDSUSP /* HP-UX */
401 IF_TERMIOS("dsusp", &opt_vdsusp
)
404 IF_OPEN ("dsync", &opt_o_dsync
)
406 IF_TERMIOS("echo", &opt_echo
)
407 IF_TERMIOS("echoctl", &opt_echoctl
)
408 IF_TERMIOS("echoe", &opt_echoe
)
409 IF_TERMIOS("echok", &opt_echok
)
410 IF_TERMIOS("echoke", &opt_echoke
)
411 IF_TERMIOS("echonl", &opt_echonl
)
413 IF_TERMIOS("echoprt", &opt_echoprt
)
415 IF_OPENSSL("egd", &opt_openssl_egd
)
416 IF_ANY ("end-close", &opt_end_close
)
417 IF_TERMIOS("eof", &opt_veof
)
418 IF_TERMIOS("eol", &opt_veol
)
419 IF_TERMIOS("eol2", &opt_veol2
)
420 IF_TERMIOS("erase", &opt_verase
)
421 IF_SOCKET ("error", &opt_so_error
)
422 IF_ANY ("escape", &opt_escape
)
423 IF_OPEN ("excl", &opt_o_excl
)
424 #if WITH_EXT2 && defined(EXT2_APPEND_FL)
425 IF_ANY ("ext2-append", &opt_ext2_append
)
427 #if WITH_EXT2 && defined(EXT2_COMPR_FL)
428 IF_ANY ("ext2-compr", &opt_ext2_compr
)
430 #if WITH_EXT2 && defined(EXT2_DIRSYNC_FL)
431 IF_ANY ("ext2-dirsync", &opt_ext2_dirsync
)
433 #if WITH_EXT2 && defined(EXT2_IMMUTABLE_FL)
434 IF_ANY ("ext2-immutable", &opt_ext2_immutable
)
436 #if WITH_EXT2 && defined(EXT2_JOURNAL_DATA_FL)
437 IF_ANY ("ext2-journal-data", &opt_ext2_journal_data
)
439 #if WITH_EXT2 && defined(EXT2_NOATIME_FL)
440 IF_ANY ("ext2-noatime", &opt_ext2_noatime
)
442 #if WITH_EXT2 && defined(EXT2_NODUMP_FL)
443 IF_ANY ("ext2-nodump", &opt_ext2_nodump
)
445 #if WITH_EXT2 && defined(EXT2_NOTAIL_FL)
446 IF_ANY ("ext2-notail", &opt_ext2_notail
)
448 #if WITH_EXT2 && defined(EXT2_SECRM_FL)
449 IF_ANY ("ext2-secrm", &opt_ext2_secrm
)
451 #if WITH_EXT2 && defined(EXT2_SYNC_FL)
452 IF_ANY ("ext2-sync", &opt_ext2_sync
)
454 #if WITH_EXT2 && defined(EXT2_TOPDIR_FL)
455 IF_ANY ("ext2-topdir", &opt_ext2_topdir
)
457 #if WITH_EXT2 && defined(EXT2_UNRM_FL)
458 IF_ANY ("ext2-unrm", &opt_ext2_unrm
)
460 #if WITH_EXT2 && defined(EXT2_APPEND_FL)
461 IF_ANY ("ext3-append", &opt_ext2_append
)
463 #if WITH_EXT2 && defined(EXT2_COMPR_FL)
464 IF_ANY ("ext3-compr", &opt_ext2_compr
)
466 #if WITH_EXT2 && defined(EXT2_DIRSYNC_FL)
467 IF_ANY ("ext3-dirsync", &opt_ext2_dirsync
)
469 #if WITH_EXT2 && defined(EXT2_IMMUTABLE_FL)
470 IF_ANY ("ext3-immutable", &opt_ext2_immutable
)
472 #if WITH_EXT2 && defined(EXT2_JOURNAL_DATA_FL)
473 IF_ANY ("ext3-journal-data", &opt_ext2_journal_data
)
475 #if WITH_EXT2 && defined(EXT2_NOATIME_FL)
476 IF_ANY ("ext3-noatime", &opt_ext2_noatime
)
478 #if WITH_EXT2 && defined(EXT2_NODUMP_FL)
479 IF_ANY ("ext3-nodump", &opt_ext2_nodump
)
481 #if WITH_EXT2 && defined(EXT2_NOTAIL_FL)
482 IF_ANY ("ext3-notail", &opt_ext2_notail
)
484 #if WITH_EXT2 && defined(EXT2_SECRM_FL)
485 IF_ANY ("ext3-secrm", &opt_ext2_secrm
)
487 #if WITH_EXT2 && defined(EXT2_SYNC_FL)
488 IF_ANY ("ext3-sync", &opt_ext2_sync
)
490 #if WITH_EXT2 && defined(EXT2_TOPDIR_FL)
491 IF_ANY ("ext3-topdir", &opt_ext2_topdir
)
493 #if WITH_EXT2 && defined(EXT2_UNRM_FL)
494 IF_ANY ("ext3-unrm", &opt_ext2_unrm
)
496 IF_ANY ("f-setlk", &opt_f_setlk_wr
)
497 IF_ANY ("f-setlk-rd", &opt_f_setlk_rd
)
498 IF_ANY ("f-setlk-wr", &opt_f_setlk_wr
)
499 IF_ANY ("f-setlkw", &opt_f_setlkw_wr
)
500 IF_ANY ("f-setlkw-rd", &opt_f_setlkw_rd
)
501 IF_ANY ("f-setlkw-wr", &opt_f_setlkw_wr
)
502 IF_EXEC ("fdin", &opt_fdin
)
503 IF_EXEC ("fdout", &opt_fdout
)
506 IF_TERMIOS("ff0", &opt_ff0
)
509 IF_TERMIOS("ff1", &opt_ff1
)
511 IF_TERMIOS("ffdly", &opt_ffdly
)
514 IF_SOCKET ("fiosetown", &opt_fiosetown
)
517 IF_OPENSSL("fips", &opt_openssl_fips
)
520 IF_ANY ("flock", &opt_flock_ex
)
521 IF_ANY ("flock-ex", &opt_flock_ex
)
522 IF_ANY ("flock-ex-nb", &opt_flock_ex_nb
)
523 IF_ANY ("flock-nb", &opt_flock_ex_nb
)
524 IF_ANY ("flock-sh", &opt_flock_sh
)
525 IF_ANY ("flock-sh-nb", &opt_flock_sh_nb
)
528 IF_IP6 ("flowinfo", &opt_ipv6_flowinfo
)
530 IF_TERMIOS("flusho", &opt_flusho
)
531 IF_RETRY ("forever", &opt_forever
)
532 IF_LISTEN ("fork", &opt_fork
)
534 IF_IP ("freebind", &opt_ip_freebind
)
537 IF_ANY ("ftruncate", &opt_ftruncate64
)
539 IF_ANY ("ftruncate", &opt_ftruncate32
)
541 IF_ANY ("ftruncate32", &opt_ftruncate32
)
543 IF_ANY ("ftruncate64", &opt_ftruncate64
)
545 IF_ANY ("gid", &opt_group
)
546 IF_NAMED ("gid-e", &opt_group_early
)
547 IF_ANY ("gid-l", &opt_group_late
)
548 IF_ANY ("group", &opt_group
)
549 IF_NAMED ("group-early", &opt_group_early
)
550 IF_ANY ("group-late", &opt_group_late
)
552 IF_IP ("hdrincl", &opt_ip_hdrincl
)
554 IF_READLINE("history", &opt_history_file
)
555 IF_READLINE("history-file", &opt_history_file
)
557 IF_IP6 ("hoplimit", &opt_ipv6_hoplimit
)
560 IF_IP6 ("hopopts", &opt_ipv6_hopopts
)
562 #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE)
563 IF_IPAPP ("hosts-allow", &opt_tcpwrap_hosts_allow_table
)
565 #if WITH_LIBWRAP && defined(HAVE_HOSTS_DENY_TABLE)
566 IF_IPAPP ("hosts-deny", &opt_tcpwrap_hosts_deny_table
)
568 IF_TERMIOS("hup", &opt_hupcl
)
569 IF_TERMIOS("hupcl", &opt_hupcl
)
571 IF_ANY ("i-pop-all", &opt_streams_i_pop_all
)
574 IF_ANY ("i-push", &opt_streams_i_push
)
576 IF_TERMIOS("icanon", &opt_icanon
)
577 IF_TERMIOS("icrnl", &opt_icrnl
)
578 IF_TERMIOS("iexten", &opt_iexten
)
579 #ifdef SO_BINDTODEVICE
580 IF_SOCKET ("if", &opt_so_bindtodevice
)
582 IF_TUN ("iff-allmulti", &opt_iff_allmulti
)
583 IF_TUN ("iff-automedia", &opt_iff_automedia
)
584 IF_TUN ("iff-broadcast", &opt_iff_broadcast
)
585 IF_TUN ("iff-debug", &opt_iff_debug
)
586 /*IF_TUN ("iff-dynamic", &opt_iff_dynamic)*/
587 IF_TUN ("iff-loopback", &opt_iff_loopback
)
588 IF_TUN ("iff-master", &opt_iff_master
)
589 IF_TUN ("iff-multicast", &opt_iff_multicast
)
590 IF_TUN ("iff-no-pi", &opt_iff_no_pi
)
591 IF_TUN ("iff-noarp", &opt_iff_noarp
)
592 IF_TUN ("iff-notrailers", &opt_iff_notrailers
)
593 IF_TUN ("iff-pointopoint", &opt_iff_pointopoint
)
594 IF_TUN ("iff-portsel", &opt_iff_portsel
)
595 IF_TUN ("iff-promisc", &opt_iff_promisc
)
596 IF_TUN ("iff-running", &opt_iff_running
)
597 IF_TUN ("iff-slave", &opt_iff_slave
)
598 IF_TUN ("iff-up", &opt_iff_up
)
599 IF_TERMIOS("ignbrk", &opt_ignbrk
)
600 IF_TERMIOS("igncr", &opt_igncr
)
601 /* you might need to terminate socat manually if you use this option: */
602 IF_PROXY ("ignorecr", &opt_ignorecr
)
603 IF_ANY ("ignoreeof", &opt_ignoreeof
)
604 IF_ANY ("ignoreof", &opt_ignoreeof
)
605 IF_TERMIOS("ignpar", &opt_ignpar
)
607 IF_IP ("igntc", &opt_res_igntc
)
608 #endif /* HAVE_RESOLV_H */
609 IF_TERMIOS("imaxbel", &opt_imaxbel
)
610 #if WITH_EXT2 && defined(EXT2_IMMUTABLE_FL)
611 IF_ANY ("immutable", &opt_ext2_immutable
)
613 #ifdef TCP_INFO /* Linux 2.4.0 */
614 IF_TCP ("info", &opt_tcp_info
)
616 IF_TERMIOS("inlcr", &opt_inlcr
)
617 IF_TERMIOS("inpck", &opt_inpck
)
618 #ifdef SO_BINDTODEVICE
619 IF_SOCKET ("interface", &opt_so_bindtodevice
)
621 IF_RETRY ("interval", &opt_intervall
)
622 IF_RETRY ("intervall", &opt_intervall
)
623 IF_TERMIOS("intr", &opt_vintr
)
624 IF_ANY ("ioctl", &opt_ioctl_void
)
625 IF_ANY ("ioctl-bin", &opt_ioctl_bin
)
626 IF_ANY ("ioctl-int", &opt_ioctl_int
)
627 IF_ANY ("ioctl-intp", &opt_ioctl_intp
)
628 IF_ANY ("ioctl-string", &opt_ioctl_string
)
629 IF_ANY ("ioctl-void", &opt_ioctl_void
)
630 #ifdef IP_ADD_MEMBERSHIP
631 IF_IP ("ip-add-membership", &opt_ip_add_membership
)
634 IF_IP ("ip-freebind", &opt_ip_freebind
)
637 IF_IP ("ip-hdrincl", &opt_ip_hdrincl
)
639 #ifdef IP_ADD_MEMBERSHIP
640 IF_IP ("ip-membership", &opt_ip_add_membership
)
643 IF_IP ("ip-mtu", &opt_ip_mtu
)
645 #ifdef IP_MTU_DISCOVER
646 IF_IP ("ip-mtu-discover", &opt_ip_mtu_discover
)
648 IF_IP ("ip-multicast-if", &opt_ip_multicast_if
)
649 IF_IP ("ip-multicast-loop", &opt_ip_multicast_loop
)
650 IF_IP ("ip-multicast-ttl", &opt_ip_multicast_ttl
)
652 IF_IP ("ip-options", &opt_ip_options
)
655 IF_IP ("ip-pktinfo", &opt_ip_pktinfo
)
658 IF_IP ("ip-pktoptions", &opt_ip_pktoptions
)
660 #ifdef IP_RECVDSTADDR
661 IF_IP ("ip-recvdstaddr", &opt_ip_recvdstaddr
)
664 IF_IP ("ip-recverr", &opt_ip_recverr
)
667 IF_IP ("ip-recvif", &opt_ip_recvif
)
670 IF_IP ("ip-recvopts", &opt_ip_recvopts
)
673 IF_IP ("ip-recvtos", &opt_ip_recvtos
)
676 IF_IP ("ip-recvttl", &opt_ip_recvttl
)
679 IF_IP ("ip-retopts", &opt_ip_retopts
)
681 #ifdef IP_ROUTER_ALERT
682 IF_IP ("ip-router-alert", &opt_ip_router_alert
)
684 IF_IP ("ip-tos", &opt_ip_tos
)
685 IF_IP ("ip-ttl", &opt_ip_ttl
)
687 IF_IP ("ipfreebind", &opt_ip_freebind
)
690 IF_IP ("iphdrincl", &opt_ip_hdrincl
)
693 IF_IP ("ipmtu", &opt_ip_mtu
)
695 #ifdef IP_MTU_DISCOVER
696 IF_IP ("ipmtudiscover", &opt_ip_mtu_discover
)
698 IF_IP ("ipmulticastloop", &opt_ip_multicast_loop
)
699 IF_IP ("ipmulticastttl", &opt_ip_multicast_ttl
)
701 IF_IP ("ipoptions", &opt_ip_options
)
704 IF_IP ("ippktinfo", &opt_ip_pktinfo
)
707 IF_IP ("ippktoptions", &opt_ip_pktoptions
)
709 #ifdef IP_RECVDSTADDR
710 IF_IP ("iprecvdstaddr", &opt_ip_recvdstaddr
)
713 IF_IP ("iprecverr", &opt_ip_recverr
)
716 IF_IP ("iprecvopts", &opt_ip_recvopts
)
719 IF_IP ("iprecvtos", &opt_ip_recvtos
)
722 IF_IP ("iprecvttl", &opt_ip_recvttl
)
725 IF_IP ("ipretopts", &opt_ip_retopts
)
727 #ifdef IP_ROUTER_ALERT
728 IF_IP ("iprouteralert", &opt_ip_router_alert
)
730 IF_IP ("iptos", &opt_ip_tos
)
731 IF_IP ("ipttl", &opt_ip_ttl
)
732 #ifdef IPV6_JOIN_GROUP
733 IF_IP6 ("ipv6-add-membership", &opt_ipv6_join_group
)
736 IF_IP6 ("ipv6-authhdr", &opt_ipv6_authhdr
)
739 IF_IP6 ("ipv6-dstopts", &opt_ipv6_dstopts
)
742 IF_IP6 ("ipv6-flowinfo", &opt_ipv6_flowinfo
)
745 IF_IP6 ("ipv6-hoplimit", &opt_ipv6_hoplimit
)
748 IF_IP6 ("ipv6-hopopts", &opt_ipv6_hopopts
)
750 #ifdef IPV6_JOIN_GROUP
751 IF_IP6 ("ipv6-join-group", &opt_ipv6_join_group
)
754 IF_IP6 ("ipv6-pktinfo", &opt_ipv6_pktinfo
)
756 #ifdef IPV6_RECVDSTOPTS
757 IF_IP6 ("ipv6-recvdstopts", &opt_ipv6_recvdstopts
)
760 IF_IP6 ("ipv6-recverr", &opt_ipv6_recverr
)
762 #ifdef IPV6_RECVHOPLIMIT
763 IF_IP6 ("ipv6-recvhoplimit", &opt_ipv6_recvhoplimit
)
765 #ifdef IPV6_RECVHOPOPTS
766 IF_IP6 ("ipv6-recvhopopts", &opt_ipv6_recvhopopts
)
769 IF_IP6 ("ipv6-recvpathmtu", &opt_ipv6_recvpathmtu
)
771 #ifdef IPV6_RECVPKTINFO
772 IF_IP6 ("ipv6-recvpktinfo", &opt_ipv6_recvpktinfo
)
774 #ifdef IPV6_RECVRTHDR
775 IF_IP6 ("ipv6-recvrthdr", &opt_ipv6_recvrthdr
)
777 #ifdef IPV6_RECVTCLASS
778 IF_IP6 ("ipv6-recvtclass", &opt_ipv6_recvtclass
)
781 IF_IP6 ("ipv6-rthdr", &opt_ipv6_rthdr
)
784 IF_IP6 ("ipv6-tclass", &opt_ipv6_tclass
)
786 IF_IP6 ("ipv6-unicast-hops", &opt_ipv6_unicast_hops
)
788 IF_IP6 ("ipv6-v6only", &opt_ipv6_v6only
)
789 IF_IP6 ("ipv6only", &opt_ipv6_v6only
)
791 IF_TERMIOS("isig", &opt_isig
)
792 #if defined(HAVE_TERMIOS_ISPEED) && defined(ISPEED_OFFSET) && (ISPEED_OFFSET != -1)
793 IF_TERMIOS("ispeed", &opt_ispeed
)
795 IF_TERMIOS("istrip", &opt_istrip
)
797 IF_TERMIOS("iuclc", &opt_iuclc
)
799 IF_TERMIOS("ixany", &opt_ixany
)
800 IF_TERMIOS("ixoff", &opt_ixoff
)
801 IF_TERMIOS("ixon", &opt_ixon
)
802 #ifdef IPV6_JOIN_GROUP
803 IF_IP6 ("join-group", &opt_ipv6_join_group
)
805 #if WITH_EXT2 && defined(EXT2_JOURNAL_DATA_FL)
806 IF_ANY ("journal", &opt_ext2_journal_data
)
807 IF_ANY ("journal-data", &opt_ext2_journal_data
)
809 IF_SOCKET ("keepalive", &opt_so_keepalive
)
810 #ifdef TCP_KEEPCNT /* Linux 2.4.0 */
811 IF_TCP ("keepcnt", &opt_tcp_keepcnt
)
813 #ifdef TCP_KEEPIDLE /* Linux 2.4.0 */
814 IF_TCP ("keepidle", &opt_tcp_keepidle
)
816 #ifdef TCP_KEEPINIT /* OSF1 */
817 IF_TCP ("keepinit", &opt_tcp_keepinit
)
819 #ifdef TCP_KEEPINTVL /* Linux 2.4.0 */
820 IF_TCP ("keepintvl", &opt_tcp_keepintvl
)
822 #ifdef SO_KERNACCEPT /* AIX 4.3.3 */
823 IF_SOCKET ("kernaccept", &opt_so_kernaccept
)
824 #endif /* SO_KERNACCEPT */
825 IF_OPENSSL("key", &opt_openssl_key
)
826 IF_TERMIOS("kill", &opt_vkill
)
828 IF_OPEN ("largefile", &opt_o_largefile
)
831 IF_IPAPP ("libwrap", &opt_tcpwrappers
)
833 IF_SOCKET ("linger", &opt_so_linger
)
834 #ifdef TCP_LINGER2 /* Linux 2.4.0 */
835 IF_TCP ("linger2", &opt_tcp_linger2
)
837 IF_PTY ("link", &opt_symbolic_link
)
838 IF_TERMIOS("lnext", &opt_vlnext
)
839 #if defined(F_SETLKW)
840 IF_ANY ("lock", &opt_f_setlkw_wr
) /* POSIX, first choice */
841 #elif defined(HAVE_FLOCK)
842 IF_ANY ("lock", &opt_flock_ex
) /* BSD, fallback */
844 IF_ANY ("lockfile", &opt_lockfile
)
845 #if defined(F_SETLKW)
846 IF_ANY ("lockw", &opt_f_setlkw_wr
) /* POSIX, first choice */
847 #elif defined(HAVE_FLOCK)
848 IF_ANY ("lockw", &opt_flock_ex_nb
) /* BSD, fallback */
850 IF_EXEC ("login", &opt_dash
)
851 IF_TUN ("loopback", &opt_iff_loopback
)
852 IF_IPAPP ("lowport", &opt_lowport
)
854 IF_ANY ("lseek", &opt_lseek64_set
)
856 IF_ANY ("lseek", &opt_lseek32_set
)
858 IF_ANY ("lseek32", &opt_lseek32_set
)
859 IF_ANY ("lseek32-cur", &opt_lseek32_cur
)
860 IF_ANY ("lseek32-end", &opt_lseek32_end
)
861 IF_ANY ("lseek32-set", &opt_lseek32_set
)
863 IF_ANY ("lseek64", &opt_lseek64_set
)
864 IF_ANY ("lseek64-cur", &opt_lseek64_cur
)
865 IF_ANY ("lseek64-end", &opt_lseek64_end
)
866 IF_ANY ("lseek64-set", &opt_lseek64_set
)
868 IF_TUN ("master", &opt_iff_master
)
869 IF_LISTEN ("max-children", &opt_max_children
)
870 IF_LISTEN ("maxchildren", &opt_max_children
)
872 IF_TCP ("maxseg", &opt_tcp_maxseg
)
873 IF_TCP ("maxseg-late", &opt_tcp_maxseg_late
)
876 IF_TCP ("md5sig", &opt_tcp_md5sig
)
878 #ifdef IP_ADD_MEMBERSHIP
879 IF_IP ("membership", &opt_ip_add_membership
)
881 IF_OPENSSL("method", &opt_openssl_method
)
882 IF_TERMIOS("min", &opt_vmin
)
883 IF_ANY ("mode", &opt_perm
)
885 IF_TCP ("mss", &opt_tcp_maxseg
)
886 IF_TCP ("mss-late", &opt_tcp_maxseg_late
)
889 IF_IP ("mtu", &opt_ip_mtu
)
891 #ifdef IP_MTU_DISCOVER
892 IF_IP ("mtudiscover", &opt_ip_mtu_discover
)
894 IF_TUN ("multicast", &opt_iff_multicast
)
895 IF_IP ("multicast-if", &opt_ip_multicast_if
)
896 IF_IP ("multicast-loop", &opt_ip_multicast_loop
)
897 IF_IP ("multicast-ttl", &opt_ip_multicast_ttl
)
898 IF_IP ("multicastloop", &opt_ip_multicast_loop
)
899 IF_IP ("multicastttl", &opt_ip_multicast_ttl
)
900 #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK)
901 IF_ANY ("ndelay", &opt_o_ndelay
)
903 IF_ANY ("ndelay", &opt_nonblock
)
905 IF_NAMED ("new", &opt_unlink_early
)
908 IF_TERMIOS("nl0", &opt_nl0
)
911 IF_TERMIOS("nl1", &opt_nl1
)
913 IF_TERMIOS("nldly", &opt_nldly
)
914 #endif /* defined(NLDLY) */
916 IF_SOCKET ("no-check", &opt_so_no_check
)
918 IF_TUN ("no-pi", &opt_iff_no_pi
)
919 IF_TUN ("noarp", &opt_iff_noarp
)
921 IF_OPEN ("noatime", &opt_o_noatime
)
924 IF_SOCKET ("nocheck", &opt_so_no_check
)
926 IF_OPEN ("noctty", &opt_o_noctty
)
928 IF_TCP ("nodelay", &opt_tcp_nodelay
)
930 #if WITH_EXT2 && defined(EXT2_NODUMP_FL)
931 IF_ANY ("nodump", &opt_ext2_nodump
)
934 IF_READLINE("noecho", &opt_noecho
)
935 #endif /* HAVE_REGEX_H */
936 IF_TERMIOS("noflsh", &opt_noflsh
)
938 IF_OPEN ("nofollow", &opt_o_nofollow
)
940 IF_EXEC ("nofork", &opt_nofork
)
942 IF_ANY ("noinherit", &opt_o_noinherit
)
944 IF_ANY ("nonblock", &opt_nonblock
)
946 IF_TCP ("noopt", &opt_tcp_noopt
)
948 IF_READLINE("noprompt", &opt_noprompt
)
950 IF_TCP ("nopush", &opt_tcp_nopush
)
952 #ifdef SO_NOREUSEADDR /* AIX 4.3.3 */
953 IF_SOCKET ("noreuseaddr", &opt_so_noreuseaddr
)
954 #endif /* SO_NOREUSEADDR */
955 IF_TUN ("notrailers", &opt_iff_notrailers
)
957 IF_OPEN ("nshare", &opt_o_nshare
)
959 IF_SOCKET ("null-eof", &opt_null_eof
)
960 IF_ANY ("o-append", &opt_append
)
962 IF_ANY ("o-async", &opt_async
)
965 IF_OPEN ("o-binary", &opt_o_binary
)
967 IF_OPEN ("o-creat", &opt_o_create
)
968 IF_OPEN ("o-create", &opt_o_create
)
970 IF_OPEN ("o-defer", &opt_o_defer
)
973 IF_OPEN ("o-delay", &opt_o_delay
)
976 IF_OPEN ("o-direct", &opt_o_direct
)
979 IF_OPEN ("o-directory", &opt_o_directory
)
982 IF_OPEN ("o-dsync", &opt_o_dsync
)
984 IF_OPEN ("o-excl", &opt_o_excl
)
986 IF_OPEN ("o-largefile", &opt_o_largefile
)
988 #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK)
989 IF_ANY ("o-ndelay", &opt_o_ndelay
)
991 IF_ANY ("o-ndelay", &opt_nonblock
)
994 IF_OPEN ("o-noatime", &opt_o_noatime
)
996 IF_OPEN ("o-noctty", &opt_o_noctty
)
998 IF_OPEN ("o-nofollow", &opt_o_nofollow
)
1001 IF_ANY ("o-noinherit", &opt_o_noinherit
)
1003 IF_ANY ("o-nonblock", &opt_nonblock
)
1005 IF_OPEN ("o-nshare", &opt_o_nshare
)
1008 IF_OPEN ("o-priv", &opt_o_priv
)
1010 IF_OPEN ("o-rdonly", &opt_o_rdonly
)
1011 IF_OPEN ("o-rdwr", &opt_o_rdwr
)
1013 IF_OPEN ("o-rshare", &opt_o_rshare
)
1016 IF_OPEN ("o-rsync", &opt_o_rsync
)
1019 IF_OPEN ("o-sync", &opt_o_sync
)
1022 IF_ANY ("o-text", &opt_o_text
)
1024 IF_OPEN ("o-trunc", &opt_o_trunc
)
1025 IF_OPEN ("o-wronly", &opt_o_wronly
)
1026 IF_OPEN ("o_create", &opt_o_create
)
1028 IF_OPEN ("o_defer", &opt_o_defer
)
1031 IF_OPEN ("o_delay", &opt_o_delay
)
1034 IF_OPEN ("o_direct", &opt_o_direct
)
1037 IF_OPEN ("o_directory", &opt_o_directory
)
1040 IF_OPEN ("o_dsync", &opt_o_dsync
)
1042 IF_OPEN ("o_excl", &opt_o_excl
)
1044 IF_OPEN ("o_largefile", &opt_o_largefile
)
1046 #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK)
1047 IF_ANY ("o_ndelay", &opt_o_ndelay
)
1049 IF_ANY ("o_ndelay", &opt_nonblock
)
1051 IF_OPEN ("o_noctty", &opt_o_noctty
)
1053 IF_OPEN ("o_nofollow", &opt_o_nofollow
)
1056 IF_OPEN ("o_nshare", &opt_o_nshare
)
1059 IF_OPEN ("o_priv", &opt_o_priv
)
1061 IF_OPEN ("o_rdonly", &opt_o_rdonly
)
1062 IF_OPEN ("o_rdwr", &opt_o_rdwr
)
1064 IF_OPEN ("o_rshare", &opt_o_rshare
)
1067 IF_OPEN ("o_rsync", &opt_o_rsync
)
1070 IF_OPEN ("o_sync", &opt_o_sync
)
1072 IF_OPEN ("o_wronly", &opt_o_wronly
)
1074 IF_TERMIOS("ocrnl", &opt_ocrnl
)
1077 IF_TERMIOS("ofdel", &opt_ofdel
)
1080 IF_TERMIOS("ofill", &opt_ofill
)
1083 IF_TERMIOS("olcuc", &opt_olcuc
)
1085 IF_TERMIOS("onlcr", &opt_onlcr
)
1087 IF_TERMIOS("onlret", &opt_onlret
)
1090 IF_TERMIOS("onocr", &opt_onocr
)
1092 IF_SOCKET ("oobinline", &opt_so_oobinline
)
1094 IF_EXEC ("openpty", &opt_openpty
)
1095 #endif /* HAVE_OPENPTY */
1096 IF_OPENSSL("openssl-cafile", &opt_openssl_cafile
)
1097 IF_OPENSSL("openssl-capath", &opt_openssl_capath
)
1098 IF_OPENSSL("openssl-certificate", &opt_openssl_certificate
)
1099 IF_OPENSSL("openssl-cipherlist", &opt_openssl_cipherlist
)
1100 IF_OPENSSL("openssl-commonname", &opt_openssl_commonname
)
1101 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
1102 IF_OPENSSL("openssl-compress", &opt_openssl_compress
)
1104 IF_OPENSSL("openssl-dhparam", &opt_openssl_dhparam
)
1105 IF_OPENSSL("openssl-egd", &opt_openssl_egd
)
1107 IF_OPENSSL("openssl-fips", &opt_openssl_fips
)
1109 IF_OPENSSL("openssl-key", &opt_openssl_key
)
1110 IF_OPENSSL("openssl-method", &opt_openssl_method
)
1111 IF_OPENSSL("openssl-pseudo", &opt_openssl_pseudo
)
1112 IF_OPENSSL("openssl-verify", &opt_openssl_verify
)
1113 IF_TERMIOS("opost", &opt_opost
)
1114 #if defined(HAVE_TERMIOS_ISPEED) && defined(OSPEED_OFFSET) && (OSPEED_OFFSET != -1)
1115 IF_TERMIOS("ospeed", &opt_ospeed
)
1117 IF_ANY ("owner", &opt_user
)
1118 IF_TERMIOS("parenb", &opt_parenb
)
1119 IF_TERMIOS("parmrk", &opt_parmrk
)
1120 IF_TERMIOS("parodd", &opt_parodd
)
1122 IF_SOCKET ("passcred", &opt_so_passcred
)
1124 IF_EXEC ("path", &opt_path
)
1125 #ifdef TCP_PAWS /* OSF1 */
1126 IF_TCP ("paws", &opt_tcp_paws
)
1129 IF_SOCKET ("peercred", &opt_so_peercred
)
1132 IF_TERMIOS("pendin", &opt_pendin
)
1134 IF_ANY ("perm", &opt_perm
)
1135 IF_NAMED ("perm-early", &opt_perm_early
)
1136 IF_ANY ("perm-late", &opt_perm_late
)
1137 IF_SOCKET ("pf", &opt_protocol_family
)
1138 IF_EXEC ("pgid", &opt_setpgid
)
1139 IF_EXEC ("pipes", &opt_pipes
)
1141 IF_IP ("pktinfo", &opt_ip_pktinfo
)
1143 #ifdef IP_PKTOPTIONS
1144 IF_IP ("pktoptions", &opt_ip_pktoptions
)
1145 IF_IP ("pktopts", &opt_ip_pktoptions
)
1147 IF_TUN ("pointopoint", &opt_iff_pointopoint
)
1149 IF_ANY ("pop-all", &opt_streams_i_pop_all
)
1151 /*IF_IPAPP("port", &opt_port)*/
1152 IF_TUN ("portsel", &opt_iff_portsel
)
1154 IF_IP ("primary", &opt_res_primary
)
1155 #endif /* HAVE_RESOLV_H */
1157 IF_SOCKET ("priority", &opt_so_priority
)
1160 IF_OPEN ("priv", &opt_o_priv
)
1162 IF_TUN ("promisc", &opt_iff_promisc
)
1163 IF_READLINE("prompt", &opt_prompt
)
1165 IF_SOCKET ("protocol", &opt_so_prototype
)
1167 IF_SOCKET ("protocol-family", &opt_protocol_family
)
1169 IF_SOCKET ("prototype", &opt_so_prototype
)
1171 IF_PROXY ("proxy-auth", &opt_proxy_authorization
)
1172 IF_PROXY ("proxy-authorization", &opt_proxy_authorization
)
1173 IF_PROXY ("proxy-resolve", &opt_proxy_resolve
)
1174 IF_PROXY ("proxyauth", &opt_proxy_authorization
)
1175 IF_PROXY ("proxyport", &opt_proxyport
)
1177 IF_TERMIOS("prterase", &opt_echoprt
)
1179 IF_OPENSSL("pseudo", &opt_openssl_pseudo
)
1180 #if HAVE_DEV_PTMX || HAVE_DEV_PTC
1181 IF_EXEC ("ptmx", &opt_ptmx
)
1184 IF_EXEC ("pty", &opt_pty
)
1186 #if HAVE_PTY && HAVE_POLL
1187 IF_PTY ("pty-interval", &opt_pty_intervall
)
1188 IF_PTY ("pty-intervall", &opt_pty_intervall
)
1189 IF_PTY ("pty-wait-slave", &opt_pty_wait_slave
)
1190 #endif /* HAVE_PTY && HAVE_POLL */
1192 IF_ANY ("push", &opt_streams_i_push
)
1195 IF_TCP ("quickack", &opt_tcp_quickack
)
1197 IF_TERMIOS("quit", &opt_vquit
)
1198 IF_RANGE ("range", &opt_range
)
1199 IF_TERMIOS("raw", &opt_raw
)
1200 IF_TERMIOS("rawer", &opt_termios_rawer
)
1201 IF_SOCKET ("rcvbuf", &opt_so_rcvbuf
)
1202 IF_SOCKET ("rcvbuf-late", &opt_so_rcvbuf_late
)
1204 IF_SOCKET ("rcvlowat", &opt_so_rcvlowat
)
1207 IF_SOCKET ("rcvtimeo", &opt_so_rcvtimeo
)
1209 IF_OPEN ("rdonly", &opt_o_rdonly
)
1210 IF_OPEN ("rdwr", &opt_o_rdwr
)
1211 IF_ANY ("readbytes", &opt_readbytes
)
1213 IF_IP ("recurse", &opt_res_recurse
)
1214 #endif /* HAVE_RESOLV_H */
1215 #ifdef IP_RECVDSTADDR
1216 IF_IP ("recvdstaddr", &opt_ip_recvdstaddr
)
1218 #ifdef IPV6_RECVDSTOPTS
1219 IF_IP6 ("recvdstopts", &opt_ipv6_recvdstopts
)
1222 IF_IP ("recverr", &opt_ip_recverr
)
1224 #ifdef IPV6_RECVHOPLIMIT
1225 IF_IP6 ("recvhoplimit", &opt_ipv6_recvhoplimit
)
1227 #ifdef IPV6_RECVHOPOPTS
1228 IF_IP6 ("recvhopopts", &opt_ipv6_recvhopopts
)
1231 IF_IP ("recvif", &opt_ip_recvif
)
1234 IF_IP ("recvopts", &opt_ip_recvopts
)
1236 #ifdef IPV6_RECVPKTINFO
1237 IF_IP6 ("recvpktinfo", &opt_ipv6_recvpktinfo
)
1239 #ifdef IPV6_RECVRTHDR
1240 IF_IP6 ("recvrthdr", &opt_ipv6_recvrthdr
)
1243 IF_IP ("recvtos", &opt_ip_recvtos
)
1246 IF_IP ("recvttl", &opt_ip_recvttl
)
1248 IF_NAMED ("remove", &opt_unlink
)
1250 IF_TERMIOS("reprint", &opt_vreprint
)
1253 IF_IP ("res-aaonly", &opt_res_aaonly
)
1254 IF_IP ("res-debug", &opt_res_debug
)
1255 IF_IP ("res-defnames", &opt_res_defnames
)
1256 IF_IP ("res-dnsrch", &opt_res_dnsrch
)
1257 IF_IP ("res-igntc", &opt_res_igntc
)
1258 IF_IP ("res-primary", &opt_res_primary
)
1259 IF_IP ("res-recurse", &opt_res_recurse
)
1260 IF_IP ("res-stayopen", &opt_res_stayopen
)
1261 IF_IP ("res-usevc", &opt_res_usevc
)
1262 #endif /* HAVE_RESOLV_H */
1263 IF_PROXY ("resolv", &opt_proxy_resolve
)
1264 IF_PROXY ("resolve", &opt_proxy_resolve
)
1266 IF_IP ("retopts", &opt_ip_retopts
)
1268 IF_RETRY ("retry", &opt_retry
)
1269 IF_SOCKET ("reuseaddr", &opt_so_reuseaddr
)
1270 #ifdef SO_REUSEPORT /* AIX 4.3.3 */
1271 IF_SOCKET ("reuseport", &opt_so_reuseport
)
1272 #endif /* defined(SO_REUSEPORT) */
1274 IF_TCP ("rfc1323", &opt_tcp_rfc1323
)
1276 #ifdef IP_ROUTER_ALERT
1277 IF_IP ("routeralert", &opt_ip_router_alert
)
1280 IF_TERMIOS("rprnt", &opt_vreprint
)
1283 IF_OPEN ("rshare", &opt_o_rshare
)
1286 IF_OPEN ("rsync", &opt_o_rsync
)
1289 IF_IP6 ("rthdr", &opt_ipv6_rthdr
)
1291 IF_TUN ("running", &opt_iff_running
)
1292 #ifdef TCP_SACK_DISABLE
1293 IF_TCP ("sack-disable", &opt_tcp_sack_disable
)
1295 #ifdef TCP_SACKENA /* OSF1 */
1296 IF_TCP ("sackena", &opt_tcp_sackena
)
1298 IF_TERMIOS("sane", &opt_sane
)
1300 IF_SCTP ("sctp-maxseg", &opt_sctp_maxseg
)
1301 IF_SCTP ("sctp-maxseg-late", &opt_sctp_maxseg_late
)
1304 IF_SCTP ("sctp-nodelay", &opt_sctp_nodelay
)
1306 #if WITH_EXT2 && defined(EXT2_SECRM_FL)
1307 IF_ANY ("secrm", &opt_ext2_secrm
)
1309 #ifdef SO_SECURITY_AUTHENTICATION
1310 IF_SOCKET ("security-authentication", &opt_so_security_authentication
)
1312 #ifdef SO_SECURITY_ENCRYPTION_NETWORK
1313 IF_SOCKET ("security-encryption-network", &opt_so_security_encryption_network
)
1315 #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
1316 IF_SOCKET ("security-encryption-transport", &opt_so_security_encryption_transport
)
1318 #ifdef SO_SECURITY_AUTHENTICATION
1319 IF_SOCKET ("securityauthentication", &opt_so_security_authentication
)
1321 #ifdef SO_SECURITY_ENCRYPTION_NETWORK
1322 IF_SOCKET ("securityencryptionnetwork", &opt_so_security_encryption_network
)
1324 #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
1325 IF_SOCKET ("securityencryptiontransport", &opt_so_security_encryption_transport
)
1328 IF_ANY ("seek", &opt_lseek64_set
)
1329 IF_ANY ("seek-cur", &opt_lseek64_cur
)
1330 IF_ANY ("seek-end", &opt_lseek64_end
)
1331 IF_ANY ("seek-set", &opt_lseek64_set
)
1333 IF_ANY ("seek", &opt_lseek32_set
)
1334 IF_ANY ("seek-cur", &opt_lseek32_cur
)
1335 IF_ANY ("seek-end", &opt_lseek32_end
)
1336 IF_ANY ("seek-set", &opt_lseek32_set
)
1338 IF_ANY ("setgid", &opt_setgid
)
1339 IF_ANY ("setgid-early", &opt_setgid_early
)
1340 IF_ANY ("setlk", &opt_f_setlk_wr
)
1341 IF_ANY ("setlk-rd", &opt_f_setlk_rd
)
1342 IF_ANY ("setlk-wr", &opt_f_setlk_wr
)
1343 IF_ANY ("setlkw", &opt_f_setlkw_wr
)
1344 IF_ANY ("setlkw-rd", &opt_f_setlkw_rd
)
1345 IF_ANY ("setlkw-wr", &opt_f_setlkw_wr
)
1346 IF_EXEC ("setpgid", &opt_setpgid
)
1347 #if WITH_EXEC || WITH_SYSTEM
1348 IF_EXEC ("setsid", &opt_setsid
)
1350 IF_SOCKET ("setsockopt-bin", &opt_setsockopt_bin
)
1351 IF_SOCKET ("setsockopt-int", &opt_setsockopt_int
)
1352 IF_SOCKET ("setsockopt-string", &opt_setsockopt_string
)
1353 IF_ANY ("setuid", &opt_setuid
)
1354 IF_ANY ("setuid-early", &opt_setuid_early
)
1355 IF_ANY ("shut-close", &opt_shut_close
)
1356 IF_ANY ("shut-down", &opt_shut_down
)
1357 IF_ANY ("shut-none", &opt_shut_none
)
1358 IF_ANY ("shut-null", &opt_shut_null
)
1359 #if WITH_EXEC || WITH_SYSTEM
1360 IF_ANY ("sid", &opt_setsid
)
1362 IF_EXEC ("sighup", &opt_sighup
)
1363 IF_EXEC ("sigint", &opt_sigint
)
1364 #ifdef TCP_SIGNATURE_ENABLE
1365 IF_TCP ("signature-enable", &opt_tcp_signature_enable
)
1367 IF_EXEC ("sigquit", &opt_sigquit
)
1369 IF_SOCKET ("siocspgrp", &opt_siocspgrp
)
1371 IF_TUN ("slave", &opt_iff_slave
)
1372 IF_SOCKET ("sndbuf", &opt_so_sndbuf
)
1373 IF_SOCKET ("sndbuf-late", &opt_so_sndbuf_late
)
1375 IF_SOCKET ("sndlowat", &opt_so_sndlowat
)
1378 IF_SOCKET ("sndtimeo", &opt_so_sndtimeo
)
1380 #ifdef SO_ACCEPTCONN /* AIX433 */
1381 IF_SOCKET ("so-acceptconn", &opt_so_acceptconn
)
1382 #endif /* SO_ACCEPTCONN */
1383 #ifdef SO_ATTACH_FILTER
1384 IF_SOCKET ("so-attach-filter", &opt_so_attach_filter
)
1386 #ifdef SO_AUDIT /* AIX 4.3.3 */
1387 IF_SOCKET ("so-audit", &opt_so_audit
)
1388 #endif /* SO_AUDIT */
1389 #ifdef SO_BINDTODEVICE
1390 IF_SOCKET ("so-bindtodevice", &opt_so_bindtodevice
)
1392 IF_SOCKET ("so-broadcast", &opt_so_broadcast
)
1394 IF_SOCKET ("so-bsdcompat", &opt_so_bsdcompat
)
1397 IF_SOCKET ("so-cksumrecv", &opt_so_cksumrecv
)
1398 #endif /* SO_CKSUMRECV */
1399 IF_SOCKET ("so-debug", &opt_so_debug
)
1400 #ifdef SO_DETACH_FILTER
1401 IF_SOCKET ("so-detach-filter", &opt_so_detach_filter
)
1403 #ifdef SO_DGRAM_ERRIND
1404 IF_SOCKET ("so-dgram-errind", &opt_so_dgram_errind
)
1406 #ifdef SO_DONTLINGER
1407 IF_SOCKET ("so-dontlinger", &opt_so_dontlinger
)
1409 IF_SOCKET ("so-dontroute", &opt_so_dontroute
)
1410 IF_SOCKET ("so-error", &opt_so_error
)
1411 IF_SOCKET ("so-keepalive", &opt_so_keepalive
)
1412 #ifdef SO_KERNACCEPT /* AIX 4.3.3 */
1413 IF_SOCKET ("so-kernaccept", &opt_so_kernaccept
)
1414 #endif /* SO_KERNACCEPT */
1415 IF_SOCKET ("so-linger", &opt_so_linger
)
1417 IF_SOCKET ("so-no-check", &opt_so_no_check
)
1419 #ifdef SO_NOREUSEADDR /* AIX 4.3.3 */
1420 IF_SOCKET ("so-noreuseaddr", &opt_so_noreuseaddr
)
1421 #endif /* SO_NOREUSEADDR */
1422 IF_SOCKET ("so-oobinline", &opt_so_oobinline
)
1424 IF_SOCKET ("so-passcred", &opt_so_passcred
)
1427 IF_SOCKET ("so-peercred", &opt_so_peercred
)
1430 IF_SOCKET ("so-priority", &opt_so_priority
)
1433 IF_SOCKET ("so-prototype", &opt_so_prototype
)
1435 IF_SOCKET ("so-rcvbuf", &opt_so_rcvbuf
)
1436 IF_SOCKET ("so-rcvbuf-late", &opt_so_rcvbuf_late
)
1438 IF_SOCKET ("so-rcvlowat", &opt_so_rcvlowat
)
1441 IF_SOCKET ("so-rcvtimeo", &opt_so_rcvtimeo
)
1443 IF_SOCKET ("so-reuseaddr", &opt_so_reuseaddr
)
1444 #ifdef SO_REUSEPORT /* AIX 4.3.3 */
1445 IF_SOCKET ("so-reuseport", &opt_so_reuseport
)
1446 #endif /* defined(SO_REUSEPORT) */
1447 #ifdef SO_SECURITY_AUTHENTICATION
1448 IF_SOCKET ("so-security-authentication", &opt_so_security_authentication
)
1450 #ifdef SO_SECURITY_ENCRYPTION_NETWORK
1451 IF_SOCKET ("so-security-encryption-network", &opt_so_security_encryption_network
)
1453 #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
1454 IF_SOCKET ("so-security-encryption-transport", &opt_so_security_encryption_transport
)
1456 IF_SOCKET ("so-sndbuf", &opt_so_sndbuf
)
1457 IF_SOCKET ("so-sndbuf-late", &opt_so_sndbuf_late
)
1459 IF_SOCKET ("so-sndlowat", &opt_so_sndlowat
)
1462 IF_SOCKET ("so-sndtimeo", &opt_so_sndtimeo
)
1465 IF_SOCKET ("so-timestamp", &opt_so_timestamp
)
1467 IF_SOCKET ("so-type", &opt_so_type
)
1468 #ifdef SO_USE_IFBUFS
1469 IF_SOCKET ("so-use-ifbufs", &opt_so_use_ifbufs
)
1470 #endif /* SO_USE_IFBUFS */
1471 #ifdef SO_USELOOPBACK /* AIX433, Solaris */
1472 IF_SOCKET ("so-useloopback", &opt_so_useloopback
)
1473 #endif /* SO_USELOOPBACK */
1474 IF_SOCKET ("sockopt-bin", &opt_setsockopt_bin
)
1475 IF_SOCKET ("sockopt-int", &opt_setsockopt_int
)
1476 IF_SOCKET ("sockopt-string", &opt_setsockopt_string
)
1477 IF_SOCKS4 ("socksport", &opt_socksport
)
1478 IF_SOCKS4 ("socksuser", &opt_socksuser
)
1479 IF_SOCKET ("socktype", &opt_so_type
)
1480 IF_IPAPP ("sourceport", &opt_sourceport
)
1481 IF_IPAPP ("sp", &opt_sourceport
)
1482 IF_TERMIOS("start", &opt_vstart
)
1484 IF_IP ("stayopen", &opt_res_stayopen
)
1485 #endif /* HAVE_RESOLV_H */
1486 IF_EXEC ("stderr", &opt_stderr
)
1488 IF_TCP ("stdurg", &opt_tcp_stdurg
)
1490 IF_TERMIOS("stop", &opt_vstop
)
1492 IF_ANY ("streams-i-pop-all", &opt_streams_i_pop_all
)
1495 IF_ANY ("streams-i-push", &opt_streams_i_push
)
1497 IF_ANY ("su", &opt_substuser
)
1498 #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
1499 IF_ANY ("su-d", &opt_substuser_delayed
)
1501 IF_ANY ("su-e", &opt_substuser_early
)
1502 IF_ANY ("substuser", &opt_substuser
)
1503 #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
1504 IF_ANY ("substuser-delayed", &opt_substuser_delayed
)
1506 IF_ANY ("substuser-early", &opt_substuser_early
)
1507 IF_TERMIOS("susp", &opt_vsusp
)
1509 IF_TERMIOS("swtc", &opt_vswtc
)
1510 IF_TERMIOS("swtch", &opt_vswtc
)
1512 IF_PTY ("symbolic-link", &opt_symbolic_link
)
1514 IF_OPEN ("sync", &opt_o_sync
)
1516 IF_ANY ("sync", &opt_ext2_sync
)
1519 IF_TCP ("syncnt", &opt_tcp_syncnt
)
1523 IF_TERMIOS("tab0", &opt_tab0
)
1526 IF_TERMIOS("tab1", &opt_tab1
)
1529 IF_TERMIOS("tab2", &opt_tab2
)
1532 IF_TERMIOS("tab3", &opt_tab3
)
1534 # if TABDLY_SHIFT >= 0
1535 IF_TERMIOS("tabdly", &opt_tabdly
)
1538 IF_TERMIOS("tandem", &opt_ixoff
)
1539 #ifdef TCP_ABORT_THRESHOLD /* HP_UX */
1540 IF_TCP ("tcp-abort-threshold", &opt_tcp_abort_threshold
)
1542 #ifdef TCP_CONN_ABORT_THRESHOLD /* HP_UX */
1543 IF_TCP ("tcp-conn-abort-threshold", &opt_tcp_conn_abort_threshold
)
1546 IF_TCP ("tcp-cork", &opt_tcp_cork
)
1548 #ifdef TCP_DEFER_ACCEPT /* Linux 2.4.0 */
1549 IF_TCP ("tcp-defer-accept", &opt_tcp_defer_accept
)
1551 #ifdef TCP_INFO /* Linux 2.4.0 */
1552 IF_TCP ("tcp-info", &opt_tcp_info
)
1554 #ifdef TCP_KEEPCNT /* Linux 2.4.0 */
1555 IF_TCP ("tcp-keepcnt", &opt_tcp_keepcnt
)
1557 #ifdef TCP_KEEPIDLE /* Linux 2.4.0 */
1558 IF_TCP ("tcp-keepidle", &opt_tcp_keepidle
)
1560 #ifdef TCP_KEEPINIT /* OSF1 */
1561 IF_TCP ("tcp-keepinit", &opt_tcp_keepinit
)
1563 #ifdef TCP_KEEPINTVL /* Linux 2.4.0 */
1564 IF_TCP ("tcp-keepintvl", &opt_tcp_keepintvl
)
1566 #ifdef TCP_LINGER2 /* Linux 2.4.0 */
1567 IF_TCP ("tcp-linger2", &opt_tcp_linger2
)
1570 IF_TCP ("tcp-maxseg", &opt_tcp_maxseg
)
1571 IF_TCP ("tcp-maxseg-late", &opt_tcp_maxseg_late
)
1574 IF_TCP ("tcp-md5sig", &opt_tcp_md5sig
)
1577 IF_TCP ("tcp-nodelay", &opt_tcp_nodelay
)
1580 IF_TCP ("tcp-noopt", &opt_tcp_noopt
)
1583 IF_TCP ("tcp-nopush", &opt_tcp_nopush
)
1585 #ifdef TCP_PAWS /* OSF1 */
1586 IF_TCP ("tcp-paws", &opt_tcp_paws
)
1589 IF_TCP ("tcp-quickack", &opt_tcp_quickack
)
1592 IF_TCP ("tcp-rfc1323", &opt_tcp_rfc1323
)
1594 #ifdef TCP_SACK_DISABLE
1595 IF_TCP ("tcp-sack-disable", &opt_tcp_sack_disable
)
1597 #ifdef TCP_SACKENA /* OSF1 */
1598 IF_TCP ("tcp-sackena", &opt_tcp_sackena
)
1600 #ifdef TCP_SIGNATURE_ENABLE
1601 IF_TCP ("tcp-signature-enable", &opt_tcp_signature_enable
)
1604 IF_TCP ("tcp-stdurg", &opt_tcp_stdurg
)
1606 #ifdef TCP_SYNCNT /* Linux 2.4.0 */
1607 IF_TCP ("tcp-syncnt", &opt_tcp_syncnt
)
1609 #ifdef TCP_TSOPTENA /* OSF1 */
1610 IF_TCP ("tcp-tsoptena", &opt_tcp_tsoptena
)
1612 #ifdef TCP_WINDOW_CLAMP /* Linux 2.4.0 */
1613 IF_TCP ("tcp-window-clamp", &opt_tcp_window_clamp
)
1616 IF_IPAPP ("tcpwrap", &opt_tcpwrappers
)
1617 IF_IPAPP ("tcpwrap-dir", &opt_tcpwrap_etc
)
1618 IF_IPAPP ("tcpwrap-etc", &opt_tcpwrap_etc
)
1619 #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE)
1620 IF_IPAPP ("tcpwrap-hosts-allow-table", &opt_tcpwrap_hosts_allow_table
)
1622 #if WITH_LIBWRAP && defined(HAVE_HOSTS_DENY_TABLE)
1623 IF_IPAPP ("tcpwrap-hosts-deny-table", &opt_tcpwrap_hosts_deny_table
)
1625 IF_IPAPP ("tcpwrapper", &opt_tcpwrappers
)
1626 IF_IPAPP ("tcpwrappers", &opt_tcpwrappers
)
1628 IF_TERMIOS("termios-cfmakeraw", &opt_termios_cfmakeraw
)
1629 IF_TERMIOS("termios-rawer", &opt_termios_rawer
)
1631 IF_ANY ("text", &opt_o_text
)
1633 IF_UNIX ("tightsocklen", &xioopt_unix_tightsocklen
)
1634 IF_TERMIOS("time", &opt_vtime
)
1636 IF_SOCKET ("timestamp", &opt_so_timestamp
)
1638 IF_TERMIOS("tiocsctty", &opt_tiocsctty
)
1639 #if WITH_EXT2 && defined(EXT2_TOPDIR_FL)
1640 IF_ANY ("topdir", &opt_ext2_topdir
)
1642 IF_IP ("tos", &opt_ip_tos
)
1643 IF_TERMIOS("tostop", &opt_tostop
)
1644 IF_OPEN ("trunc", &opt_o_trunc
)
1645 #if HAVE_FTRUNCATE64
1646 IF_ANY ("truncate", &opt_ftruncate64
)
1648 IF_ANY ("truncate", &opt_ftruncate32
)
1650 #ifdef TCP_TSOPTENA /* OSF1 */
1651 IF_TCP ("tsoptena", &opt_tcp_tsoptena
)
1653 IF_IP ("ttl", &opt_ip_ttl
)
1654 IF_TUN ("tun-device", &opt_tun_device
)
1655 IF_TUN ("tun-name", &opt_tun_name
)
1656 IF_TUN ("tun-no-pi", &opt_iff_no_pi
)
1657 IF_TUN ("tun-type", &opt_tun_type
)
1658 IF_SOCKET ("type", &opt_so_type
)
1659 IF_ANY ("uid", &opt_user
)
1660 IF_NAMED ("uid-e", &opt_user_early
)
1661 IF_ANY ("uid-l", &opt_user_late
)
1662 IF_NAMED ("umask", &opt_umask
)
1663 IF_IP6 ("unicast-hops", &opt_ipv6_unicast_hops
)
1664 IF_UNIX ("unix-tightsocklen", &xioopt_unix_tightsocklen
)
1665 IF_NAMED ("unlink", &opt_unlink
)
1666 IF_NAMED ("unlink-close", &opt_unlink_close
)
1667 IF_NAMED ("unlink-early", &opt_unlink_early
)
1668 IF_NAMED ("unlink-late", &opt_unlink_late
)
1669 #if WITH_EXT2 && defined(EXT2_UNRM_FL)
1670 IF_ANY ("unrm", &opt_ext2_unrm
)
1672 IF_TUN ("up", &opt_iff_up
)
1673 #ifdef SO_USE_IFBUFS
1674 IF_SOCKET ("use-ifbufs", &opt_so_use_ifbufs
)
1675 IF_SOCKET ("useifbufs", &opt_so_use_ifbufs
)
1676 #endif /* SO_USE_IFBUFS */
1677 #ifdef SO_USELOOPBACK /* AIX433, Solaris */
1678 IF_SOCKET ("useloopback", &opt_so_useloopback
)
1679 #endif /* SO_USELOOPBACK */
1680 IF_ANY ("user", &opt_user
)
1681 IF_NAMED ("user-early", &opt_user_early
)
1682 IF_ANY ("user-late", &opt_user_late
)
1684 IF_IP ("usevc", &opt_res_usevc
)
1685 #endif /* HAVE_RESOLV_H */
1687 IF_IP6 ("v6only", &opt_ipv6_v6only
)
1690 IF_TERMIOS("vdiscard", &opt_vdiscard
)
1692 #ifdef VDSUSP /* HP-UX */
1693 IF_TERMIOS("vdsusp", &opt_vdsusp
)
1695 IF_TERMIOS("veof", &opt_veof
)
1696 IF_TERMIOS("veol", &opt_veol
)
1697 IF_TERMIOS("veol2", &opt_veol2
)
1698 IF_TERMIOS("verase", &opt_verase
)
1699 IF_OPENSSL("verify", &opt_openssl_verify
)
1700 IF_TERMIOS("vintr", &opt_vintr
)
1701 IF_TERMIOS("vkill", &opt_vkill
)
1702 IF_TERMIOS("vlnext", &opt_vlnext
)
1703 IF_TERMIOS("vmin", &opt_vmin
)
1704 IF_TERMIOS("vquit", &opt_vquit
)
1706 IF_TERMIOS("vreprint", &opt_vreprint
)
1708 IF_TERMIOS("vstart", &opt_vstart
)
1709 IF_TERMIOS("vstop", &opt_vstop
)
1710 IF_TERMIOS("vsusp", &opt_vsusp
)
1712 IF_TERMIOS("vswtc", &opt_vswtc
)
1716 IF_TERMIOS("vt0", &opt_vt0
)
1719 IF_TERMIOS("vt1", &opt_vt1
)
1721 IF_TERMIOS("vtdly", &opt_vtdly
)
1723 IF_TERMIOS("vtime", &opt_vtime
)
1725 IF_TERMIOS("vwerase", &opt_vwerase
)
1727 #if HAVE_PTY && HAVE_POLL
1728 IF_PTY ("wait-slave", &opt_pty_wait_slave
)
1729 #endif /* HAVE_PTY && HAVE_POLL */
1730 IF_ANY ("waitlock", &opt_waitlock
)
1731 #if HAVE_PTY && HAVE_POLL
1732 IF_PTY ("waitslave", &opt_pty_wait_slave
)
1733 #endif /* HAVE_PTY && HAVE_POLL */
1735 IF_TERMIOS("werase", &opt_vwerase
)
1737 #ifdef TCP_WINDOW_CLAMP /* Linux 2.4.0 */
1738 IF_TCP ("window-clamp", &opt_tcp_window_clamp
)
1741 IF_IPAPP ("wrap", &opt_tcpwrappers
)
1743 IF_OPEN ("wronly", &opt_o_wronly
)
1745 IF_TERMIOS("xcase", &opt_xcase
)
1747 #if defined(TABDLY) && defined(XTABS)
1748 IF_TERMIOS("xtabs", &opt_xtabs
)
1754 /* walks the text argument a and writes its options that conform to groups
1755 to the array opts. Uses the option table 'optionnames'.
1756 returns 0 on success, -1 on error, 1 on unknown/wrong option
1758 int parseopts(const char **a
, unsigned int groups
, struct opt
**opts
) {
1760 return parseopts_table(a
, groups
, opts
, optionnames
,
1761 sizeof(optionnames
)/sizeof(struct optname
)-1);
1765 /* walks the text argument a and writes its options that conform to groups
1766 to the array opts. Uses the specified option table.
1767 returns 0 on success, -1 on error, 1 on unknown/wrong option
1769 int parseopts_table(const char **a
, unsigned int groups
, struct opt
**opts
,
1770 const struct optname optionnames
[], size_t optionnum
) {
1774 const char *a0
= *a
;
1775 unsigned long ulongval
;
1777 long long slonglongval
;
1778 char token
[512], *tokp
; size_t len
;
1781 char optbuf
[256]; size_t optlen
;
1782 const char *endkey
[6+1];
1783 const char *endval
[5+1];
1784 const char *assign_str
= "=";
1785 const char *hquotes
[] = {
1789 const char *squotes
[] = {
1793 const char *nests
[] = {
1801 /*endkey[i++] = xioopts.chainsep;*/ /* default: "|" */
1802 endkey
[i
++] = xioopts
.pipesep
; /* default: "!!" */
1803 endkey
[i
++] = ","/*xioopts.comma*/; /* default: "," */
1808 /*endval[i++] = xioopts.chainsep;*/ /* default: "|" */
1809 endval
[i
++] = xioopts
.pipesep
; /* default: "!!" */
1810 endval
[i
++] = ","/*xioopts.comma*/; /* default: "," */
1814 *opts
= Malloc((i
+8)*sizeof(struct opt
));
1815 if (*opts
== NULL
) {
1819 (*opts
)[i
].desc
= ODESC_END
;
1824 const struct optname
*ent
;
1826 if (a
== NULL
|| *a
== NULL
|| **a
== '\0')
1829 while (!strncmp(*a
, ",", strlen(","))) { (*a
) += strlen(","); }
1832 len
= sizeof(token
); tokp
= token
;
1834 nestlex(a
, &tokp
, &len
, endkey
, hquotes
, squotes
, nests
,
1837 Error1("option too long: \"%s\"", *a
);
1839 } else if (parsres
> 0) {
1840 Error1("syntax error in \"%s\"", *a
);
1843 if (tokp
== token
) {
1844 /* no option found */
1849 ent
= (struct optname
*)
1850 keyw((struct wordent
*)optionnames
, token
, optionnum
);
1852 Error1("parseopts(): unknown option \"%s\"", token
);
1856 if (!(ent
->desc
->group
& groups
) && !(ent
->desc
->group
& GROUP_ANY
) &&
1857 !xioopts_ignoregroups
) {
1858 Error1("parseopts(): option \"%s\" not supported with this address type",
1860 Info2("parseopts() groups=%08x, ent->group=%08x",
1861 groups
, ent
->desc
->group
);
1866 (*opts
)[i
].desc
= ent
->desc
;
1868 if (!strncmp(*a
, assign_str
, strlen(assign_str
))) {
1869 /* there is an assignment (mostly "=") */
1870 (*a
) += strlen(assign_str
);
1871 len
= sizeof(token
); tokp
= token
;
1873 nestlex(a
, &tokp
, &len
, endval
, hquotes
, squotes
, nests
,
1876 Error1("option too long: \"%s\"", *a
);
1878 } else if (parsres
> 0) {
1879 Error1("syntax error in \"%s\"", *a
);
1890 switch (ent
->desc
->type
) {
1893 Error1("no value permitted for option \"%s\"",
1894 ent
->desc
->defname
);
1897 Info1("setting option \"%s\"", ent
->desc
->defname
);
1900 if (!assign
) { Error1("option \"%s\": value required", a0
);
1903 if ((result
= dalan(token
, optbuf
, &optlen
, sizeof(optbuf
))) != 0) {
1904 Error1("parseopts(): problem with \"%s\" data", token
);
1907 if (((*opts
)[i
].value
.u_bin
.b_data
= memdup(optbuf
, optlen
)) == NULL
) {
1908 Error1("memdup(, "F_Zu
"): out of memory", optlen
);
1911 (*opts
)[i
].value
.u_bin
.b_len
= optlen
;
1917 ul
= strtoul(token
, &rest
/*!*/, 0);
1918 if (ul
> UCHAR_MAX
) {
1919 Error3("parseopts(%s): byte value exceeds limit (%lu vs. %u), using max",
1921 (*opts
)[i
].value
.u_byte
= UCHAR_MAX
;
1923 (*opts
)[i
].value
.u_byte
= ul
;
1926 (*opts
)[i
].value
.u_byte
= 1;
1928 Info2("setting option \"%s\" to %d", ent
->desc
->defname
,
1929 (*opts
)[i
].value
.u_byte
);
1931 #if HAVE_BASIC_OFF_T==3
1937 (*opts
)[i
].value
.u_int
= strtoul(token
, &rest
/*!*/, 0);
1939 (*opts
)[i
].value
.u_int
= 1;
1941 Info2("setting option \"%s\" to %d", ent
->desc
->defname
,
1942 (*opts
)[i
].value
.u_int
);
1946 (*opts
)[i
].value
.u_bool
= 1;
1949 (*opts
)[i
].value
.u_bool
= strtoul(token
, &rest
, 0);
1950 if (rest
&& *rest
) {
1951 Error1("error in option \"%s\": \"0\" or \"1\" required", a0
);
1954 Info2("setting option \"%s\" to %d", ent
->desc
->defname
,
1955 (*opts
)[i
].value
.u_bool
);
1958 #if HAVE_BASIC_SIZE_T==4
1963 (*opts
)[i
].value
.u_uint
= 1;
1966 ulongval
= strtoul(token
, &rest
/*!*/, 0);
1967 if (ulongval
> UINT_MAX
) {
1968 Error3("parseopts(%s): unsigned int value exceeds limit (%lu vs. %u), using max",
1969 a0
, ulongval
, UINT_MAX
);
1971 (*opts
)[i
].value
.u_uint
= ulongval
;
1973 Info2("setting option \"%s\" to %u", ent
->desc
->defname
,
1974 (*opts
)[i
].value
.u_uint
);
1977 #if HAVE_BASIC_SIZE_T==2
1982 (*opts
)[i
].value
.u_ushort
= 1;
1985 ulongval
= strtoul(token
, &rest
/*!*/, 0);
1986 if (ulongval
> USHRT_MAX
) {
1987 Error3("parseopts(%s): unsigned short value exceeds limit (%lu vs. %u), using max",
1988 a0
, ulongval
, USHRT_MAX
);
1990 (*opts
)[i
].value
.u_ushort
= ulongval
;
1992 Info2("setting option \"%s\" to %u", ent
->desc
->defname
,
1993 (*opts
)[i
].value
.u_ushort
);
1996 #if HAVE_BASIC_OFF_T==5
1999 #if HAVE_STAT64 && defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T==5
2004 (*opts
)[i
].value
.u_long
= 1;
2007 slongval
= strtol(token
, &rest
, 0);
2008 (*opts
)[i
].value
.u_long
= slongval
;
2010 Info2("setting option \"%s\" to %lu", ent
->desc
->defname
,
2011 (*opts
)[i
].value
.u_long
);
2014 #if HAVE_BASIC_SIZE_T==6
2019 (*opts
)[i
].value
.u_ulong
= 1;
2022 ulongval
= strtoul(token
, &rest
, 0);
2023 (*opts
)[i
].value
.u_ulong
= ulongval
;
2025 Info2("setting option \"%s\" to %lu", ent
->desc
->defname
,
2026 (*opts
)[i
].value
.u_ulong
);
2029 #if HAVE_BASIC_OFF_T==7
2032 #if HAVE_TYPE_LONGLONG
2034 # if HAVE_STAT64 && defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T==7
2038 (*opts
)[i
].value
.u_longlong
= 1;
2042 slonglongval
= strtoll(token
, &rest
, 0);
2044 /* in this case, input value range is limited */
2045 slonglongval
= strtol(token
, &rest
, 0);
2046 # endif /* HAVE_STRTOLL */
2047 (*opts
)[i
].value
.u_longlong
= slonglongval
;
2049 Info2("setting option \"%s\" to %Lu", ent
->desc
->defname
,
2050 (*opts
)[i
].value
.u_longlong
);
2052 #endif /* HAVE_TYPE_LONGLONG */
2056 Error1("option \"%s\": value required", a0
);
2059 if (isdigit((*token
)&0xff)) {
2061 (*opts
)[i
].value
.u_uidt
= strtoul(token
, &rest
/*!*/, 0);
2064 if ((pwd
= getpwnam(token
)) == NULL
) {
2065 Error1("getpwnam(\"%s\"): no such user", token
);
2068 (*opts
)[i
].value
.u_uidt
= getpwnam(token
)->pw_uid
;
2070 Info2("setting option \"%s\" to %u", ent
->desc
->defname
,
2071 (*opts
)[i
].value
.u_uidt
);
2075 if (!assign
) { Error1("option \"%s\": value required", a0
);
2077 if (isdigit((token
[0])&0xff)) {
2079 (*opts
)[i
].value
.u_gidt
= strtoul(token
, &rest
/*!*/, 0);
2082 grp
= getgrnam(token
);
2084 Error1("getgrnam(\"%s\"): no such group", token
);
2087 (*opts
)[i
].value
.u_gidt
= grp
->gr_gid
;
2089 Info2("setting option \"%s\" to %u", ent
->desc
->defname
,
2090 (*opts
)[i
].value
.u_gidt
);
2094 if (!assign
) { Error1("option \"%s\": value required", a0
);
2099 (*opts
)[i
].value
.u_modet
= strtoul(token
, &rest
/*!*/, 8);
2101 Info2("setting option \"%s\" to %u", ent
->desc
->defname
,
2102 (*opts
)[i
].value
.u_modet
);
2107 Error1("option \"%s\": value required", a0
);
2110 if (((*opts
)[i
].value
.u_string
= strdup(token
)) == NULL
) {
2111 Error("out of memory"); return -1;
2113 Info2("setting option \"%s\" to \"%s\"", ent
->desc
->defname
,
2114 (*opts
)[i
].value
.u_string
);
2117 case TYPE_STRING_NULL
:
2119 (*opts
)[i
].value
.u_string
= NULL
;
2120 Info1("setting option \"%s\" to NULL", ent
->desc
->defname
);
2122 (*opts
)[i
].value
.u_string
= strdup(token
);
2123 Info2("setting option \"%s\" to \"%s\"", ent
->desc
->defname
,
2124 (*opts
)[i
].value
.u_string
);
2136 Error1("option \"%s\": value required", a0
);
2140 val
= strtod(token
, NULL
);
2141 if (val
== HUGE_VAL
|| val
== -HUGE_VAL
||
2142 val
== 0.0 && errno
== ERANGE
) {
2143 Error2("strtod(\"%s\", NULL): %s", token
, strerror(errno
));
2146 (*opts
)[i
].value
.u_timeval
.tv_sec
= val
;
2147 (*opts
)[i
].value
.u_timeval
.tv_usec
=
2148 (val
-(*opts
)[i
].value
.u_timeval
.tv_sec
) * 1000000;
2152 #if HAVE_STRUCT_TIMESPEC
2155 Error1("option \"%s\": value required", a0
);
2159 val
= strtod(token
, NULL
);
2160 if (val
== HUGE_VAL
|| val
== -HUGE_VAL
||
2161 val
== 0.0 && errno
== ERANGE
) {
2162 Error2("strtod(\"%s\", NULL): %s", token
, strerror(errno
));
2165 (*opts
)[i
].value
.u_timespec
.tv_sec
= val
;
2166 (*opts
)[i
].value
.u_timespec
.tv_nsec
=
2167 (val
-(*opts
)[i
].value
.u_timespec
.tv_sec
) * 1000000000.;
2170 #endif /* HAVE_STRUCT_TIMESPEC */
2172 #if HAVE_STRUCT_LINGER
2175 Error1("option \"%s\": value required", a0
);
2178 (*opts
)[i
].value
.u_linger
.l_onoff
= 1;
2181 (*opts
)[i
].value
.u_linger
.l_linger
= strtoul(token
, &rest
/*!*/, 0);
2183 Info3("setting option \"%s\" to {%d,%d}", ent
->desc
->defname
,
2184 (*opts
)[i
].value
.u_linger
.l_onoff
,
2185 (*opts
)[i
].value
.u_linger
.l_linger
);
2187 #endif /* HAVE_STRUCT_LINGER */
2192 Error1("option \"%s\": values required", a0
);
2197 (*opts
)[i
].value
.u_int
= strtoul(token
, &rest
, 0);
2199 Error1("option \"%s\": 2 arguments required",
2200 ent
->desc
->defname
);
2203 (*opts
)[i
].value2
.u_int
= strtoul(rest
, &rest
, 0);
2205 Info3("setting option \"%s\" to %d:%d", ent
->desc
->defname
,
2206 (*opts
)[i
].value
.u_int
, (*opts
)[i
].value2
.u_int
);
2211 Error1("option \"%s\": values required", a0
);
2216 (*opts
)[i
].value
.u_int
= strtoul(token
, &rest
, 0);
2218 Error1("option \"%s\": 2 arguments required",
2219 ent
->desc
->defname
);
2223 if ((result
= dalan(rest
, optbuf
, &optlen
, sizeof(optbuf
))) != 0) {
2224 Error1("parseopts(): problem with \"%s\" data", rest
);
2227 if (((*opts
)[i
].value2
.u_bin
.b_data
= memdup(optbuf
, optlen
)) == NULL
) {
2228 Error1("memdup(, "F_Zu
"): out of memory", optlen
);
2231 (*opts
)[i
].value2
.u_bin
.b_len
= optlen
;
2233 Info2("setting option \"%s\" to %d:..."/*!!!*/, ent
->desc
->defname
,
2234 (*opts
)[i
].value
.u_int
);
2237 case TYPE_INT_STRING
:
2239 Error1("option \"%s\": values required", a0
);
2244 (*opts
)[i
].value
.u_int
= strtoul(token
, &rest
, 0);
2246 Error1("option \"%s\": 2 arguments required",
2247 ent
->desc
->defname
);
2250 if (((*opts
)[i
].value2
.u_string
= strdup(rest
)) == NULL
) {
2251 Error("out of memory"); return -1;
2254 Info3("setting option \"%s\" to %d:\"%s\"", ent
->desc
->defname
,
2255 (*opts
)[i
].value
.u_int
, (*opts
)[i
].value2
.u_string
);
2258 case TYPE_INT_INT_INT
:
2260 Error1("option \"%s\": values required", a0
);
2265 (*opts
)[i
].value
.u_int
= strtoul(token
, &rest
, 0);
2267 Error1("option \"%s\": 3 arguments required",
2268 ent
->desc
->defname
);
2271 (*opts
)[i
].value2
.u_int
= strtoul(rest
, &rest
, 0);
2273 Error1("option \"%s\": 3 arguments required",
2274 ent
->desc
->defname
);
2277 (*opts
)[i
].value3
.u_int
= strtoul(rest
, &rest
, 0);
2279 Info4("setting option \"%s\" to %d:%d:%d", ent
->desc
->defname
,
2280 (*opts
)[i
].value
.u_int
, (*opts
)[i
].value2
.u_int
, (*opts
)[i
].value3
.u_int
);
2283 case TYPE_INT_INT_BIN
:
2285 Error1("option \"%s\": values required", a0
);
2290 (*opts
)[i
].value
.u_int
= strtoul(token
, &rest
, 0);
2292 Error1("option \"%s\": 3 arguments required",
2293 ent
->desc
->defname
);
2296 (*opts
)[i
].value2
.u_int
= strtoul(rest
, &rest
, 0);
2298 Error1("option \"%s\": 3 arguments required",
2299 ent
->desc
->defname
);
2303 if ((result
= dalan(rest
, optbuf
, &optlen
, sizeof(optbuf
))) != 0) {
2304 Error1("parseopts(): problem with \"%s\" data", rest
);
2307 if (((*opts
)[i
].value3
.u_bin
.b_data
= memdup(optbuf
, optlen
)) == NULL
) {
2308 Error1("memdup(, "F_Zu
"): out of memory", optlen
);
2311 (*opts
)[i
].value3
.u_bin
.b_len
= optlen
;
2313 Info3("setting option \"%s\" to %d:%d:..."/*!!!*/, ent
->desc
->defname
,
2314 (*opts
)[i
].value
.u_int
, (*opts
)[i
].value2
.u_int
);
2317 case TYPE_INT_INT_STRING
:
2319 Error1("option \"%s\": values required", a0
);
2324 (*opts
)[i
].value
.u_int
= strtoul(token
, &rest
, 0);
2326 Error1("option \"%s\": 3 arguments required",
2327 ent
->desc
->defname
);
2330 (*opts
)[i
].value2
.u_int
= strtoul(rest
, &rest
, 0);
2332 Error1("option \"%s\": 3 arguments required",
2333 ent
->desc
->defname
);
2336 if (((*opts
)[i
].value3
.u_string
= strdup(rest
)) == NULL
) {
2337 Error("out of memory"); return -1;
2340 Info4("setting option \"%s\" to %d:%d:\"%s\"", ent
->desc
->defname
,
2341 (*opts
)[i
].value
.u_int
, (*opts
)[i
].value2
.u_int
,
2342 (*opts
)[i
].value3
.u_string
);
2344 #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)
2348 /* we do not resolve the addresses here because we do not yet know
2349 if we are coping with a IPv4 or IPv6 socat address */
2350 const char *ends
[] = { ":", NULL
};
2351 const char *nests
[] = { "[","]", NULL
};
2352 char buff
[512], *buffp
=buff
; size_t bufspc
= sizeof(buff
)-1;
2354 /* parse first IP address, expect ':' */
2358 nestlex((const char **)&tokp
, &buffp
, &bufspc
,
2359 ends
, NULL
, NULL
, nests
,
2360 true, false, false);
2362 Error1("option too long: \"%s\"", *a
);
2364 } else if (parsres
> 0) {
2365 Error1("syntax error in \"%s\"", *a
);
2369 Error1("syntax in option %s: missing ':'", token
);
2372 (*opts
)[i
].value
.u_ip_mreq
.multiaddr
= strdup(buff
); /*!!! NULL */
2375 /* parse second IP address, expect ':' or '\0'' */
2379 nestlex((const char **)&tokp
, &buffp
, &bufspc
,
2380 ends
, NULL
, NULL
, nests
,
2381 true, false, false);
2383 Error1("option too long: \"%s\"", *a
);
2385 } else if (parsres
> 0) {
2386 Error1("syntax error in \"%s\"", *a
);
2390 (*opts
)[i
].value
.u_ip_mreq
.param2
= strdup(buff
); /*!!! NULL */
2392 #if HAVE_STRUCT_IP_MREQN
2393 if (*tokp
++ == ':') {
2394 strncpy((*opts
)[i
].value
.u_ip_mreq
.ifindex
, tokp
, IF_NAMESIZE
); /* ok */
2395 Info4("setting option \"%s\" to {\"%s\",\"%s\",\"%s\"}",
2397 (*opts
)[i
].value
.u_ip_mreq
.multiaddr
,
2398 (*opts
)[i
].value
.u_ip_mreq
.param2
,
2399 (*opts
)[i
].value
.u_ip_mreq
.ifindex
);
2401 (*opts
)[i
].value
.u_ip_mreq
.ifindex
[0] = '\0';
2402 Info3("setting option \"%s\" to {\"%s\",\"%s\"}",
2404 (*opts
)[i
].value
.u_ip_mreq
.multiaddr
,
2405 (*opts
)[i
].value
.u_ip_mreq
.param2
);
2407 #else /* !HAVE_STRUCT_IP_MREQN */
2408 Info3("setting option \"%s\" to {0x%08x,0x%08x}",
2410 (*opts
)[i
].value
.u_ip_mreq
.multiaddr
,
2411 (*opts
)[i
].value
.u_ip_mreq
.param2
);
2412 #endif /* !HAVE_STRUCT_IP_MREQN */
2415 #endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */
2420 struct sockaddr_in sa
; socklen_t salen
= sizeof(sa
);
2421 const char *ends
[] = { NULL
};
2422 const char *nests
[] = { "[","]", NULL
};
2423 char buff
[512], *buffp
=buff
; size_t bufspc
= sizeof(buff
)-1;
2427 nestlex((const char **)&tokp
, &buffp
, &bufspc
,
2428 ends
, NULL
, NULL
, nests
,
2429 true, false, false);
2431 Error1("option too long: \"%s\"", *a
);
2433 } else if (parsres
> 0) {
2434 Error1("syntax error in \"%s\"", *a
);
2437 if (*tokp
!= '\0') {
2438 Error1("trailing data in option \"%s\"", token
);
2441 if (xiogetaddrinfo(buff
, NULL
, AF_INET
, SOCK_DGRAM
, IPPROTO_IP
,
2442 (union sockaddr_union
*)&sa
, &salen
,
2443 0, 0/*!!!*/) != STAT_OK
) {
2444 opt
->desc
= ODESC_ERROR
; continue;
2446 opt
->value
.u_ip4addr
= sa
.sin_addr
;
2449 #endif /* defined(WITH_IP4) */
2452 Error2("parseopts(): internal error on option \"%s\": unimplemented type %d",
2453 ent
->desc
->defname
, ent
->desc
->type
);
2459 *opts
= Realloc(*opts
, (i
+8) * sizeof(struct opt
));
2460 if (*opts
== NULL
) {
2466 /*(*opts)[i+1].desc = ODESC_END;*/
2467 (*opts
)[i
].desc
= ODESC_END
;
2471 /* copy the already parsed options for repeated application, but only those
2472 matching groups ANY and <groups> */
2473 struct opt
*copyopts(const struct opt
*opts
, unsigned int groups
) {
2477 if (!opts
) return NULL
;
2479 /* just count the options in the array */
2480 i
= 0; while (opts
[i
].desc
!= ODESC_END
) {
2485 new = Malloc(n
* sizeof(struct opt
));
2492 if (opts
[i
].desc
== ODESC_DONE
) {
2493 new[j
].desc
= ODESC_DONE
;
2494 } else if ((opts
[i
].desc
->group
& (GROUP_ANY
&~GROUP_PROCESS
)) ||
2495 (opts
[i
].desc
->group
& groups
)) {
2500 new[j
].desc
= ODESC_END
;
2504 /* move options to a new options list
2505 move only those matching <groups> */
2506 struct opt
*moveopts(struct opt
*opts
, unsigned int groups
) {
2510 if (!opts
) return NULL
;
2512 /* just count the options in the array */
2513 i
= 0; j
= 0; while (opts
[i
].desc
!= ODESC_END
) {
2514 if (opts
[i
].desc
!= ODESC_DONE
&&
2515 opts
[i
].desc
!= ODESC_ERROR
)
2521 new = Malloc((j
+1) * sizeof(struct opt
));
2528 if (opts
[i
].desc
== ODESC_DONE
||
2529 opts
[i
].desc
== ODESC_ERROR
) {
2531 } else if (opts
[i
].desc
->group
& groups
) {
2533 opts
[i
].desc
= ODESC_DONE
;
2537 new[j
].desc
= ODESC_END
;
2541 /* return the number of yet unconsumed options; -1 on error */
2542 int leftopts(const struct opt
*opts
) {
2543 const struct opt
*opt
= opts
;
2546 if (!opts
) return 0;
2548 while (opt
->desc
!= ODESC_END
) {
2549 if (opt
->desc
!= ODESC_DONE
) {
2557 /* show as warning which options are still unused */
2558 int showleft(const struct opt
*opts
) {
2559 const struct opt
*opt
= opts
;
2561 while (opt
->desc
!= ODESC_END
) {
2562 if (opt
->desc
!= ODESC_DONE
) {
2563 Warn1("showleft(): option \"%s\" not inquired", opt
->desc
->defname
);
2571 /* determines the address group from mode_t */
2572 /* does not set GROUP_FD; cannot determine GROUP_TERMIOS ! */
2573 int _groupbits(mode_t mode
) {
2574 unsigned int result
= 0;
2576 switch ((mode
&S_IFMT
)>>12) {
2577 case (S_IFIFO
>>12): /* 1, FIFO */
2578 result
= GROUP_FIFO
; break;
2579 case (S_IFCHR
>>12): /* 2, character device */
2580 result
= GROUP_CHR
|GROUP_TERMIOS
; break;
2581 case (S_IFDIR
>>12): /* 4, directory !!! not supported */
2582 result
= GROUP_NONE
; break;
2583 case (S_IFBLK
>>12): /* 6, block device */
2584 result
= GROUP_BLK
; break;
2585 case (S_IFREG
>>12): /* 8, regular file */
2586 result
= GROUP_REG
; break;
2587 case (S_IFLNK
>>12): /* 10, symbolic link !!! not supported */
2588 result
= GROUP_NONE
; break;
2590 case (S_IFSOCK
>>12): /* 12, socket */
2591 result
= GROUP_SOCKET
|GROUP_SOCK_UNIX
; break;
2593 default: /* some systems (pure POSIX.1) do not know S_IFSOCK */
2594 result
= GROUP_SOCKET
|GROUP_SOCK_UNIX
; break;
2597 Debug2("_groupbits(%d) -> %d", mode
, result
);
2601 /* does not set GROUP_FD */
2602 int groupbits(int fd
) {
2607 #endif /* !HAVE_STAT64 */
2612 Fstat64(fd
, &buf
) < 0
2615 #endif /* !HAVE_STAT64 */
2617 Error4("groupbits(%d): fstat(%d, %p): %s",
2618 fd
, fd
, &buf
, strerror(errno
));
2621 result
= _groupbits(buf
.st_mode
&S_IFMT
);
2622 if (result
== GROUP_CHR
) {
2623 if (Isatty(fd
) > 0) {
2624 result
|= GROUP_TERMIOS
;
2630 #if 0 /* currently not used */
2631 int retropt(struct opt
*opts
, int optcode
, union integral
*result
) {
2632 struct opt
*opt
= opts
;
2634 while (opt
->desc
!= ODESC_END
) {
2635 if (opt
->desc
!= ODESC_DONE
&& opt
->desc
->optcode
== optcode
) {
2636 *result
= opt
->value
;
2637 opt
->desc
= ODESC_DONE
;
2646 static struct opt
*xio_findopt(struct opt
*opts
, int optcode
) {
2647 struct opt
*opt
= opts
;
2649 while (opt
->desc
!= ODESC_END
) {
2650 if (opt
->desc
!= ODESC_DONE
&& opt
->desc
->optcode
== optcode
) {
2658 int retropt_timespec(struct opt
*opts
, int optcode
, struct timespec
*result
) {
2661 if (!(opt
= xio_findopt(opts
, optcode
))) {
2664 *result
= opt
->value
.u_timespec
;
2665 opt
->desc
= ODESC_DONE
;
2670 /* Looks for the first option of type <optcode>. If the option is found,
2671 this function stores its bool value in *result, "consumes" the
2672 option, and returns 0.
2673 If the option is not found, *result is not modified, and -1 is returned. */
2674 int retropt_bool(struct opt
*opts
, int optcode
, bool *result
) {
2675 struct opt
*opt
= opts
;
2677 while (opt
->desc
!= ODESC_END
) {
2678 if (opt
->desc
!= ODESC_DONE
&& opt
->desc
->optcode
== optcode
) {
2679 *result
= opt
->value
.u_bool
;
2680 opt
->desc
= ODESC_DONE
;
2688 #if 0 /* currently not used */
2689 /* Looks for the first option of type <optcode>. If the option is found,
2690 this function stores its short value in *result, "consumes" the
2691 option, and returns 0.
2692 If the option is not found, *result is not modified, and -1 is returned. */
2693 int retropt_short(struct opt
*opts
, int optcode
, short *result
) {
2694 struct opt
*opt
= opts
;
2696 while (opt
->desc
!= ODESC_END
) {
2697 if (opt
->desc
!= ODESC_DONE
&& opt
->desc
->optcode
== optcode
) {
2698 *result
= opt
->value
.u_short
;
2699 opt
->desc
= ODESC_DONE
;
2708 /* Looks for the first option of type <optcode>. If the option is found,
2709 this function stores its unsigned short value in *result, "consumes" the
2710 option, and returns 0.
2711 If the option is not found, *result is not modified, and -1 is returned. */
2712 int retropt_ushort(struct opt
*opts
, int optcode
, unsigned short *result
) {
2713 struct opt
*opt
= opts
;
2715 while (opt
->desc
!= ODESC_END
) {
2716 if (opt
->desc
!= ODESC_DONE
&& opt
->desc
->optcode
== optcode
) {
2717 *result
= opt
->value
.u_ushort
;
2718 opt
->desc
= ODESC_DONE
;
2726 /* Looks for the first option of type <optcode>. If the option is found,
2727 this function stores its int value in *result, "consumes" the
2728 option, and returns 0.
2729 If the option is not found, *result is not modified, and -1 is returned. */
2730 int retropt_int(struct opt
*opts
, int optcode
, int *result
) {
2731 struct opt
*opt
= opts
;
2733 while (opt
->desc
!= ODESC_END
) {
2734 if (opt
->desc
!= ODESC_DONE
&& opt
->desc
->optcode
== optcode
) {
2735 switch (opt
->desc
->type
) {
2736 case TYPE_INT
: *result
= opt
->value
.u_int
; break;
2737 case TYPE_STRING
: *result
= strtol(opt
->value
.u_string
, NULL
, 0);
2739 default: Error2("cannot convert type %d of option %s to int",
2740 opt
->desc
->type
, opt
->desc
->defname
);
2741 opt
->desc
= ODESC_ERROR
;
2744 opt
->desc
= ODESC_DONE
;
2752 /* Looks for the first option of type <optcode>. If the option is found,
2753 this function stores its unsigned int value in *result, "consumes" the
2754 option, and returns 0.
2755 If the option is not found, *result is not modified, and -1 is returned. */
2756 int retropt_uint(struct opt
*opts
, int optcode
, unsigned int *result
) {
2757 struct opt
*opt
= opts
;
2759 while (opt
->desc
!= ODESC_END
) {
2760 if (opt
->desc
!= ODESC_DONE
&& opt
->desc
->optcode
== optcode
) {
2761 *result
= opt
->value
.u_uint
;
2762 opt
->desc
= ODESC_DONE
;
2770 /* Looks for the first option of type <optcode>. If the option is found,
2771 this function stores its long value in *result, "consumes" the option,
2773 If the option is not found, *result is not modified, and -1 is returned. */
2774 int retropt_long(struct opt
*opts
, int optcode
, long *result
) {
2775 struct opt
*opt
= opts
;
2777 while (opt
->desc
!= ODESC_END
) {
2778 if (opt
->desc
!= ODESC_DONE
&& opt
->desc
->optcode
== optcode
) {
2779 *result
= opt
->value
.u_long
;
2780 opt
->desc
= ODESC_DONE
;
2788 /* Looks for the first option of type <optcode>. If the option is found,
2789 this function stores its unsigned long value in *result, "consumes" the
2790 option, and returns 0.
2791 If the option is not found, *result is not modified, and -1 is returned. */
2792 int retropt_ulong(struct opt
*opts
, int optcode
, unsigned long *result
) {
2793 struct opt
*opt
= opts
;
2795 while (opt
->desc
!= ODESC_END
) {
2796 if (opt
->desc
!= ODESC_DONE
&& opt
->desc
->optcode
== optcode
) {
2797 *result
= opt
->value
.u_ulong
;
2798 opt
->desc
= ODESC_DONE
;
2806 #if 0 /* currently not used */
2807 /* get the value of a FLAG typed option, and apply it to the appropriate
2808 bit position. Mark the option as consumed (done). return 0 if options was found and successfully applied,
2809 or -1 if option was not in opts */
2810 int retropt_flag(struct opt
*opts
, int optcode
, flags_t
*result
) {
2811 struct opt
*opt
= opts
;
2813 while (opt
->desc
!= ODESC_END
) {
2814 if (opt
->desc
!= ODESC_DONE
&& opt
->desc
->optcode
== optcode
) {
2815 if (opt
->value
.u_bool
) {
2816 *result
|= opt
->desc
->major
;
2818 *result
&= ~opt
->desc
->major
;
2820 opt
->desc
= ODESC_DONE
;
2829 /* Looks for the first option of type <optcode>. If the option is found,
2830 this function stores its character pointer value in *result, "consumes" the
2831 option, and returns 0. Note that, for options of type STRING_NULL, the
2832 character pointer might degenerate to NULL.
2833 The resulting string is malloc'ed and should be freed after use.
2834 If the option is not found, *result is not modified, and -1 is returned.
2836 int retropt_string(struct opt
*opts
, int optcode
, char **result
) {
2837 struct opt
*opt
= opts
;
2839 while (opt
->desc
!= ODESC_END
) {
2840 if (opt
->desc
!= ODESC_DONE
&& opt
->desc
->optcode
== optcode
) {
2841 if (opt
->value
.u_string
== NULL
) {
2843 } else if ((*result
= strdup(opt
->value
.u_string
)) == NULL
) {
2844 Error1("strdup("F_Zu
"): out of memory",
2845 strlen(opt
->value
.u_string
));
2848 opt
->desc
= ODESC_DONE
;
2858 /* looks for a bind option and, if found, overwrites the complete contents of
2859 sa with the appropriate value(s).
2860 returns STAT_OK if option exists and could be resolved,
2861 STAT_NORETRY if option exists but had error,
2862 or STAT_NOACTION if it does not exist */
2863 /* currently only for IP (v4, v6) and raw (PF_UNSPEC) */
2864 int retropt_bind(struct opt
*opts
,
2868 struct sockaddr
*sa
,
2870 int feats
, /* TCP etc: 1..address allowed,
2871 3..address and port allowed
2872 UNIX (or'd): 1..tight
2875 unsigned long res_opts0
, unsigned long res_opts1
) {
2876 const char portsep
[] = ":";
2877 const char *ends
[] = { portsep
, NULL
};
2878 const char *nests
[] = { "[", "]", NULL
};
2880 char *bindname
, *bindp
;
2881 char hostname
[512], *hostp
= hostname
, *portp
= NULL
;
2882 size_t hostlen
= sizeof(hostname
)-1;
2886 if (retropt_string(opts
, OPT_BIND
, &bindname
) < 0) {
2887 return STAT_NOACTION
;
2896 dalan(bindname
, (char *)sa
->sa_data
, &p
, *salen
-sizeof(sa
->sa_family
));
2897 *salen
= p
+ sizeof(sa
->sa_family
);
2899 #if HAVE_STRUCT_SOCKADDR_SALEN
2900 sizeof(sa
->sa_len
) +
2902 sizeof(sa
->sa_family
);
2903 #if HAVE_STRUCT_SOCKADDR_SALEN
2904 sa
->sa_len
= *salen
;
2909 #if WITH_IP4 || WITH_IP6
2915 #endif /*WITH_IP6 */
2916 portallowed
= (feats
>=2);
2918 nestlex((const char **)&bindp
, &hostp
, &hostlen
, ends
, NULL
, NULL
, nests
,
2919 true, false, false);
2921 Error1("option too long: \"%s\"", bindp
);
2922 return STAT_NORETRY
;
2923 } else if (parsres
> 0) {
2924 Error1("syntax error in \"%s\"", bindp
);
2925 return STAT_NORETRY
;
2928 if (!strncmp(bindp
, portsep
, strlen(portsep
))) {
2930 Error("port specification not allowed in this bind option");
2931 return STAT_NORETRY
;
2933 portp
= bindp
+ strlen(portsep
);
2937 xiogetaddrinfo(hostname
[0]!='\0'?hostname
:NULL
, portp
,
2938 af
, socktype
, ipproto
,
2939 (union sockaddr_union
*)sa
, salen
,
2940 res_opts0
, res_opts1
))
2942 Error("error resolving bind option");
2943 return STAT_NORETRY
;
2946 #endif /* WITH_IP4 || WITH_IP6 */
2951 bool abstract
= (feats
&2);
2952 bool tight
= (feats
&1);
2953 struct sockaddr_un
*s_un
= (struct sockaddr_un
*)sa
;
2954 *salen
= xiosetunix(af
, s_un
, bindname
, abstract
, tight
);
2957 #endif /* WITH_UNIX */
2960 Error1("bind: unknown address family %d", af
);
2961 return STAT_NORETRY
;
2965 #endif /* _WITH_SOCKET */
2968 /* applies to fd all options belonging to phase */
2969 /* note: not all options can be applied this way (e.g. OFUNC_SPEC with PH_OPEN)
2970 implemented are: OFUNC_FCNTL, OFUNC_SOCKOPT (probably not all types),
2971 OFUNC_TERMIOS_FLAG, OFUNC_TERMIOS_PATTERN, and some OFUNC_SPEC */
2972 int applyopts(int fd
, struct opt
*opts
, enum e_phase phase
) {
2975 opt
= opts
; while (opt
&& opt
->desc
!= ODESC_END
) {
2976 if (opt
->desc
== ODESC_DONE
||
2977 (phase
!= PH_ALL
&& opt
->desc
->phase
!= phase
)) {
2980 if (opt
->desc
->func
== OFUNC_SEEK32
) {
2981 if (Lseek(fd
, opt
->value
.u_off
, opt
->desc
->major
) < 0) {
2982 Error4("lseek(%d, "F_off
", %d): %s",
2983 fd
, opt
->value
.u_off
, opt
->desc
->major
, strerror(errno
));
2986 } else if (opt
->desc
->func
== OFUNC_SEEK64
) {
2988 /*! this depends on off64_t atomic type */
2989 if (Lseek64(fd
, opt
->value
.u_off64
, opt
->desc
->major
) < 0) {
2990 Error4("lseek64(%d, "F_off64
", %d): %s",
2991 fd
, opt
->value
.u_off64
, opt
->desc
->major
, strerror(errno
));
2993 #endif /* HAVE_LSEEK64 */
2995 } else if (opt
->desc
->func
== OFUNC_FCNTL
) {
2998 /* retrieve existing flag setttings */
2999 if ((flag
= Fcntl(fd
, opt
->desc
->major
-1)) < 0) {
3000 Error3("fcntl(%d, %d): %s",
3001 fd
, opt
->desc
->major
, strerror(errno
));
3002 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3004 if (opt
->value
.u_bool
) {
3005 flag
|= opt
->desc
->minor
;
3007 flag
&= ~opt
->desc
->minor
;
3009 if (Fcntl_l(fd
, opt
->desc
->major
, flag
) < 0) {
3010 Error4("fcntl(%d, %d, %d): %s",
3011 fd
, opt
->desc
->major
, flag
, strerror(errno
));
3012 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3016 } else if (opt
->desc
->func
== OFUNC_IOCTL
) {
3017 if (Ioctl(fd
, opt
->desc
->major
, (void *)&opt
->value
) < 0) {
3018 Error4("ioctl(%d, 0x%x, %p): %s",
3019 fd
, opt
->desc
->major
, (void *)&opt
->value
, strerror(errno
));
3020 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3023 } else if (opt
->desc
->func
== OFUNC_IOCTL_MASK_LONG
) {
3025 int getreq
= opt
->desc
->major
;
3026 int setreq
= opt
->desc
->minor
;
3027 long mask
= opt
->desc
->arg3
;
3029 if (Ioctl(fd
, getreq
, (void *)&val
) < 0) {
3030 Error4("ioctl(%d, 0x%x, %p): %s",
3031 fd
, opt
->desc
->major
, (void *)&val
, strerror(errno
));
3032 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3035 if (opt
->value
.u_bool
) val
|= mask
;
3036 if (Ioctl(fd
, setreq
, (void *)&val
) < 0) {
3037 Error4("ioctl(%d, 0x%x, %p): %s",
3038 fd
, opt
->desc
->major
, (void *)&val
, strerror(errno
));
3039 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3042 } else if (opt
->desc
->func
== OFUNC_IOCTL_GENERIC
) {
3043 switch (opt
->desc
->type
) {
3045 if (Ioctl(fd
, opt
->value
.u_int
, NULL
) < 0) {
3046 Error3("ioctl(%d, 0x%x, NULL): %s",
3047 fd
, opt
->value
.u_int
, strerror(errno
));
3048 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3052 if (Ioctl_int(fd
, opt
->value
.u_int
, opt
->value2
.u_int
) < 0) {
3053 Error4("ioctl(%d, 0x%x, 0x%x): %s",
3054 fd
, opt
->value
.u_int
, opt
->value2
.u_int
, strerror(errno
));
3055 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3059 if (Ioctl(fd
, opt
->value
.u_int
, (void *)&opt
->value2
.u_int
) < 0) {
3060 Error4("ioctl(%d, 0x%x, %p): %s",
3061 fd
, opt
->value
.u_int
, (void *)&opt
->value2
.u_int
, strerror(errno
));
3062 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3066 if (Ioctl(fd
, opt
->value
.u_int
, (void *)opt
->value2
.u_bin
.b_data
) < 0) {
3067 Error4("ioctl(%d, 0x%x, %p): %s",
3068 fd
, opt
->value
.u_int
, (void *)opt
->value2
.u_bin
.b_data
, strerror(errno
));
3069 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3072 case TYPE_INT_STRING
:
3073 if (Ioctl(fd
, opt
->value
.u_int
, (void *)opt
->value2
.u_string
) < 0) {
3074 Error4("ioctl(%d, 0x%x, %p): %s",
3075 fd
, opt
->value
.u_int
, (void *)opt
->value2
.u_string
, strerror(errno
));
3076 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3080 Error1("ioctl() data type %d not implemented",
3085 } else if (opt
->desc
->func
== OFUNC_SOCKOPT
) {
3088 #if 0 && HAVE_STRUCT_LINGER
3089 } else if (opt
->desc
->optcode
== OPT_SO_LINGER
) {
3090 struct linger lingstru
;
3091 lingstru
.l_onoff
= (opt
->value
.u_int
>=0 ? 1 : 0);
3092 lingstru
.l_linger
= opt
->value
.u_int
;
3093 if (Setsockopt(fd
, opt
->desc
->major
, opt
->desc
->minor
, &lingstru
,
3094 sizeof(lingstru
)) < 0) {
3095 Error6("setsockopt(%d, %d, %d, {%d,%d}, "F_Zu
,
3096 fd
, opt
->desc
->major
, opt
->desc
->minor
, lingstru
.l_onoff
,
3097 lingstru
.l_linger
, sizeof(lingstru
));
3098 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3100 #endif /* HAVE_STRUCT_LINGER */
3102 switch (opt
->desc
->type
) {
3104 if (Setsockopt(fd
, opt
->desc
->major
, opt
->desc
->minor
,
3105 opt
->value
.u_bin
.b_data
, opt
->value
.u_bin
.b_len
)
3107 Error6("setsockopt(%d, %d, %d, %p, "F_Zu
"): %s",
3108 fd
, opt
->desc
->major
, opt
->desc
->minor
,
3109 opt
->value
.u_bin
.b_data
, opt
->value
.u_bin
.b_len
,
3111 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3115 if (Setsockopt(fd
, opt
->desc
->major
, opt
->desc
->minor
,
3116 &opt
->value
.u_bool
, sizeof(opt
->value
.u_bool
))
3118 Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu
"): %s", fd
,
3119 opt
->desc
->major
, opt
->desc
->minor
,
3120 opt
->value
.u_bool
, sizeof(opt
->value
.u_bool
),
3122 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3126 if (Setsockopt(fd
, opt
->desc
->major
, opt
->desc
->minor
,
3127 &opt
->value
.u_byte
, sizeof(uint8_t)) < 0) {
3128 Error6("setsockopt(%d, %d, %d, {%u}, "F_Zu
"): %s",
3129 fd
, opt
->desc
->major
, opt
->desc
->minor
,
3130 opt
->value
.u_byte
, sizeof(uint8_t), strerror(errno
));
3131 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3135 if (Setsockopt(fd
, opt
->desc
->major
, opt
->desc
->minor
,
3136 &opt
->value
.u_int
, sizeof(int)) < 0) {
3137 Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu
"): %s",
3138 fd
, opt
->desc
->major
, opt
->desc
->minor
,
3139 opt
->value
.u_int
, sizeof(int), strerror(errno
));
3140 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3144 if (Setsockopt(fd
, opt
->desc
->major
, opt
->desc
->minor
,
3145 &opt
->value
.u_long
, sizeof(long)) < 0) {
3146 Error6("setsockopt(%d, %d, %d, {%ld}, "F_Zu
"): %s",
3147 fd
, opt
->desc
->major
, opt
->desc
->minor
,
3148 opt
->value
.u_long
, sizeof(long), strerror(errno
));
3149 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3153 if (Setsockopt(fd
, opt
->desc
->major
, opt
->desc
->minor
,
3154 opt
->value
.u_string
,
3155 strlen(opt
->value
.u_string
)+1) < 0) {
3156 Error6("setsockopt(%d, %d, %d, \"%s\", "F_Zu
"): %s",
3157 fd
, opt
->desc
->major
, opt
->desc
->minor
,
3158 opt
->value
.u_string
, strlen(opt
->value
.u_string
)+1,
3160 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3164 if (Setsockopt(fd
, opt
->desc
->major
, opt
->desc
->minor
,
3165 &opt
->value
.u_uint
, sizeof(unsigned int)) < 0) {
3166 Error6("setsockopt(%d, %d, %d, {%u}, "F_Zu
"): %s",
3167 fd
, opt
->desc
->major
, opt
->desc
->minor
,
3168 opt
->value
.u_uint
, sizeof(unsigned int),
3170 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3174 if (Setsockopt(fd
, opt
->desc
->major
, opt
->desc
->minor
,
3175 &opt
->value
.u_timeval
, sizeof(struct timeval
)) < 0) {
3176 Error7("setsockopt(%d, %d, %d, {%ld,%ld}, "F_Zu
"): %s",
3177 fd
, opt
->desc
->major
, opt
->desc
->minor
,
3178 opt
->value
.u_timeval
.tv_sec
, opt
->value
.u_timeval
.tv_usec
,
3179 sizeof(struct timeval
), strerror(errno
));
3180 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3183 #if HAVE_STRUCT_LINGER
3186 struct linger lingstru
;
3187 lingstru
.l_onoff
= (opt
->value
.u_linger
.l_onoff
>=0 ? 1 : 0);
3188 lingstru
.l_linger
= opt
->value
.u_linger
.l_linger
;
3189 if (Setsockopt(fd
, opt
->desc
->major
, opt
->desc
->minor
,
3190 &lingstru
, sizeof(lingstru
)) < 0) {
3191 Error6("setsockopt(%d, %d, %d, {%d,%d}): %s",
3192 fd
, opt
->desc
->major
, opt
->desc
->minor
,
3193 lingstru
.l_onoff
, lingstru
.l_linger
,
3195 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3199 #endif /* HAVE_STRUCT_LINGER */
3200 #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)
3202 /* handled in applyopts_single */
3204 #endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */
3206 /*! still many types missing; implement on demand */
3209 if (Setsockopt(fd
, opt
->desc
->major
, opt
->desc
->minor
,
3210 &opt
->value
.u_ip4addr
, sizeof(opt
->value
.u_ip4addr
)) < 0) {
3211 Error6("setsockopt(%d, %d, %d, {0x%x}, "F_Zu
"): %s",
3212 fd
, opt
->desc
->major
, opt
->desc
->minor
,
3213 *(uint32_t *)&opt
->value
.u_ip4addr
, sizeof(opt
->value
.u_ip4addr
),
3217 #endif /* defined(WITH_IP4) */
3220 Error1("applyopts(): type %d not implemented",
3223 Warn1("applyopts(): type %d not implemented",
3226 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3230 } else if (opt
->desc
->func
== OFUNC_SOCKOPT_APPEND
) {
3231 switch (opt
->desc
->type
) {
3233 socklen_t oldlen
, newlen
;
3235 oldlen
= sizeof(data
);
3236 if (Getsockopt(fd
, opt
->desc
->major
, opt
->desc
->minor
,
3239 Error6("getsockopt(%d, %d, %d, %p, {"F_socklen
"}): %s",
3240 fd
, opt
->desc
->major
, opt
->desc
->minor
, data
, oldlen
,
3242 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3244 memcpy(&data
[oldlen
], opt
->value
.u_bin
.b_data
,
3245 MIN(opt
->value
.u_bin
.b_len
, sizeof(data
)-oldlen
));
3246 newlen
= oldlen
+ MIN(opt
->value
.u_bin
.b_len
, sizeof(data
)-oldlen
);
3247 if (Setsockopt(fd
, opt
->desc
->major
, opt
->desc
->minor
,
3250 Error6("setsockopt(%d, %d, %d, %p, %d): %s",
3251 fd
, opt
->desc
->major
, opt
->desc
->minor
, data
, newlen
,
3253 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3257 Error2("internal: option \"%s\": unimplemented type %d",
3258 opt
->desc
->defname
, opt
->desc
->type
);
3261 } else if (opt
->desc
->func
== OFUNC_SOCKOPT_GENERIC
) {
3262 switch (opt
->desc
->type
) {
3263 case TYPE_INT_INT_INT
:
3264 if (Setsockopt(fd
, opt
->value
.u_int
, opt
->value2
.u_int
,
3265 &opt
->value3
.u_int
, sizeof(int)) < 0) {
3266 Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu
"): %s",
3267 fd
, opt
->value
.u_int
, opt
->value2
.u_int
,
3268 opt
->value3
.u_int
, sizeof(int), strerror(errno
));
3271 case TYPE_INT_INT_BIN
:
3272 if (Setsockopt(fd
, opt
->value
.u_int
, opt
->value2
.u_int
,
3273 opt
->value3
.u_bin
.b_data
, opt
->value3
.u_bin
.b_len
) < 0) {
3274 Error5("setsockopt(%d, %d, %d, {...}, "F_Zu
"): %s",
3275 fd
, opt
->value
.u_int
, opt
->value2
.u_int
,
3276 opt
->value3
.u_bin
.b_len
, strerror(errno
));
3279 case TYPE_INT_INT_STRING
:
3280 if (Setsockopt(fd
, opt
->value
.u_int
, opt
->value2
.u_int
,
3281 opt
->value3
.u_string
,
3282 strlen(opt
->value3
.u_string
)+1) < 0) {
3283 Error6("setsockopt(%d, %d, %d, \"%s\", "F_Zu
"): %s",
3284 fd
, opt
->value
.u_int
, opt
->value2
.u_int
,
3285 opt
->value3
.u_string
, strlen(opt
->value3
.u_string
)+1,
3290 Error1("setsockopt() data type %d not implemented",
3293 #endif /* _WITH_SOCKET */
3296 } else if (opt
->desc
->func
== OFUNC_FLOCK
) {
3297 if (Flock(fd
, opt
->desc
->major
) < 0) {
3298 Error3("flock(%d, %d): %s",
3299 fd
, opt
->desc
->major
, strerror(errno
));
3300 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3302 #endif /* defined(HAVE_FLOCK) */
3304 } else if (opt
->desc
->func
== OFUNC_SPEC
||
3305 opt
->desc
->func
== OFUNC_FLAG
) {
3306 switch (opt
->desc
->optcode
) {
3309 if (Fchown(fd
, opt
->value
.u_uidt
, -1) < 0) {
3310 Error3("fchown(%d, "F_uid
", -1): %s",
3311 fd
, opt
->value
.u_uidt
, strerror(errno
));
3312 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3316 case OPT_GROUP_LATE
:
3317 if (Fchown(fd
, -1, opt
->value
.u_gidt
) < 0) {
3318 Error3("fchown(%d, -1, "F_gid
"): %s",
3319 fd
, opt
->value
.u_gidt
, strerror(errno
));
3320 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3325 if (Fchmod(fd
, opt
->value
.u_modet
) < 0) {
3326 Error3("fchmod(%d, %u): %s",
3327 fd
, opt
->value
.u_modet
, strerror(errno
));
3328 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3331 case OPT_FTRUNCATE32
:
3332 if (Ftruncate(fd
, opt
->value
.u_off
) < 0) {
3333 Error3("ftruncate(%d, "F_off
"): %s",
3334 fd
, opt
->value
.u_off
, strerror(errno
));
3335 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3338 #if HAVE_FTRUNCATE64
3339 case OPT_FTRUNCATE64
:
3340 if (Ftruncate64(fd
, opt
->value
.u_off64
) < 0) {
3341 Error3("ftruncate64(%d, "F_off64
"): %s",
3342 fd
, opt
->value
.u_off64
, strerror(errno
));
3343 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3345 #endif /* HAVE_FTRUNCATE64 */
3347 case OPT_F_SETLK_RD
:
3348 case OPT_F_SETLK_WR
:
3349 case OPT_F_SETLKW_RD
:
3350 case OPT_F_SETLKW_WR
:
3352 struct flock l
; /* Linux: <asm/fcntl.h> */
3353 l
.l_type
= opt
->desc
->minor
;
3354 l
.l_whence
= SEEK_SET
;
3357 l
.l_pid
= 0; /* hope this uses our current process */
3358 if (Fcntl_lock(fd
, opt
->desc
->major
, &l
) < 0) {
3359 Error3("fcntl(%d, %d, {type=F_WRLCK,whence=SEEK_SET,start=0,len=LONG_MAX,pid=0}): %s", fd
, opt
->desc
->major
, strerror(errno
));
3360 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3364 case OPT_SETUID_EARLY
:
3366 if (Setuid(opt
->value
.u_uidt
) < 0) {
3367 Error2("setuid("F_uid
"): %s", opt
->value
.u_uidt
,
3369 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3372 case OPT_SETGID_EARLY
:
3374 if (Setgid(opt
->value
.u_gidt
) < 0) {
3375 Error2("setgid("F_gid
"): %s", opt
->value
.u_gidt
,
3377 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3380 case OPT_SUBSTUSER_EARLY
:
3384 if ((pwd
= getpwuid(opt
->value
.u_uidt
)) == NULL
) {
3385 Error1("getpwuid("F_uid
"): no such user",
3387 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3389 if (Initgroups(pwd
->pw_name
, pwd
->pw_gid
) < 0) {
3390 Error3("initgroups(%s, "F_gid
"): %s",
3391 pwd
->pw_name
, pwd
->pw_gid
, strerror(errno
));
3392 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3394 if (Setgid(pwd
->pw_gid
) < 0) {
3395 Error2("setgid("F_gid
"): %s", pwd
->pw_gid
,
3397 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3399 if (Setuid(opt
->value
.u_uidt
) < 0) {
3400 Error2("setuid("F_uid
"): %s", opt
->value
.u_uidt
,
3402 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3405 if (setenv("USER", pwd
->pw_name
, 1) < 0)
3406 Error1("setenv(\"USER\", \"%s\", 1): insufficient space",
3408 if (setenv("LOGNAME", pwd
->pw_name
, 1) < 0)
3409 Error1("setenv(\"LOGNAME\", \"%s\", 1): insufficient space",
3411 if (setenv("HOME", pwd
->pw_dir
, 1) < 0)
3412 Error1("setenv(\"HOME\", \"%s\", 1): insufficient space",
3414 if (setenv("SHELL", pwd
->pw_shell
, 1) < 0)
3415 Error1("setenv(\"SHELL\", \"%s\", 1): insufficient space",
3420 #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
3421 case OPT_SUBSTUSER_DELAYED
:
3425 if ((pwd
= getpwuid(opt
->value
.u_uidt
)) == NULL
) {
3426 Error1("getpwuid("F_uid
"): no such user",
3428 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3430 delayeduser_uid
= opt
->value
.u_uidt
;
3431 delayeduser_gid
= pwd
->pw_gid
;
3432 if ((delayeduser_name
= strdup(pwd
->pw_name
)) == NULL
) {
3433 Error1("strdup("F_Zu
"): out of memory",
3434 strlen(pwd
->pw_name
)+1);
3435 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3437 if ((delayeduser_dir
= strdup(pwd
->pw_dir
)) == NULL
) {
3438 Error1("strdup("F_Zu
"): out of memory",
3439 strlen(pwd
->pw_dir
)+1);
3440 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3442 if ((delayeduser_shell
= strdup(pwd
->pw_shell
)) == NULL
) {
3443 Error1("strdup("F_Zu
"): out of memory",
3444 strlen(pwd
->pw_shell
)+1);
3445 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3447 /* function to get all supplementary groups of user */
3448 delayeduser_ngids
= sizeof(delayeduser_gids
)/sizeof(gid_t
);
3449 getusergroups(delayeduser_name
, delayeduser_gids
,
3450 &delayeduser_ngids
);
3455 case OPT_CHROOT_EARLY
:
3457 if (Chroot(opt
->value
.u_string
) < 0) {
3458 Error2("chroot(\"%s\"): %s", opt
->value
.u_string
,
3460 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3462 if (Chdir("/") < 0) {
3463 Error1("chdir(\"/\"): %s", strerror(errno
));
3468 Warn1("setsid(): %s", strerror(errno
));
3469 if (Setpgid(getpid(), getppid()) < 0) {
3470 Warn3("setpgid(%d, %d): %s",
3471 getpid(), getppid(), strerror(errno
));
3474 Error1("setsid(): %s", strerror(errno
));
3480 if (Setpgid(0, opt
->value
.u_int
) < 0) {
3481 Warn2("setpgid(0, "F_pid
"): %s",
3482 opt
->value
.u_int
, strerror(errno
));
3488 /* this code idea taken from ssh/pty.c: make pty controlling term. */
3489 if ((mytty
= Open("/dev/tty", O_NOCTTY
, 0640)) < 0) {
3490 Warn1("open(\"/dev/tty\", O_NOCTTY, 0640): %s", strerror(errno
));
3492 /*0 Info1("open(\"/dev/tty\", O_NOCTTY, 0640) -> %d", mytty);*/
3494 if (Ioctl(mytty
, TIOCNOTTY
, NULL
) < 0) {
3495 Warn2("ioctl(%d, TIOCNOTTY, NULL): %s",
3496 mytty
, strerror(errno
));
3499 if (Close(mytty
) < 0) {
3500 Info2("close(%d): %s",
3501 mytty
, strerror(errno
));
3505 if (Ioctl(fd
, TIOCSCTTY
, NULL
) < 0) {
3506 Warn2("ioctl(%d, TIOCSCTTY, NULL): %s", fd
, strerror(errno
));
3509 if (Tcsetpgrp(0, getpid()) < 0) {
3510 Warn2("tcsetpgrp("F_pid
"): %s", getpid(), strerror(errno
));
3515 default: Error1("applyopts(): option \"%s\" not implemented",
3516 opt
->desc
->defname
);
3517 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3521 } else if (opt
->desc
->func
== OFUNC_TERMIOS_FLAG
) {
3524 struct termios termarg
;
3527 if (Tcgetattr(fd
, &tdata
.termarg
) < 0) {
3528 Error3("tcgetattr(%d, %p): %s",
3529 fd
, &tdata
.termarg
, strerror(errno
));
3530 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3532 if (opt
->value
.u_bool
) {
3533 tdata
.flags
[opt
->desc
->major
] |= opt
->desc
->minor
;
3535 tdata
.flags
[opt
->desc
->major
] &= ~opt
->desc
->minor
;
3537 if (Tcsetattr(fd
, TCSADRAIN
, &tdata
.termarg
) < 0) {
3538 Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
3539 fd
, &tdata
.termarg
, strerror(errno
));
3540 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3543 if (xiotermiosflag_applyopt(fd
, opt
) < 0) {
3544 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3548 } else if (opt
->desc
->func
== OFUNC_TERMIOS_VALUE
) {
3550 struct termios termarg
;
3553 if (((opt
->value
.u_uint
<< opt
->desc
->arg3
) & opt
->desc
->minor
) !=
3554 (opt
->value
.u_uint
<< opt
->desc
->arg3
)) {
3555 Error2("option %s: invalid value %u",
3556 opt
->desc
->defname
, opt
->value
.u_uint
);
3557 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3559 if (Tcgetattr(fd
, &tdata
.termarg
) < 0) {
3560 Error3("tcgetattr(%d, %p): %s",
3561 fd
, &tdata
.termarg
, strerror(errno
));
3562 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3565 tdata
.flags
[opt
->desc
->major
] &= ~opt
->desc
->minor
;
3566 tdata
.flags
[opt
->desc
->major
] |=
3567 ((opt
->value
.u_uint
<< opt
->desc
->arg3
) & opt
->desc
->minor
);
3568 if (Tcsetattr(fd
, TCSADRAIN
, &tdata
.termarg
) < 0) {
3569 Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
3570 fd
, &tdata
.termarg
, strerror(errno
));
3571 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3574 } else if (opt
->desc
->func
== OFUNC_TERMIOS_PATTERN
) {
3576 struct termios termarg
;
3579 if (Tcgetattr(fd
, &tdata
.termarg
) < 0) {
3580 Error3("tcgetattr(%d, %p): %s",
3581 fd
, &tdata
.termarg
, strerror(errno
));
3582 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3584 tdata
.flags
[opt
->desc
->major
] &= ~opt
->desc
->arg3
;
3585 tdata
.flags
[opt
->desc
->major
] |= opt
->desc
->minor
;
3586 if (Tcsetattr(fd
, TCSADRAIN
, &tdata
.termarg
) < 0) {
3587 Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
3588 fd
, &tdata
.termarg
, strerror(errno
));
3589 opt
->desc
= ODESC_ERROR
;++opt
; continue;
3592 } else if (opt
->desc
->func
== OFUNC_TERMIOS_CHAR
) {
3593 struct termios termarg
;
3594 if (Tcgetattr(fd
, &termarg
) < 0) {
3595 Error3("tcgetattr(%d, %p): %s",
3596 fd
, &termarg
, strerror(errno
));
3597 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3599 termarg
.c_cc
[opt
->desc
->major
] = opt
->value
.u_byte
;
3600 if (Tcsetattr(fd
, TCSADRAIN
, &termarg
) < 0) {
3601 Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
3602 fd
, &termarg
, strerror(errno
));
3603 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3606 #ifdef HAVE_TERMIOS_ISPEED
3607 } else if (opt
->desc
->func
== OFUNC_TERMIOS_SPEED
) {
3609 struct termios termarg
;
3610 speed_t speeds
[sizeof(struct termios
)/sizeof(speed_t
)];
3612 if (Tcgetattr(fd
, &tdata
.termarg
) < 0) {
3613 Error3("tcgetattr(%d, %p): %s",
3614 fd
, &tdata
.termarg
, strerror(errno
));
3615 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3617 tdata
.speeds
[opt
->desc
->major
] = opt
->value
.u_uint
;
3618 if (Tcsetattr(fd
, TCSADRAIN
, &tdata
.termarg
) < 0) {
3619 Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
3620 fd
, &tdata
.termarg
, strerror(errno
));
3621 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3623 #endif /* HAVE_TERMIOS_ISPEED */
3625 } else if (opt
->desc
->func
== OFUNC_TERMIOS_SPEC
) {
3626 struct termios termarg
;
3627 if (Tcgetattr(fd
, &termarg
) < 0) {
3628 Error3("tcgetattr(%d, %p): %s",
3629 fd
, &termarg
, strerror(errno
));
3630 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3632 switch (opt
->desc
->optcode
) {
3635 ~(IGNBRK
|BRKINT
|IGNPAR
|PARMRK
|INPCK
|ISTRIP
|INLCR
|IGNCR
|ICRNL
|IXON
|IXOFF
3640 termarg
.c_iflag
|= (0);
3641 termarg
.c_oflag
&= ~(OPOST
);
3642 termarg
.c_oflag
|= (0);
3643 termarg
.c_cflag
&= ~(0);
3644 termarg
.c_cflag
|= (0);
3645 termarg
.c_lflag
&= ~(ISIG
|ICANON
3650 termarg
.c_lflag
|= (0);
3651 termarg
.c_cc
[VMIN
] = 1;
3652 termarg
.c_cc
[VTIME
] = 0;
3654 case OPT_TERMIOS_RAWER
:
3655 termarg
.c_iflag
= 0;
3656 termarg
.c_oflag
= 0;
3657 termarg
.c_lflag
= 0;
3658 termarg
.c_cflag
= (CS8
);
3659 termarg
.c_cc
[VMIN
] = 1;
3660 termarg
.c_cc
[VTIME
] = 0;
3663 /* cread -ignbrk brkint -inlcr -igncr icrnl
3664 -ixoff -iuclc -ixany imaxbel opost -olcuc -ocrnl
3665 onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0
3666 vt0 ff0 isig icanon iexten echo echoe echok -echonl
3667 -noflsh -xcase -tostop -echoprt echoctl echoke, and
3668 also sets all special characters to their default
3671 termarg
.c_iflag
&= ~(IGNBRK
|INLCR
|IGNCR
|IXOFF
3676 termarg
.c_iflag
|= (BRKINT
|ICRNL
|IMAXBEL
);
3677 termarg
.c_oflag
&= ~(0 /* for canonical reasons */
3715 termarg
.c_oflag
|= (OPOST
|ONLCR
3735 termarg
.c_cflag
&= ~(0);
3736 termarg
.c_cflag
|= (CREAD
);
3737 termarg
.c_lflag
&= ~(ECHONL
|NOFLSH
3746 termarg
.c_lflag
|= (ISIG
|ICANON
|IEXTEN
|ECHO
|ECHOE
|ECHOK
|ECHOCTL
|ECHOKE
);
3747 /*! "sets characters to their default values... - which? */
3749 case OPT_TERMIOS_CFMAKERAW
:
3751 cfmakeraw(&termarg
);
3753 /* these setting follow the Linux documenation of cfmakeraw */
3755 ~(IGNBRK
|BRKINT
|PARMRK
|ISTRIP
|INLCR
|IGNCR
|ICRNL
|IXON
);
3756 termarg
.c_oflag
&= ~(OPOST
);
3757 termarg
.c_lflag
&= ~(ECHO
|ECHONL
|ICANON
|ISIG
|IEXTEN
);
3758 termarg
.c_cflag
&= ~(CSIZE
|PARENB
);
3759 termarg
.c_cflag
|= (CS8
);
3763 Error("TERMIOS option not handled - internal error?");
3765 if (Tcsetattr(fd
, TCSADRAIN
, &termarg
) < 0) {
3766 Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
3767 fd
, &termarg
, strerror(errno
));
3768 opt
->desc
= ODESC_ERROR
; ++opt
; continue;
3771 #endif /* WITH_TERMIOS */
3774 #define ENABLE_APPLYOPT
3775 #include "xio-streams.c"
3776 #undef ENABLE_APPLYOPT
3777 #endif /* WITH_STREAMS */
3780 /*Error1("applyopts(): function %d not implemented",
3782 if (opt
->desc
->func
!= OFUNC_EXT
&& opt
->desc
->func
!= OFUNC_SIGNAL
) {
3783 Error1("applyopts(): option \"%s\" does not apply",
3784 opt
->desc
->defname
);
3785 opt
->desc
= ODESC_ERROR
;
3792 opt
->desc
= ODESC_DONE
;
3798 /* applies to fd all options belonging to phases */
3799 /* note: not all options can be applied this way (e.g. OFUNC_SPEC with PH_OPEN)
3800 implemented are: OFUNC_FCNTL, OFUNC_SOCKOPT (probably not all types),
3801 OFUNC_TERMIOS_FLAG, OFUNC_TERMIOS_PATTERN, and some OFUNC_SPEC */
3802 int applyopts2(int fd
, struct opt
*opts
, unsigned int from
, unsigned int to
) {
3806 for (i
= from
; i
<= to
; ++i
) {
3807 if ((stat
= applyopts(fd
, opts
, i
)) < 0)
3813 /* apply and consume all options of type FLAG and group.
3814 Return 0 if everything went right, or -1 if an error occurred. */
3815 int applyopts_flags(struct opt
*opts
, int group
, flags_t
*result
) {
3816 struct opt
*opt
= opts
;
3818 if (!opts
) return 0;
3820 while (opt
->desc
!= ODESC_END
) {
3821 if (opt
->desc
!= ODESC_DONE
&&
3822 (opt
->desc
->group
& group
)) {
3823 if (opt
->desc
->func
== OFUNC_FLAG
) {
3824 if (opt
->value
.u_bool
) {
3825 *result
|= opt
->desc
->major
;
3827 *result
&= ~opt
->desc
->major
;
3829 opt
->desc
= ODESC_DONE
;
3830 } else if (opt
->desc
->func
== OFUNC_FLAG_PATTERN
) {
3831 *result
&= ~opt
->desc
->minor
;
3832 *result
|= opt
->desc
->major
;
3833 opt
->desc
= ODESC_DONE
;
3843 /* set the FD_CLOEXEC fcntl if the options do not set it to 0 */
3844 int applyopts_cloexec(int fd
, struct opt
*opts
) {
3847 if (!opts
) return 0;
3849 retropt_bool(opts
, OPT_CLOEXEC
, &docloexec
);
3851 if (Fcntl_l(fd
, F_SETFD
, FD_CLOEXEC
) < 0) {
3852 Warn2("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", fd
, strerror(errno
));
3858 int applyopts_fchown(int fd
, struct opt
*opts
) {
3862 retropt_uidt(opts
, OPT_USER
, &user
);
3863 retropt_gidt(opts
, OPT_GROUP
, &group
);
3865 if (user
!= (uid_t
)-1 || group
!= (gid_t
)-1) {
3866 if (Fchown(fd
, user
, group
) < 0) {
3867 Error4("fchown(%d, "F_uid
", "F_gid
"): %s", fd
, user
, group
,
3869 return STAT_RETRYLATER
;
3875 /* caller must make sure that option is not yet consumed */
3876 static int applyopt_offset(struct single
*xfd
, struct opt
*opt
) {
3879 ptr
= (unsigned char *)xfd
+ opt
->desc
->major
;
3880 switch (opt
->desc
->type
) {
3882 *(bool *)ptr
= opt
->value
.u_bool
; break;
3884 *(int *)ptr
= opt
->value
.u_int
; break;
3886 *(double *)ptr
= opt
->value
.u_double
; break;
3888 *(struct timeval
*)ptr
= opt
->value
.u_timeval
; break;
3889 case TYPE_STRING_NULL
:
3890 if (opt
->value
.u_string
== NULL
) {
3891 *(char **)ptr
= NULL
;
3896 if ((*(char **)ptr
= strdup(opt
->value
.u_string
)) == NULL
) {
3897 Error1("strdup("F_Zu
"): out of memory",
3898 strlen(opt
->value
.u_string
)+1);
3902 *(int *)ptr
= opt
->desc
->minor
;
3905 Error1("applyopt_offset(): type %d not implemented",
3909 opt
->desc
= ODESC_DONE
;
3913 int applyopts_offset(struct single
*xfd
, struct opt
*opts
) {
3916 opt
= opts
; while (opt
->desc
!= ODESC_END
) {
3917 if ((opt
->desc
== ODESC_DONE
) ||
3918 opt
->desc
->func
!= OFUNC_OFFSET
) {
3921 applyopt_offset(xfd
, opt
);
3922 opt
->desc
= ODESC_DONE
;
3928 /* applies to xfd all OFUNC_EXT options belonging to phase
3929 returns -1 if an error occurred */
3930 int applyopts_single(struct single
*xfd
, struct opt
*opts
, enum e_phase phase
) {
3934 if (!opts
) return 0;
3936 opt
= opts
; while (opt
->desc
!= ODESC_END
) {
3937 if ((opt
->desc
== ODESC_DONE
) ||
3938 (opt
->desc
->phase
!= phase
&& phase
!= PH_ALL
)) {
3939 /* option not handled in this function */
3942 switch (opt
->desc
->func
) {
3945 applyopt_offset(xfd
, opt
);
3949 switch (opt
->desc
->optcode
) {
3952 xfd
->ignoreeof
= true;
3955 xfd
->lineterm
= LINETERM_CR
;
3958 xfd
->lineterm
= LINETERM_CRNL
;
3962 xfd
->readbytes
= opt
->value
.u_sizet
;
3963 xfd
->actbytes
= xfd
->readbytes
;
3966 if (xfd
->lock
.lockfile
) {
3967 Error("only one use of options lockfile and waitlock allowed");
3969 xfd
->lock
.lockfile
= strdup(opt
->value
.u_string
);
3970 xfd
->lock
.intervall
.tv_sec
= 1;
3971 xfd
->lock
.intervall
.tv_nsec
= 0;
3973 if ((lockrc
= xiolock(&xfd
->lock
)) < 0) {
3974 /* error message already printed */
3978 Error1("could not obtain lock \"%s\"", xfd
->lock
.lockfile
);
3980 xfd
->havelock
= true;
3984 if (xfd
->lock
.lockfile
) {
3985 Error("only one use of options lockfile and waitlock allowed");
3987 xfd
->lock
.lockfile
= strdup(opt
->value
.u_string
);
3988 xfd
->lock
.waitlock
= true;
3989 xfd
->lock
.intervall
.tv_sec
= 1;
3990 xfd
->lock
.intervall
.tv_nsec
= 0;
3992 /*! this should be integrated into central select()/poll() loop */
3993 if (xiolock(&xfd
->lock
) < 0) {
3996 xfd
->havelock
= true;
4000 /* just store the value in the correct component of struct single */
4001 if (opt
->desc
->type
== TYPE_CONST
) {
4002 /* only for integral types compatible to int */
4003 *(int *)(&((char *)xfd
)[opt
->desc
->major
]) = opt
->desc
->arg3
;
4005 memcpy(&((char *)xfd
)[opt
->desc
->major
], &opt
->value
, opt
->desc
->minor
);
4010 case OFUNC_OFFSET_MASKS
:
4012 void *masks
= (char *)xfd
+ opt
->desc
->major
;
4013 size_t masksize
= opt
->desc
->minor
;
4014 unsigned long bit
= opt
->desc
->arg3
;
4016 case sizeof(uint16_t):
4017 if (opt
->value
.u_bool
) {
4018 ((uint16_t *)masks
)[0] |= bit
;
4020 ((uint16_t *)masks
)[1] |= bit
;
4023 case sizeof(uint32_t):
4024 if (opt
->value
.u_bool
) {
4025 ((uint32_t *)masks
)[0] |= bit
;
4027 ((uint32_t *)masks
)[1] |= bit
;
4031 Info1("sizeof(uint32_t)="F_Zu
, sizeof(uint32_t));
4032 Error1("applyopts_single: masksize "F_Zu
" not implemented",
4040 switch (opt
->desc
->optcode
) {
4041 #if WITH_IP4 && (defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN))
4042 case OPT_IP_ADD_MEMBERSHIP
:
4045 #if HAVE_STRUCT_IP_MREQN
4046 struct ip_mreqn mreqn
;
4048 struct ip_mreq mreq
;
4049 } ip4_mreqn
= {{{0}}};
4050 /* IPv6 not supported - seems to have different handling */
4052 mc:addr:ifname|ifind
4056 union sockaddr_union sockaddr1
;
4057 socklen_t socklen1
= sizeof(sockaddr1
.ip4
);
4058 union sockaddr_union sockaddr2
;
4059 socklen_t socklen2
= sizeof(sockaddr2
.ip4
);
4061 /* first parameter is alway multicast address */
4063 xiogetaddrinfo(opt
->value
.u_ip_mreq
.multiaddr
, NULL
,
4064 xfd
->para
.socket
.la
.soa
.sa_family
,
4065 SOCK_DGRAM
, IPPROTO_IP
,
4066 &sockaddr1
, &socklen1
, 0, 0);
4067 ip4_mreqn
.mreq
.imr_multiaddr
= sockaddr1
.ip4
.sin_addr
;
4069 ; /* for canonical reasons */
4070 #if HAVE_STRUCT_IP_MREQN
4071 } else if (opt
->value
.u_ip_mreq
.ifindex
[0] != '\0') {
4072 /* three parameters */
4073 /* second parameter is interface address */
4074 xiogetaddrinfo(opt
->value
.u_ip_mreq
.param2
, NULL
,
4075 xfd
->para
.socket
.la
.soa
.sa_family
,
4076 SOCK_DGRAM
, IPPROTO_IP
,
4077 &sockaddr2
, &socklen2
, 0, 0);
4078 ip4_mreqn
.mreq
.imr_interface
= sockaddr2
.ip4
.sin_addr
;
4079 /* third parameter is interface */
4080 if (ifindex(opt
->value
.u_ip_mreq
.ifindex
,
4081 (unsigned int *)&ip4_mreqn
.mreqn
.imr_ifindex
, -1)
4083 Error1("cannot resolve interface \"%s\"",
4084 opt
->value
.u_ip_mreq
.ifindex
);
4086 #endif /* HAVE_STRUCT_IP_MREQN */
4088 /* two parameters */
4090 ; /* for canonical reasons */
4091 #if HAVE_STRUCT_IP_MREQN
4092 /* there is a form with two parameters that uses mreqn */
4093 } else if (ifindex(opt
->value
.u_ip_mreq
.param2
,
4094 (unsigned int *)&ip4_mreqn
.mreqn
.imr_ifindex
,
4097 /* yes, second param converts to interface */
4098 ip4_mreqn
.mreq
.imr_interface
.s_addr
= htonl(0);
4099 #endif /* HAVE_STRUCT_IP_MREQN */
4102 xiogetaddrinfo(opt
->value
.u_ip_mreq
.param2
, NULL
,
4103 xfd
->para
.socket
.la
.soa
.sa_family
,
4104 SOCK_DGRAM
, IPPROTO_IP
,
4105 &sockaddr2
, &socklen2
, 0, 0);
4106 ip4_mreqn
.mreq
.imr_interface
= sockaddr2
.ip4
.sin_addr
;
4112 ; /* for canonical reasons */
4113 } else if (xfd
->para
.socket
.la
.soa
.sa_family
== PF_INET
) {
4114 } else if (xfd
->para
.socket
.la
.soa
.sa_family
== PF_INET6
) {
4115 ip6_mreqn
.mreq
.imr_multiaddr
= sockaddr1
.ip6
.sin6_addr
;
4116 ip6_mreqn
.mreq
.imr_interface
= sockaddr2
.ip6
.sin6_addr
;
4120 #if HAVE_STRUCT_IP_MREQN
4121 if (Setsockopt(xfd
->fd
, opt
->desc
->major
, opt
->desc
->minor
,
4122 &ip4_mreqn
.mreqn
, sizeof(ip4_mreqn
.mreqn
)) < 0) {
4123 Error8("setsockopt(%d, %d, %d, {0x%08x,0x%08x,%d}, "F_Zu
"): %s",
4124 xfd
->fd
, opt
->desc
->major
, opt
->desc
->minor
,
4125 ip4_mreqn
.mreqn
.imr_multiaddr
.s_addr
,
4126 ip4_mreqn
.mreqn
.imr_address
.s_addr
,
4127 ip4_mreqn
.mreqn
.imr_ifindex
,
4128 sizeof(ip4_mreqn
.mreqn
),
4130 opt
->desc
= ODESC_ERROR
; continue;
4133 if (Setsockopt(xfd
->fd
, opt
->desc
->major
, opt
->desc
->minor
,
4134 &ip4_mreqn
.mreq
, sizeof(ip4_mreqn
.mreq
)) < 0) {
4135 Error7("setsockopt(%d, %d, %d, {0x%08x,0x%08x}, "F_Zu
"): %s",
4136 xfd
->fd
, opt
->desc
->major
, opt
->desc
->minor
,
4137 ip4_mreqn
.mreq
.imr_multiaddr
,
4138 ip4_mreqn
.mreq
.imr_interface
,
4139 sizeof(ip4_mreqn
.mreq
),
4141 opt
->desc
= ODESC_ERROR
; continue;
4147 #endif /* WITH_IP4 && (defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)) */
4151 #if WITH_IP6 && defined(HAVE_STRUCT_IPV6_MREQ)
4152 case OPT_IPV6_JOIN_GROUP
:
4154 struct ipv6_mreq ip6_mreq
= {{{{0}}}};
4155 union sockaddr_union sockaddr1
;
4156 socklen_t socklen1
= sizeof(sockaddr1
.ip6
);
4158 /* always two parameters */
4159 /* first parameter is multicast address */
4161 xiogetaddrinfo(opt
->value
.u_ip_mreq
.multiaddr
, NULL
,
4162 xfd
->para
.socket
.la
.soa
.sa_family
,
4163 SOCK_DGRAM
, IPPROTO_IP
,
4164 &sockaddr1
, &socklen1
, 0, 0);
4165 ip6_mreq
.ipv6mr_multiaddr
= sockaddr1
.ip6
.sin6_addr
;
4166 if (ifindex(opt
->value
.u_ip_mreq
.param2
,
4167 &ip6_mreq
.ipv6mr_interface
, -1)
4169 Error1("interface \"%s\" not found",
4170 opt
->value
.u_ip_mreq
.param2
);
4171 ip6_mreq
.ipv6mr_interface
= htonl(0);
4174 if (Setsockopt(xfd
->fd
, opt
->desc
->major
, opt
->desc
->minor
,
4175 &ip6_mreq
, sizeof(ip6_mreq
)) < 0) {
4176 Error6("setsockopt(%d, %d, %d, {...,0x%08x}, "F_Zu
"): %s",
4177 xfd
->fd
, opt
->desc
->major
, opt
->desc
->minor
,
4178 ip6_mreq
.ipv6mr_interface
,
4181 opt
->desc
= ODESC_ERROR
; continue;
4185 #endif /* WITH_IP6 && defined(HAVE_STRUCT_IPV6_MREQ) */
4191 #endif /* _WITH_SOCKET */
4197 opt
->desc
= ODESC_DONE
;
4205 /* xfd->para.exec.pid must be set */
4206 int applyopts_signal(struct single
*xfd
, struct opt
*opts
) {
4209 if (!opts
) return 0;
4211 opt
= opts
; while (opt
->desc
!= ODESC_END
) {
4212 if (opt
->desc
== ODESC_DONE
|| opt
->desc
->func
!= OFUNC_SIGNAL
) {
4216 if (xio_opt_signal(xfd
->para
.exec
.pid
, opt
->desc
->major
) < 0) {
4217 opt
->desc
= ODESC_ERROR
; continue;
4219 opt
->desc
= ODESC_DONE
;
4225 /* apply remaining options to file descriptor, and tell us if something is
4227 int _xio_openlate(struct single
*fd
, struct opt
*opts
) {
4231 _xioopen_setdelayeduser();
4233 if ((result
= applyopts(fd
->fd
, opts
, PH_LATE
)) < 0) {
4236 if ((result
= applyopts_single(fd
, opts
, PH_LATE
)) < 0) {
4239 if ((result
= applyopts(fd
->fd
, opts
, PH_LATE2
)) < 0) {
4243 if ((numleft
= leftopts(opts
)) > 0) {
4245 Error1("%d option(s) could not be used", numleft
);
4251 int dropopts(struct opt
*opts
, unsigned int phase
) {
4254 if (phase
== PH_ALL
) {
4255 opts
[0].desc
= ODESC_END
;
4258 opt
= opts
; while (opt
&& opt
->desc
!= ODESC_END
) {
4259 if (opt
->desc
!= ODESC_DONE
&& opt
->desc
->phase
== phase
) {
4260 Debug1("ignoring option \"%s\"", opt
->desc
->defname
);
4261 opt
->desc
= ODESC_DONE
;
4268 int dropopts2(struct opt
*opts
, unsigned int from
, unsigned int to
) {
4271 for (i
= from
; i
<= to
; ++i
) {