Version 1.8.0.0
[socat.git] / xioopts.c
blob4b651aa8fe9b93fd1d7fc1668b4357c3f7ad9b5b
1 /* source: xioopts.c */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
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"
8 #include "xioopen.h"
9 #include "xio-unix.h"
10 #include "xio-ip.h"
12 #include "xiomodes.h"
13 #include "xiolockfile.h"
14 #include "nestlex.h"
15 #include "xiohelp.h"
17 bool xioopts_ignoregroups;
19 #define IF_ANY(a,b) {a,b},
21 #if WITH_NAMED
22 # define IF_NAMED(a,b) {a,b},
23 #else
24 # define IF_NAMED(a,b)
25 #endif
27 #if WITH_PIPE || WITH_GOPEN
28 # define IF_OPEN(a,b) {a,b},
29 #else
30 # define IF_OPEN(a,b)
31 #endif
33 #if WITH_TERMIOS
34 # define IF_TERMIOS(a,b) {a,b},
35 #else
36 # define IF_TERMIOS(a,b)
37 #endif
39 #if WITH_EXEC
40 # define IF_EXEC(a,b) {a,b},
41 #else
42 # define IF_EXEC(a,b)
43 #endif
45 #if _WITH_SOCKET
46 # define IF_SOCKET(a,b) {a,b},
47 #else
48 # define IF_SOCKET(a,b)
49 #endif
51 #if WITH_LISTEN
52 # define IF_LISTEN(a,b) {a,b},
53 #else
54 # define IF_LISTEN(a,b)
55 #endif
57 #if (WITH_UDP || WITH_TCP) && WITH_LISTEN
58 # define IF_RANGE(a,b) {a,b},
59 #else
60 # define IF_RANGE(a,b)
61 #endif
63 #if WITH_IP4 || WITH_IP6
64 # define IF_IP(a,b) {a,b},
65 #else
66 # define IF_IP(a,b)
67 #endif
69 #if WITH_IP6
70 # define IF_IP6(a,b) {a,b},
71 #else
72 # define IF_IP6(a,b)
73 #endif
75 #if WITH_TCP|WITH_UDP
76 # define IF_IPAPP(a,b) {a,b},
77 #else
78 # define IF_IPAPP(a,b)
79 #endif
81 #if WITH_TCP
82 # define IF_TCP(a,b) {a,b},
83 #else
84 # define IF_TCP(a,b)
85 #endif
87 #if WITH_UDP
88 # define IF_UDP(a,b) {a,b},
89 #else
90 # define IF_UDP(a,b)
91 #endif
93 #if WITH_SCTP
94 # define IF_SCTP(a,b) {a,b},
95 #else
96 # define IF_SCTP(a,b)
97 #endif
99 #if WITH_DCCP
100 # define IF_DCCP(a,b) {a,b},
101 #else
102 # define IF_DCCP(a,b)
103 #endif
105 #if WITH_UDPLITE
106 # define IF_UDPLITE(a,b) {a,b},
107 #else
108 # define IF_UDPLITE(a,b)
109 #endif
111 #if WITH_SOCKS4
112 # define IF_SOCKS4(a,b) {a,b},
113 #else
114 # define IF_SOCKS4(a,b)
115 #endif
117 #if WITH_PROXY
118 # define IF_PROXY(a,b) {a,b},
119 #else
120 # define IF_PROXY(a,b)
121 #endif
123 #if WITH_READLINE
124 # define IF_READLINE(a,b) {a,b},
125 #else
126 # define IF_READLINE(a,b)
127 #endif
129 #if WITH_PTY
130 # define IF_PTY(a,b) {a,b},
131 #else
132 # define IF_PTY(a,b)
133 #endif
135 #if WITH_OPENSSL
136 # define IF_OPENSSL(a,b) {a,b},
137 #else
138 # define IF_OPENSSL(a,b)
139 #endif
141 #if WITH_RESOLVE
142 # define IF_RESOLVE(a,b) {a,b},
143 #else
144 # define IF_RESOLVE(a,b)
145 #endif
147 #if WITH_INTERFACE
148 # define IF_INTERFACE(a,b) {a,b},
149 #else
150 # define IF_INTERFACE(a,b)
151 #endif
153 #if WITH_TUN
154 # define IF_TUN(a,b) {a,b},
155 #else
156 # define IF_TUN(a,b)
157 #endif
159 #if WITH_UNIX
160 # define IF_UNIX(a,b) {a,b},
161 #else
162 # define IF_UNIX(a,b)
163 #endif
165 #if WITH_RETRY
166 # define IF_RETRY(a,b) {a,b},
167 #else
168 # define IF_RETRY(a,b)
169 #endif
172 static int applyopt_offset(struct single *sfd, struct opt *opt);
173 static int applyopt(struct single *sfd, int fd, struct opt *opt);
176 /* address options - keep this array strictly alphabetically sorted for
177 binary search! */
178 /* NULL terminated */
179 const struct optname optionnames[] = {
180 #if HAVE_RESOLV_H && WITH_RES_AAONLY
181 IF_RESOLVE("aaonly", &opt_res_aaonly)
182 #endif
183 #ifdef TCP_ABORT_THRESHOLD /* HP_UX */
184 IF_TCP ("abort-threshold", &opt_tcp_abort_threshold)
185 #endif
186 IF_LISTEN ("accept-timeout", &opt_accept_timeout)
187 #ifdef SO_ACCEPTCONN /* AIX433 */
188 IF_SOCKET ("acceptconn", &opt_so_acceptconn)
189 #endif /* SO_ACCEPTCONN */
190 #ifdef IP_ADD_MEMBERSHIP
191 IF_IP ("add-membership", &opt_ip_add_membership)
192 #endif
193 #if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP)
194 IF_IP ("add-source-membership", &opt_ip_add_source_membership)
195 #endif
196 #if defined(AI_ADDRCONFIG)
197 IF_IP ("addrconfig", &opt_ai_addrconfig)
198 #endif
199 #if defined(AI_ADDRCONFIG)
200 IF_IP ("ai-addrconfig", &opt_ai_addrconfig)
201 #endif
202 #if defined(AI_PASSIVE )
203 IF_IP ("ai-passive", &opt_ai_passive)
204 #endif
205 #if defined(AI_V4MAPPED)
206 IF_IP ("ai-v4mapped", &opt_ai_v4mapped)
207 #endif
208 IF_INTERFACE("allmulti", &opt_iff_allmulti)
209 #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE)
210 IF_IPAPP ("allow-table", &opt_tcpwrap_hosts_allow_table)
211 #endif
212 IF_ANY ("append", &opt_append)
213 #ifdef O_ASYNC
214 IF_ANY ("async", &opt_async)
215 #endif
216 #ifdef SO_ATTACH_FILTER
217 IF_SOCKET ("attach-filter", &opt_so_attach_filter)
218 IF_SOCKET ("attachfilter", &opt_so_attach_filter)
219 #endif
220 #ifdef SO_AUDIT /* AIX 4.3.3 */
221 IF_SOCKET ("audit", &opt_so_audit)
222 #endif /* SO_AUDIT */
223 #ifdef IPV6_AUTHHDR
224 IF_IP6 ("authhdr", &opt_ipv6_authhdr)
225 #endif
226 #ifdef IFF_AUTOMEDIA
227 IF_INTERFACE("automedia", &opt_iff_automedia)
228 #endif
229 #ifdef CBAUD
230 IF_TERMIOS("b0", &opt_b0)
231 #ifdef B1000000
232 IF_TERMIOS("b1000000", &opt_b1000000)
233 #endif
234 IF_TERMIOS("b110", &opt_b110)
235 #ifdef B115200
236 IF_TERMIOS("b115200", &opt_b115200)
237 #endif
238 #ifdef B1152000
239 IF_TERMIOS("b1152000", &opt_b1152000)
240 #endif
241 IF_TERMIOS("b1200", &opt_b1200)
242 IF_TERMIOS("b134", &opt_b134)
243 IF_TERMIOS("b150", &opt_b150)
244 #ifdef B1500000
245 IF_TERMIOS("b1500000", &opt_b1500000)
246 #endif
247 IF_TERMIOS("b1800", &opt_b1800)
248 IF_TERMIOS("b19200", &opt_b19200)
249 IF_TERMIOS("b200", &opt_b200)
250 #ifdef B2000000
251 IF_TERMIOS("b2000000", &opt_b2000000)
252 #endif
253 #ifdef B230400
254 IF_TERMIOS("b230400", &opt_b230400)
255 #endif
256 IF_TERMIOS("b2400", &opt_b2400)
257 #ifdef B2500000
258 IF_TERMIOS("b2500000", &opt_b2500000)
259 #endif
260 IF_TERMIOS("b300", &opt_b300)
261 #ifdef B3000000
262 IF_TERMIOS("b3000000", &opt_b3000000)
263 #endif
264 #ifdef B3500000
265 IF_TERMIOS("b3500000", &opt_b3500000)
266 #endif
267 #ifdef B3600 /* HP-UX */
268 IF_TERMIOS("b3600", &opt_b3600)
269 #endif
270 IF_TERMIOS("b38400", &opt_b38400)
271 #ifdef B4000000
272 IF_TERMIOS("b4000000", &opt_b4000000)
273 #endif
274 #ifdef B460800
275 IF_TERMIOS("b460800", &opt_b460800)
276 #endif
277 IF_TERMIOS("b4800", &opt_b4800)
278 IF_TERMIOS("b50", &opt_b50)
279 #ifdef B500000
280 IF_TERMIOS("b500000", &opt_b500000)
281 #endif
282 #ifdef B57600
283 IF_TERMIOS("b57600", &opt_b57600)
284 #endif
285 #ifdef B576000
286 IF_TERMIOS("b576000", &opt_b576000)
287 #endif
288 IF_TERMIOS("b600", &opt_b600)
289 #ifdef B7200 /* HP-UX */
290 IF_TERMIOS("b7200", &opt_b7200)
291 #endif
292 IF_TERMIOS("b75", &opt_b75)
293 #ifdef B900 /* HP-UX */
294 IF_TERMIOS("b900", &opt_b900)
295 #endif
296 #ifdef B921600
297 IF_TERMIOS("b921600", &opt_b921600)
298 #endif
299 IF_TERMIOS("b9600", &opt_b9600)
300 #endif /* defined(CBAUD) */
301 IF_LISTEN ("backlog", &opt_backlog)
302 #ifdef O_BINARY
303 IF_OPEN ("bin", &opt_o_binary)
304 IF_OPEN ("binary", &opt_o_binary)
305 #endif
306 IF_SOCKET ("bind", &opt_bind)
307 IF_UNIX ("bind-tempname", &xioopt_unix_bind_tempname)
308 #ifdef SO_BINDTODEVICE
309 IF_SOCKET ("bindtodevice", &opt_so_bindtodevice)
310 #endif
311 IF_TERMIOS("brkint", &opt_brkint)
312 IF_SOCKET ("broadcast", &opt_so_broadcast)
313 #ifdef BSDLY
314 # ifdef BS0
315 IF_TERMIOS("bs0", &opt_bs0)
316 # endif
317 # ifdef BS1
318 IF_TERMIOS("bs1", &opt_bs1)
319 # endif
320 #endif
321 #ifdef SO_BSDCOMPAT
322 IF_SOCKET ("bsdcompat", &opt_so_bsdcompat)
323 #endif
324 #ifdef BSDLY
325 IF_TERMIOS("bsdly", &opt_bsdly)
326 #endif
327 IF_ANY ("bytes", &opt_readbytes)
328 IF_OPENSSL("cafile", &opt_openssl_cafile)
329 IF_OPENSSL("capath", &opt_openssl_capath)
330 #if defined(SOL_DCCP) && defined(DCCP_SOCKOPT_QPOLICY_ID)
331 IF_DCCP ("ccid", &xioopt_dccp_set_ccid)
332 #endif
333 IF_ANY ("cd", &opt_chdir)
334 IF_OPENSSL("cert", &opt_openssl_certificate)
335 IF_OPENSSL("certificate", &opt_openssl_certificate)
336 IF_TERMIOS("cfmakeraw", &opt_termios_cfmakeraw)
337 IF_ANY ("chdir", &opt_chdir)
338 #if WITH_LISTEN
339 IF_ANY ("children-shutup", &opt_children_shutup)
340 #endif
341 IF_ANY ("chroot", &opt_chroot)
342 IF_ANY ("chroot-early", &opt_chroot_early)
343 /*IF_TERMIOS("cibaud", &opt_cibaud)*/
344 IF_OPENSSL("cipher", &opt_openssl_cipherlist)
345 IF_OPENSSL("cipherlist", &opt_openssl_cipherlist)
346 IF_OPENSSL("ciphers", &opt_openssl_cipherlist)
347 #ifdef SO_CKSUMRECV
348 IF_SOCKET ("cksumrecv", &opt_so_cksumrecv)
349 #endif /* SO_CKSUMRECV */
350 /*IF_NAMED ("cleanup", &opt_cleanup)*/
351 IF_TERMIOS("clocal", &opt_clocal)
352 IF_ANY ("cloexec", &opt_cloexec)
353 IF_ANY ("close", &opt_end_close)
354 IF_OPENSSL("cn", &opt_openssl_commonname)
355 IF_OPENSSL("commonname", &opt_openssl_commonname)
356 #if WITH_FS && defined(FS_COMPR_FL)
357 IF_ANY ("compr", &opt_fs_compr)
358 #endif
359 #if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_COMP)
360 IF_OPENSSL("compress", &opt_openssl_compress)
361 #endif
362 #ifdef TCP_CONN_ABORT_THRESHOLD /* HP_UX */
363 IF_TCP ("conn-abort-threshold", &opt_tcp_conn_abort_threshold)
364 #endif
365 IF_SOCKET ("connect-timeout", &opt_connect_timeout)
366 IF_LISTEN ("cool-write", &opt_cool_write)
367 IF_LISTEN ("coolwrite", &opt_cool_write)
368 #ifdef TCP_CORK
369 IF_TCP ("cork", &opt_tcp_cork)
370 #endif
371 IF_ANY ("cr", &opt_cr)
372 #ifdef CRDLY
373 # ifdef CR0
374 IF_TERMIOS("cr0", &opt_cr0)
375 # endif
376 # ifdef CR1
377 IF_TERMIOS("cr1", &opt_cr1)
378 # endif
379 # ifdef CR2
380 IF_TERMIOS("cr2", &opt_cr2)
381 # endif
382 # ifdef CR3
383 IF_TERMIOS("cr3", &opt_cr3)
384 # endif
385 # if CRDLY_SHIFT >= 0
386 IF_TERMIOS("crdly", &opt_crdly)
387 # endif
388 #endif /* defined(CRDLY) */
389 IF_TERMIOS("cread", &opt_cread)
390 IF_OPEN ("creat", &opt_o_create)
391 IF_OPEN ("create", &opt_o_create)
392 IF_ANY ("crlf", &opt_crnl)
393 IF_ANY ("crnl", &opt_crnl)
394 IF_TERMIOS("crterase", &opt_echoe)
395 IF_TERMIOS("crtkill", &opt_echoke)
396 #ifdef CRTSCTS
397 IF_TERMIOS("crtscts", &opt_crtscts)
398 #endif
399 IF_TERMIOS("cs5", &opt_cs5)
400 IF_TERMIOS("cs6", &opt_cs6)
401 IF_TERMIOS("cs7", &opt_cs7)
402 IF_TERMIOS("cs8", &opt_cs8)
403 #if CSIZE_SHIFT >= 0
404 IF_TERMIOS("csize", &opt_csize)
405 #endif
406 IF_TERMIOS("cstopb", &opt_cstopb)
407 IF_TERMIOS("ctlecho", &opt_echoctl)
408 IF_TERMIOS("ctty", &opt_tiocsctty)
409 IF_EXEC ("dash", &opt_dash)
410 #if defined(SOL_DCCP) && defined(DCCP_SOCKOPT_QPOLICY_ID)
411 IF_DCCP ("dccp-set-ccid", &xioopt_dccp_set_ccid)
412 #endif
413 IF_SOCKET ("debug", &opt_so_debug)
414 /*IF_RESOLVE("debug", &opt_res_debug)*/
415 #ifdef O_DEFER
416 IF_OPEN ("defer", &opt_o_defer)
417 #endif
418 #ifdef TCP_DEFER_ACCEPT /* Linux 2.4.0 */
419 IF_TCP ("defer-accept", &opt_tcp_defer_accept)
420 #endif
421 #if HAVE_RESOLV_H
422 IF_RESOLVE("defnames", &opt_res_defnames)
423 #endif /* HAVE_RESOLV_H */
424 #ifdef O_DELAY
425 IF_OPEN ("delay", &opt_o_delay)
426 #endif
427 IF_NAMED ("delete", &opt_unlink)
428 #if WITH_LIBWRAP && defined(HAVE_HOSTS_DENY_TABLE)
429 IF_IPAPP ("deny-table", &opt_tcpwrap_hosts_deny_table)
430 #endif
431 #ifdef SO_DETACH_FILTER
432 IF_SOCKET ("detach-filter", &opt_so_detach_filter)
433 IF_SOCKET ("detachfilter", &opt_so_detach_filter)
434 #endif
435 #ifdef SO_DGRAM_ERRIND
436 IF_SOCKET ("dgram-errind", &opt_so_dgram_errind)
437 IF_SOCKET ("dgramerrind", &opt_so_dgram_errind)
438 #endif
439 IF_OPENSSL("dh", &opt_openssl_dhparam)
440 IF_OPENSSL("dhparam", &opt_openssl_dhparam)
441 IF_OPENSSL("dhparams", &opt_openssl_dhparam)
442 #ifdef O_DIRECT
443 IF_OPEN ("direct", &opt_o_direct)
444 #endif
445 #ifdef O_DIRECTORY
446 IF_OPEN ("directory", &opt_o_directory)
447 #endif
448 #if WITH_FS && defined(FS_DIRSYNC_FL)
449 IF_ANY ("dirsync", &opt_fs_dirsync)
450 #endif
451 #ifdef VDISCARD
452 IF_TERMIOS("discard", &opt_vdiscard)
453 #endif
454 #if WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST
455 IF_IP ("dns", &opt_res_nsaddr)
456 #endif
457 #if HAVE_RESOLV_H
458 IF_RESOLVE("dnsrch", &opt_res_dnsrch)
459 #endif /* HAVE_RESOLV_H */
460 #ifdef SO_DONTLINGER
461 IF_SOCKET ("dontlinger", &opt_so_dontlinger)
462 #endif
463 IF_SOCKET ("dontroute", &opt_so_dontroute)
464 #ifdef IPV6_DSTOPTS
465 IF_IP6 ("dstopts", &opt_ipv6_dstopts)
466 #endif
467 #ifdef VDSUSP /* HP-UX */
468 IF_TERMIOS("dsusp", &opt_vdsusp)
469 #endif
470 #ifdef O_DSYNC
471 IF_OPEN ("dsync", &opt_o_dsync)
472 #endif
473 IF_TERMIOS("echo", &opt_echo)
474 IF_TERMIOS("echoctl", &opt_echoctl)
475 IF_TERMIOS("echoe", &opt_echoe)
476 IF_TERMIOS("echok", &opt_echok)
477 IF_TERMIOS("echoke", &opt_echoke)
478 IF_TERMIOS("echonl", &opt_echonl)
479 #ifdef ECHOPRT
480 IF_TERMIOS("echoprt", &opt_echoprt)
481 #endif
482 IF_OPENSSL("egd", &opt_openssl_egd)
483 IF_ANY ("end-close", &opt_end_close)
484 IF_TERMIOS("eof", &opt_veof)
485 IF_TERMIOS("eol", &opt_veol)
486 IF_TERMIOS("eol2", &opt_veol2)
487 IF_TERMIOS("erase", &opt_verase)
488 IF_SOCKET ("error", &opt_so_error)
489 IF_ANY ("escape", &opt_escape)
490 IF_OPEN ("excl", &opt_o_excl)
491 #if WITH_FS && defined(FS_APPEND_FL)
492 IF_ANY ("ext2-append", &opt_fs_append)
493 #endif
494 #if WITH_FS && defined(FS_COMPR_FL)
495 IF_ANY ("ext2-compr", &opt_fs_compr)
496 #endif
497 #if WITH_FS && defined(FS_DIRSYNC_FL)
498 IF_ANY ("ext2-dirsync", &opt_fs_dirsync)
499 #endif
500 #if WITH_FS && defined(FS_IMMUTABLE_FL)
501 IF_ANY ("ext2-immutable", &opt_fs_immutable)
502 #endif
503 #if WITH_FS && defined(FS_JOURNAL_DATA_FL)
504 IF_ANY ("ext2-journal-data", &opt_fs_journal_data)
505 #endif
506 #if WITH_FS && defined(FS_NOATIME_FL)
507 IF_ANY ("ext2-noatime", &opt_fs_noatime)
508 #endif
509 #if WITH_FS && defined(FS_NODUMP_FL)
510 IF_ANY ("ext2-nodump", &opt_fs_nodump)
511 #endif
512 #if WITH_FS && defined(FS_NOTAIL_FL)
513 IF_ANY ("ext2-notail", &opt_fs_notail)
514 #endif
515 #if WITH_FS && defined(FS_SECRM_FL)
516 IF_ANY ("ext2-secrm", &opt_fs_secrm)
517 #endif
518 #if WITH_FS && defined(FS_SYNC_FL)
519 IF_ANY ("ext2-sync", &opt_fs_sync)
520 #endif
521 #if WITH_FS && defined(FS_TOPDIR_FL)
522 IF_ANY ("ext2-topdir", &opt_fs_topdir)
523 #endif
524 #if WITH_FS && defined(FS_UNRM_FL)
525 IF_ANY ("ext2-unrm", &opt_fs_unrm)
526 #endif
527 #if WITH_FS && defined(FS_APPEND_FL)
528 IF_ANY ("ext3-append", &opt_fs_append)
529 #endif
530 #if WITH_FS && defined(FS_COMPR_FL)
531 IF_ANY ("ext3-compr", &opt_fs_compr)
532 #endif
533 #if WITH_FS && defined(FS_DIRSYNC_FL)
534 IF_ANY ("ext3-dirsync", &opt_fs_dirsync)
535 #endif
536 #if WITH_FS && defined(FS_IMMUTABLE_FL)
537 IF_ANY ("ext3-immutable", &opt_fs_immutable)
538 #endif
539 #if WITH_FS && defined(FS_JOURNAL_DATA_FL)
540 IF_ANY ("ext3-journal-data", &opt_fs_journal_data)
541 #endif
542 #if WITH_FS && defined(FS_NOATIME_FL)
543 IF_ANY ("ext3-noatime", &opt_fs_noatime)
544 #endif
545 #if WITH_FS && defined(FS_NODUMP_FL)
546 IF_ANY ("ext3-nodump", &opt_fs_nodump)
547 #endif
548 #if WITH_FS && defined(FS_NOTAIL_FL)
549 IF_ANY ("ext3-notail", &opt_fs_notail)
550 #endif
551 #if WITH_FS && defined(FS_SECRM_FL)
552 IF_ANY ("ext3-secrm", &opt_fs_secrm)
553 #endif
554 #if WITH_FS && defined(FS_SYNC_FL)
555 IF_ANY ("ext3-sync", &opt_fs_sync)
556 #endif
557 #if WITH_FS && defined(FS_TOPDIR_FL)
558 IF_ANY ("ext3-topdir", &opt_fs_topdir)
559 #endif
560 #if WITH_FS && defined(FS_UNRM_FL)
561 IF_ANY ("ext3-unrm", &opt_fs_unrm)
562 #endif
563 IF_ANY ("f-setlk", &opt_f_setlk_wr)
564 IF_ANY ("f-setlk-rd", &opt_f_setlk_rd)
565 IF_ANY ("f-setlk-wr", &opt_f_setlk_wr)
566 IF_ANY ("f-setlkw", &opt_f_setlkw_wr)
567 IF_ANY ("f-setlkw-rd", &opt_f_setlkw_rd)
568 IF_ANY ("f-setlkw-wr", &opt_f_setlkw_wr)
569 #if WITH_PIPE && defined(F_SETPIPE_SZ)
570 IF_ANY ("f-setpipe-sz", &opt_f_setpipe_sz)
571 #endif
572 IF_EXEC ("fdin", &opt_fdin)
573 IF_EXEC ("fdout", &opt_fdout)
574 #ifdef FFDLY
575 # ifdef FF0
576 IF_TERMIOS("ff0", &opt_ff0)
577 # endif
578 # ifdef FF1
579 IF_TERMIOS("ff1", &opt_ff1)
580 # endif
581 IF_TERMIOS("ffdly", &opt_ffdly)
582 #endif
583 #ifdef FIOSETOWN
584 IF_SOCKET ("fiosetown", &opt_fiosetown)
585 #endif
586 #if WITH_FIPS
587 IF_OPENSSL("fips", &opt_openssl_fips)
588 #endif
589 #if HAVE_FLOCK
590 IF_ANY ("flock", &opt_flock_ex)
591 IF_ANY ("flock-ex", &opt_flock_ex)
592 IF_ANY ("flock-ex-nb", &opt_flock_ex_nb)
593 IF_ANY ("flock-nb", &opt_flock_ex_nb)
594 IF_ANY ("flock-sh", &opt_flock_sh)
595 IF_ANY ("flock-sh-nb", &opt_flock_sh_nb)
596 #endif
597 #ifdef IPV4_FLOWINFO
598 IF_IP6 ("flowinfo", &opt_ipv6_flowinfo)
599 #endif
600 IF_TERMIOS("flusho", &opt_flusho)
601 IF_RETRY ("forever", &opt_forever)
602 IF_LISTEN ("fork", &opt_fork)
603 #ifdef IP_FREEBIND
604 IF_IP ("freebind", &opt_ip_freebind)
605 #endif
606 #if WITH_FS && defined(FS_APPEND_FL)
607 IF_ANY ("fs-append", &opt_fs_append)
608 #endif
609 #if WITH_FS && defined(FS_COMPR_FL)
610 IF_ANY ("fs-compr", &opt_fs_compr)
611 #endif
612 #if WITH_FS && defined(FS_DIRSYNC_FL)
613 IF_ANY ("fs-dirsync", &opt_fs_dirsync)
614 #endif
615 #if WITH_FS && defined(FS_IMMUTABLE_FL)
616 IF_ANY ("fs-immutable", &opt_fs_immutable)
617 #endif
618 #if WITH_FS && defined(FS_JOURNAL_DATA_FL)
619 IF_ANY ("fs-journal-data", &opt_fs_journal_data)
620 #endif
621 #if WITH_FS && defined(FS_NOATIME_FL)
622 IF_ANY ("fs-noatime", &opt_fs_noatime)
623 #endif
624 #if WITH_FS && defined(FS_NODUMP_FL)
625 IF_ANY ("fs-nodump", &opt_fs_nodump)
626 #endif
627 #if WITH_FS && defined(FS_NOTAIL_FL)
628 IF_ANY ("fs-notail", &opt_fs_notail)
629 #endif
630 #if WITH_FS && defined(FS_SECRM_FL)
631 IF_ANY ("fs-secrm", &opt_fs_secrm)
632 #endif
633 #if WITH_FS && defined(FS_SYNC_FL)
634 IF_ANY ("fs-sync", &opt_fs_sync)
635 #endif
636 #if WITH_FS && defined(FS_TOPDIR_FL)
637 IF_ANY ("fs-topdir", &opt_fs_topdir)
638 #endif
639 #if WITH_FS && defined(FS_UNRM_FL)
640 IF_ANY ("fs-unrm", &opt_fs_unrm)
641 #endif
642 #if HAVE_FTRUNCATE64
643 IF_ANY ("ftruncate", &opt_ftruncate64)
644 #else
645 IF_ANY ("ftruncate", &opt_ftruncate32)
646 #endif
647 IF_ANY ("ftruncate32", &opt_ftruncate32)
648 #if HAVE_FTRUNCATE64
649 IF_ANY ("ftruncate64", &opt_ftruncate64)
650 #endif
651 IF_ANY ("gid", &opt_group)
652 IF_NAMED ("gid-e", &opt_group_early)
653 IF_ANY ("gid-l", &opt_group_late)
654 IF_ANY ("group", &opt_group)
655 IF_NAMED ("group-early", &opt_group_early)
656 IF_ANY ("group-late", &opt_group_late)
657 #ifdef IP_HDRINCL
658 IF_IP ("hdrincl", &opt_ip_hdrincl)
659 #endif
660 IF_READLINE("history", &opt_history_file)
661 IF_READLINE("history-file", &opt_history_file)
662 #ifdef IPV6_HOPLIMIT
663 IF_IP6 ("hoplimit", &opt_ipv6_hoplimit)
664 #endif
665 #ifdef IPV6_HOPOPTS
666 IF_IP6 ("hopopts", &opt_ipv6_hopopts)
667 #endif
668 #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE)
669 IF_IPAPP ("hosts-allow", &opt_tcpwrap_hosts_allow_table)
670 #endif
671 #if WITH_LIBWRAP && defined(HAVE_HOSTS_DENY_TABLE)
672 IF_IPAPP ("hosts-deny", &opt_tcpwrap_hosts_deny_table)
673 #endif
674 IF_PROXY ("http-version", &opt_http_version)
675 IF_TERMIOS("hup", &opt_hupcl)
676 IF_TERMIOS("hupcl", &opt_hupcl)
677 #ifdef I_POP
678 IF_ANY ("i-pop-all", &opt_streams_i_pop_all)
679 #endif
680 #ifdef I_PUSH
681 IF_ANY ("i-push", &opt_streams_i_push)
682 #endif
683 IF_TERMIOS("icanon", &opt_icanon)
684 IF_TERMIOS("icrnl", &opt_icrnl)
685 IF_TERMIOS("iexten", &opt_iexten)
686 #ifdef SO_BINDTODEVICE
687 IF_SOCKET ("if", &opt_so_bindtodevice)
688 #endif
689 IF_INTERFACE("iff-allmulti", &opt_iff_allmulti)
690 #ifdef IFF_AUTOMEDIA
691 IF_INTERFACE("iff-automedia", &opt_iff_automedia)
692 #endif
693 IF_INTERFACE("iff-broadcast", &opt_iff_broadcast)
694 IF_INTERFACE("iff-debug", &opt_iff_debug)
695 /*IF_INTERFACE("iff-dynamic", &opt_iff_dynamic)*/
696 IF_INTERFACE("iff-loopback", &opt_iff_loopback)
697 #ifdef IFF_MASTER
698 IF_INTERFACE("iff-master", &opt_iff_master)
699 #endif
700 IF_INTERFACE("iff-multicast", &opt_iff_multicast)
701 IF_TUN ("iff-no-pi", &opt_iff_no_pi)
702 IF_INTERFACE("iff-noarp", &opt_iff_noarp)
703 IF_INTERFACE("iff-notrailers", &opt_iff_notrailers)
704 IF_INTERFACE("iff-pointopoint", &opt_iff_pointopoint)
705 #ifdef IFF_PORTSEL
706 IF_INTERFACE("iff-portsel", &opt_iff_portsel)
707 #endif
708 IF_INTERFACE("iff-promisc", &opt_iff_promisc)
709 IF_INTERFACE("iff-running", &opt_iff_running)
710 #ifdef IFF_SLAVE
711 IF_INTERFACE("iff-slave", &opt_iff_slave)
712 #endif
713 IF_INTERFACE("iff-up", &opt_iff_up)
714 IF_TERMIOS("ignbrk", &opt_ignbrk)
715 IF_TERMIOS("igncr", &opt_igncr)
716 /* you might need to terminate socat manually if you use this option: */
717 IF_PROXY ("ignorecr", &opt_ignorecr)
718 IF_ANY ("ignoreeof", &opt_ignoreeof)
719 IF_ANY ("ignoreof", &opt_ignoreeof)
720 IF_TERMIOS("ignpar", &opt_ignpar)
721 #if HAVE_RESOLV_H
722 IF_RESOLVE("igntc", &opt_res_igntc)
723 #endif /* HAVE_RESOLV_H */
724 IF_TERMIOS("imaxbel", &opt_imaxbel)
725 #if WITH_FS && defined(FS_IMMUTABLE_FL)
726 IF_ANY ("immutable", &opt_fs_immutable)
727 #endif
728 #ifdef TCP_INFO /* Linux 2.4.0 */
729 IF_TCP ("info", &opt_tcp_info)
730 #endif
731 IF_TERMIOS("inlcr", &opt_inlcr)
732 IF_TERMIOS("inpck", &opt_inpck)
733 #ifdef SO_BINDTODEVICE
734 IF_SOCKET ("interface", &opt_so_bindtodevice)
735 #endif
736 IF_RETRY ("interval", &opt_intervall)
737 IF_RETRY ("intervall", &opt_intervall)
738 IF_TERMIOS("intr", &opt_vintr)
739 IF_ANY ("ioctl", &opt_ioctl_void)
740 IF_ANY ("ioctl-bin", &opt_ioctl_bin)
741 IF_ANY ("ioctl-int", &opt_ioctl_int)
742 IF_ANY ("ioctl-intp", &opt_ioctl_intp)
743 IF_ANY ("ioctl-string", &opt_ioctl_string)
744 IF_ANY ("ioctl-void", &opt_ioctl_void)
745 #ifdef IP_ADD_MEMBERSHIP
746 IF_IP ("ip-add-membership", &opt_ip_add_membership)
747 #endif
748 #if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP)
749 IF_IP ("ip-add-source-membership", &opt_ip_add_source_membership)
750 #endif
751 #ifdef IP_FREEBIND
752 IF_IP ("ip-freebind", &opt_ip_freebind)
753 #endif
754 #ifdef IP_HDRINCL
755 IF_IP ("ip-hdrincl", &opt_ip_hdrincl)
756 #endif
757 #ifdef IP_ADD_MEMBERSHIP
758 IF_IP ("ip-membership", &opt_ip_add_membership)
759 #endif
760 #ifdef IP_MTU
761 IF_IP ("ip-mtu", &opt_ip_mtu)
762 #endif
763 #ifdef IP_MTU_DISCOVER
764 IF_IP ("ip-mtu-discover", &opt_ip_mtu_discover)
765 #endif
766 IF_IP ("ip-multicast-if", &opt_ip_multicast_if)
767 IF_IP ("ip-multicast-loop", &opt_ip_multicast_loop)
768 IF_IP ("ip-multicast-ttl", &opt_ip_multicast_ttl)
769 #ifdef IP_OPTIONS
770 IF_IP ("ip-options", &opt_ip_options)
771 #endif
772 #ifdef IP_PKTINFO
773 IF_IP ("ip-pktinfo", &opt_ip_pktinfo)
774 #endif
775 #ifdef IP_PKTOPTIONS
776 IF_IP ("ip-pktoptions", &opt_ip_pktoptions)
777 #endif
778 #ifdef IP_RECVDSTADDR
779 IF_IP ("ip-recvdstaddr", &opt_ip_recvdstaddr)
780 #endif
781 #ifdef IP_RECVERR
782 IF_IP ("ip-recverr", &opt_ip_recverr)
783 #endif
784 #ifdef IP_RECVIF
785 IF_IP ("ip-recvif", &opt_ip_recvif)
786 #endif
787 #ifdef IP_RECVOPTS
788 IF_IP ("ip-recvopts", &opt_ip_recvopts)
789 #endif
790 #ifdef IP_RECVTOS
791 IF_IP ("ip-recvtos", &opt_ip_recvtos)
792 #endif
793 #ifdef IP_RECVTTL
794 IF_IP ("ip-recvttl", &opt_ip_recvttl)
795 #endif
796 #ifdef IP_RETOPTS
797 IF_IP ("ip-retopts", &opt_ip_retopts)
798 #endif
799 #ifdef IP_ROUTER_ALERT
800 IF_IP ("ip-router-alert", &opt_ip_router_alert)
801 #endif
802 IF_IP ("ip-tos", &opt_ip_tos)
803 #ifdef IP_TRANSPARENT
804 IF_IP ("ip-transparent", &opt_ip_transparent)
805 #endif
806 IF_IP ("ip-ttl", &opt_ip_ttl)
807 #ifdef IP_FREEBIND
808 IF_IP ("ipfreebind", &opt_ip_freebind)
809 #endif
810 #ifdef IP_HDRINCL
811 IF_IP ("iphdrincl", &opt_ip_hdrincl)
812 #endif
813 #ifdef IP_MTU
814 IF_IP ("ipmtu", &opt_ip_mtu)
815 #endif
816 #ifdef IP_MTU_DISCOVER
817 IF_IP ("ipmtudiscover", &opt_ip_mtu_discover)
818 #endif
819 IF_IP ("ipmulticastloop", &opt_ip_multicast_loop)
820 IF_IP ("ipmulticastttl", &opt_ip_multicast_ttl)
821 #ifdef IP_OPTIONS
822 IF_IP ("ipoptions", &opt_ip_options)
823 #endif
824 #ifdef IP_PKTINFO
825 IF_IP ("ippktinfo", &opt_ip_pktinfo)
826 #endif
827 #ifdef IP_PKTOPTIONS
828 IF_IP ("ippktoptions", &opt_ip_pktoptions)
829 #endif
830 #ifdef IP_RECVDSTADDR
831 IF_IP ("iprecvdstaddr", &opt_ip_recvdstaddr)
832 #endif
833 #ifdef IP_RECVERR
834 IF_IP ("iprecverr", &opt_ip_recverr)
835 #endif
836 #ifdef IP_RECVOPTS
837 IF_IP ("iprecvopts", &opt_ip_recvopts)
838 #endif
839 #ifdef IP_RECVTOS
840 IF_IP ("iprecvtos", &opt_ip_recvtos)
841 #endif
842 #ifdef IP_RECVTTL
843 IF_IP ("iprecvttl", &opt_ip_recvttl)
844 #endif
845 #ifdef IP_RETOPTS
846 IF_IP ("ipretopts", &opt_ip_retopts)
847 #endif
848 #ifdef IP_ROUTER_ALERT
849 IF_IP ("iprouteralert", &opt_ip_router_alert)
850 #endif
851 IF_IP ("iptos", &opt_ip_tos)
852 IF_IP ("ipttl", &opt_ip_ttl)
853 #ifdef IPV6_JOIN_GROUP
854 IF_IP6 ("ipv6-add-membership", &opt_ipv6_join_group)
855 #endif
856 #ifdef MCAST_JOIN_SOURCE_GROUP
857 IF_IP6 ("ipv6-add-source-membership", &opt_ipv6_join_source_group)
858 #endif
859 #ifdef IPV6_AUTHHDR
860 IF_IP6 ("ipv6-authhdr", &opt_ipv6_authhdr)
861 #endif
862 #ifdef IPV6_DSTOPTS
863 IF_IP6 ("ipv6-dstopts", &opt_ipv6_dstopts)
864 #endif
865 #ifdef IPV4_FLOWINFO
866 IF_IP6 ("ipv6-flowinfo", &opt_ipv6_flowinfo)
867 #endif
868 #ifdef IPV6_HOPLIMIT
869 IF_IP6 ("ipv6-hoplimit", &opt_ipv6_hoplimit)
870 #endif
871 #ifdef IPV6_HOPOPTS
872 IF_IP6 ("ipv6-hopopts", &opt_ipv6_hopopts)
873 #endif
874 #ifdef IPV6_JOIN_GROUP
875 IF_IP6 ("ipv6-join-group", &opt_ipv6_join_group)
876 #endif
877 #ifdef MCAST_JOIN_SOURCE_GROUP
878 IF_IP6 ("ipv6-join-source-group", &opt_ipv6_join_source_group)
879 #endif
880 #ifdef IPV6_PKTINFO
881 IF_IP6 ("ipv6-pktinfo", &opt_ipv6_pktinfo)
882 #endif
883 #ifdef IPV6_RECVDSTOPTS
884 IF_IP6 ("ipv6-recvdstopts", &opt_ipv6_recvdstopts)
885 #endif
886 #ifdef IPV6_RECVERR
887 IF_IP6 ("ipv6-recverr", &opt_ipv6_recverr)
888 #endif
889 #ifdef IPV6_RECVHOPLIMIT
890 IF_IP6 ("ipv6-recvhoplimit", &opt_ipv6_recvhoplimit)
891 #endif
892 #ifdef IPV6_RECVHOPOPTS
893 IF_IP6 ("ipv6-recvhopopts", &opt_ipv6_recvhopopts)
894 #endif
895 #ifdef IPV6_PATHMTU
896 IF_IP6 ("ipv6-recvpathmtu", &opt_ipv6_recvpathmtu)
897 #endif
898 #ifdef IPV6_RECVPKTINFO
899 IF_IP6 ("ipv6-recvpktinfo", &opt_ipv6_recvpktinfo)
900 #endif
901 #ifdef IPV6_RECVRTHDR
902 IF_IP6 ("ipv6-recvrthdr", &opt_ipv6_recvrthdr)
903 #endif
904 #ifdef IPV6_RECVTCLASS
905 IF_IP6 ("ipv6-recvtclass", &opt_ipv6_recvtclass)
906 #endif
907 #ifdef IPV6_RTHDR
908 IF_IP6 ("ipv6-rthdr", &opt_ipv6_rthdr)
909 #endif
910 #ifdef IPV6_TCLASS
911 IF_IP6 ("ipv6-tclass", &opt_ipv6_tclass)
912 #endif
913 IF_IP6 ("ipv6-unicast-hops", &opt_ipv6_unicast_hops)
914 #ifdef IPV6_V6ONLY
915 IF_IP6 ("ipv6-v6only", &opt_ipv6_v6only)
916 IF_IP6 ("ipv6only", &opt_ipv6_v6only)
917 #endif
918 IF_TERMIOS("isig", &opt_isig)
919 #if HAVE_TERMIOS_ISPEED
920 IF_TERMIOS("ispeed", &opt_ispeed)
921 #endif
922 IF_TERMIOS("istrip", &opt_istrip)
923 #ifdef IUCLC
924 IF_TERMIOS("iuclc", &opt_iuclc)
925 #endif
926 IF_TERMIOS("ixany", &opt_ixany)
927 IF_TERMIOS("ixoff", &opt_ixoff)
928 IF_TERMIOS("ixon", &opt_ixon)
929 #ifdef IPV6_JOIN_GROUP
930 IF_IP6 ("join-group", &opt_ipv6_join_group)
931 #endif
932 #ifdef MCAST_JOIN_SOURCE_GROUP
933 IF_IP6 ("join-source-group", &opt_ipv6_join_source_group)
934 #endif
935 #if WITH_FS && defined(FS_JOURNAL_DATA_FL)
936 IF_ANY ("journal", &opt_fs_journal_data)
937 IF_ANY ("journal-data", &opt_fs_journal_data)
938 #endif
939 IF_SOCKET ("keepalive", &opt_so_keepalive)
940 #ifdef TCP_KEEPCNT /* Linux 2.4.0 */
941 IF_TCP ("keepcnt", &opt_tcp_keepcnt)
942 #endif
943 #ifdef TCP_KEEPIDLE /* Linux 2.4.0 */
944 IF_TCP ("keepidle", &opt_tcp_keepidle)
945 #endif
946 #ifdef TCP_KEEPINIT /* OSF1 */
947 IF_TCP ("keepinit", &opt_tcp_keepinit)
948 #endif
949 #ifdef TCP_KEEPINTVL /* Linux 2.4.0 */
950 IF_TCP ("keepintvl", &opt_tcp_keepintvl)
951 #endif
952 #ifdef SO_KERNACCEPT /* AIX 4.3.3 */
953 IF_SOCKET ("kernaccept", &opt_so_kernaccept)
954 #endif /* SO_KERNACCEPT */
955 IF_OPENSSL("key", &opt_openssl_key)
956 IF_TERMIOS("kill", &opt_vkill)
957 #ifdef O_LARGEFILE
958 IF_OPEN ("largefile", &opt_o_largefile)
959 #endif
960 #if WITH_LIBWRAP
961 IF_IPAPP ("libwrap", &opt_tcpwrappers)
962 #endif
963 IF_SOCKET ("linger", &opt_so_linger)
964 #ifdef TCP_LINGER2 /* Linux 2.4.0 */
965 IF_TCP ("linger2", &opt_tcp_linger2)
966 #endif
967 IF_PTY ("link", &opt_symbolic_link)
968 IF_LISTEN ("listen-timeout", &opt_accept_timeout)
969 IF_TERMIOS("lnext", &opt_vlnext)
970 #if defined(F_SETLKW)
971 IF_ANY ("lock", &opt_f_setlkw_wr) /* POSIX, first choice */
972 #elif defined(HAVE_FLOCK)
973 IF_ANY ("lock", &opt_flock_ex) /* BSD, fallback */
974 #endif
975 IF_ANY ("lockfile", &opt_lockfile)
976 #if defined(F_SETLKW)
977 IF_ANY ("lockw", &opt_f_setlkw_wr) /* POSIX, first choice */
978 #elif defined(HAVE_FLOCK)
979 IF_ANY ("lockw", &opt_flock_ex_nb) /* BSD, fallback */
980 #endif
981 IF_EXEC ("login", &opt_dash)
982 IF_INTERFACE("loopback", &opt_iff_loopback)
983 IF_IPAPP ("lowport", &opt_lowport)
984 #if HAVE_LSEEK64
985 IF_ANY ("lseek", &opt_lseek64_set)
986 #else
987 IF_ANY ("lseek", &opt_lseek32_set)
988 #endif
989 IF_ANY ("lseek32", &opt_lseek32_set)
990 IF_ANY ("lseek32-cur", &opt_lseek32_cur)
991 IF_ANY ("lseek32-end", &opt_lseek32_end)
992 IF_ANY ("lseek32-set", &opt_lseek32_set)
993 #if HAVE_LSEEK64
994 IF_ANY ("lseek64", &opt_lseek64_set)
995 IF_ANY ("lseek64-cur", &opt_lseek64_cur)
996 IF_ANY ("lseek64-end", &opt_lseek64_end)
997 IF_ANY ("lseek64-set", &opt_lseek64_set)
998 #endif
999 #ifdef IFF_MASTER
1000 IF_INTERFACE("master", &opt_iff_master)
1001 #endif
1002 IF_LISTEN ("max-children", &opt_max_children)
1003 #if HAVE_SSL_set_max_proto_version || defined(SSL_set_max_proto_version)
1004 IF_OPENSSL("max-version", &opt_openssl_max_proto_version)
1005 #endif
1006 IF_LISTEN ("maxchildren", &opt_max_children)
1007 #if HAVE_SSL_CTX_set_tlsext_max_fragment_length || defined(SSL_CTX_set_tlsext_max_fragment_length)
1008 IF_OPENSSL("maxfraglen", &opt_openssl_maxfraglen)
1009 #endif
1010 #ifdef TCP_MAXSEG
1011 IF_TCP ("maxseg", &opt_tcp_maxseg)
1012 IF_TCP ("maxseg-late", &opt_tcp_maxseg_late)
1013 #endif
1014 #if HAVE_SSL_CTX_set_max_send_fragment || defined(SSL_CTX_set_max_send_fragment)
1015 IF_OPENSSL("maxsendfrag", &opt_openssl_maxsendfrag)
1016 #endif
1017 #ifdef TCP_MD5SUM
1018 IF_TCP ("md5sig", &opt_tcp_md5sig)
1019 #endif
1020 #ifdef IP_ADD_MEMBERSHIP
1021 IF_IP ("membership", &opt_ip_add_membership)
1022 #endif
1023 #if WITH_OPENSSL_METHOD
1024 IF_OPENSSL("method", &opt_openssl_method)
1025 #endif
1026 IF_TERMIOS("min", &opt_vmin)
1027 #if HAVE_SSL_set_min_proto_version || defined(SSL_set_min_proto_version)
1028 IF_OPENSSL("min-version", &opt_openssl_min_proto_version)
1029 #endif
1030 IF_ANY ("mode", &opt_perm)
1031 #if WITH_POSIXMQ
1032 IF_ANY ("mq-prio", &opt_posixmq_priority)
1033 #endif
1034 #ifdef TCP_MAXSEG
1035 IF_TCP ("mss", &opt_tcp_maxseg)
1036 IF_TCP ("mss-late", &opt_tcp_maxseg_late)
1037 #endif
1038 #ifdef IP_MTU
1039 IF_IP ("mtu", &opt_ip_mtu)
1040 #endif
1041 #ifdef IP_MTU_DISCOVER
1042 IF_IP ("mtudiscover", &opt_ip_mtu_discover)
1043 #endif
1044 IF_INTERFACE("multicast", &opt_iff_multicast)
1045 IF_IP ("multicast-if", &opt_ip_multicast_if)
1046 IF_IP ("multicast-loop", &opt_ip_multicast_loop)
1047 IF_IP ("multicast-ttl", &opt_ip_multicast_ttl)
1048 IF_IP ("multicastloop", &opt_ip_multicast_loop)
1049 IF_IP ("multicastttl", &opt_ip_multicast_ttl)
1050 #if WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST
1051 IF_IP ("nameserver", &opt_res_nsaddr)
1052 #endif
1053 #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK)
1054 IF_ANY ("ndelay", &opt_o_ndelay)
1055 #else
1056 IF_ANY ("ndelay", &opt_nonblock)
1057 #endif
1058 #if WITH_NAMESPACES
1059 IF_ANY ("netns", &opt_set_netns)
1060 #endif
1061 IF_NAMED ("new", &opt_unlink_early)
1062 #ifdef NLDLY
1063 # ifdef NL0
1064 IF_TERMIOS("nl0", &opt_nl0)
1065 # endif
1066 # ifdef NL1
1067 IF_TERMIOS("nl1", &opt_nl1)
1068 # endif
1069 IF_TERMIOS("nldly", &opt_nldly)
1070 #endif /* defined(NLDLY) */
1071 #ifdef SO_NO_CHECK
1072 IF_SOCKET ("no-check", &opt_so_no_check)
1073 #endif
1074 IF_TUN ("no-pi", &opt_iff_no_pi)
1075 #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
1076 IF_OPENSSL("no-sni", &opt_openssl_no_sni)
1077 #endif
1078 IF_INTERFACE("noarp", &opt_iff_noarp)
1079 #ifdef O_NOATIME
1080 IF_OPEN ("noatime", &opt_o_noatime)
1081 #endif
1082 #ifdef SO_NO_CHECK
1083 IF_SOCKET ("nocheck", &opt_so_no_check)
1084 #endif
1085 IF_OPEN ("noctty", &opt_o_noctty)
1086 #ifdef TCP_NODELAY
1087 IF_TCP ("nodelay", &opt_tcp_nodelay)
1088 #endif
1089 #if WITH_FS && defined(FS_NODUMP_FL)
1090 IF_ANY ("nodump", &opt_fs_nodump)
1091 #endif
1092 #if HAVE_REGEX_H
1093 IF_READLINE("noecho", &opt_noecho)
1094 #endif /* HAVE_REGEX_H */
1095 IF_TERMIOS("noflsh", &opt_noflsh)
1096 #ifdef O_NOFOLLOW
1097 IF_OPEN ("nofollow", &opt_o_nofollow)
1098 #endif
1099 IF_EXEC ("nofork", &opt_nofork)
1100 #ifdef O_NOINHERIT
1101 IF_ANY ("noinherit", &opt_o_noinherit)
1102 #endif
1103 IF_ANY ("nonblock", &opt_nonblock)
1104 #ifdef TCP_NOOPT
1105 IF_TCP ("noopt", &opt_tcp_noopt)
1106 #endif
1107 IF_READLINE("noprompt", &opt_noprompt)
1108 #ifdef TCP_NOPUSH
1109 IF_TCP ("nopush", &opt_tcp_nopush)
1110 #endif
1111 #ifdef SO_NOREUSEADDR /* AIX 4.3.3 */
1112 IF_SOCKET ("noreuseaddr", &opt_so_noreuseaddr)
1113 #endif /* SO_NOREUSEADDR */
1114 #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
1115 IF_OPENSSL("nosni", &opt_openssl_no_sni)
1116 #endif
1117 IF_INTERFACE("notrailers", &opt_iff_notrailers)
1118 #if WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST
1119 IF_IP ("nsaddr", &opt_res_nsaddr)
1120 #endif
1121 #ifdef O_NSHARE
1122 IF_OPEN ("nshare", &opt_o_nshare)
1123 #endif
1124 IF_SOCKET ("null-eof", &opt_null_eof)
1125 IF_ANY ("o-append", &opt_append)
1126 #ifdef O_ASYNC
1127 IF_ANY ("o-async", &opt_async)
1128 #endif
1129 #ifdef O_BINARY
1130 IF_OPEN ("o-binary", &opt_o_binary)
1131 #endif
1132 IF_OPEN ("o-creat", &opt_o_create)
1133 IF_OPEN ("o-create", &opt_o_create)
1134 #ifdef O_DEFER
1135 IF_OPEN ("o-defer", &opt_o_defer)
1136 #endif
1137 #ifdef O_DELAY
1138 IF_OPEN ("o-delay", &opt_o_delay)
1139 #endif
1140 #ifdef O_DIRECT
1141 IF_OPEN ("o-direct", &opt_o_direct)
1142 #endif
1143 #ifdef O_DIRECTORY
1144 IF_OPEN ("o-directory", &opt_o_directory)
1145 #endif
1146 #ifdef O_DSYNC
1147 IF_OPEN ("o-dsync", &opt_o_dsync)
1148 #endif
1149 IF_OPEN ("o-excl", &opt_o_excl)
1150 #ifdef O_LARGEFILE
1151 IF_OPEN ("o-largefile", &opt_o_largefile)
1152 #endif
1153 #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK)
1154 IF_ANY ("o-ndelay", &opt_o_ndelay)
1155 #else
1156 IF_ANY ("o-ndelay", &opt_nonblock)
1157 #endif
1158 #ifdef O_NOATIME
1159 IF_OPEN ("o-noatime", &opt_o_noatime)
1160 #endif
1161 IF_OPEN ("o-noctty", &opt_o_noctty)
1162 #ifdef O_NOFOLLOW
1163 IF_OPEN ("o-nofollow", &opt_o_nofollow)
1164 #endif
1165 #ifdef O_NOINHERIT
1166 IF_ANY ("o-noinherit", &opt_o_noinherit)
1167 #endif
1168 IF_ANY ("o-nonblock", &opt_nonblock)
1169 #ifdef O_NSHARE
1170 IF_OPEN ("o-nshare", &opt_o_nshare)
1171 #endif
1172 #ifdef O_PRIV
1173 IF_OPEN ("o-priv", &opt_o_priv)
1174 #endif
1175 IF_OPEN ("o-rdonly", &opt_o_rdonly)
1176 IF_OPEN ("o-rdwr", &opt_o_rdwr)
1177 #ifdef O_RSHARE
1178 IF_OPEN ("o-rshare", &opt_o_rshare)
1179 #endif
1180 #ifdef O_RSYNC
1181 IF_OPEN ("o-rsync", &opt_o_rsync)
1182 #endif
1183 #ifdef O_SYNC
1184 IF_OPEN ("o-sync", &opt_o_sync)
1185 #endif
1186 #ifdef O_TEXT
1187 IF_ANY ("o-text", &opt_o_text)
1188 #endif
1189 IF_OPEN ("o-trunc", &opt_o_trunc)
1190 IF_OPEN ("o-wronly", &opt_o_wronly)
1191 IF_OPEN ("o_create", &opt_o_create)
1192 #ifdef O_DEFER
1193 IF_OPEN ("o_defer", &opt_o_defer)
1194 #endif
1195 #ifdef O_DELAY
1196 IF_OPEN ("o_delay", &opt_o_delay)
1197 #endif
1198 #ifdef O_DIRECT
1199 IF_OPEN ("o_direct", &opt_o_direct)
1200 #endif
1201 #ifdef O_DIRECTORY
1202 IF_OPEN ("o_directory", &opt_o_directory)
1203 #endif
1204 #ifdef O_DSYNC
1205 IF_OPEN ("o_dsync", &opt_o_dsync)
1206 #endif
1207 IF_OPEN ("o_excl", &opt_o_excl)
1208 #ifdef O_LARGEFILE
1209 IF_OPEN ("o_largefile", &opt_o_largefile)
1210 #endif
1211 #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK)
1212 IF_ANY ("o_ndelay", &opt_o_ndelay)
1213 #else
1214 IF_ANY ("o_ndelay", &opt_nonblock)
1215 #endif
1216 IF_OPEN ("o_noctty", &opt_o_noctty)
1217 #ifdef O_NOFOLLOW
1218 IF_OPEN ("o_nofollow", &opt_o_nofollow)
1219 #endif
1220 #ifdef O_NSHARE
1221 IF_OPEN ("o_nshare", &opt_o_nshare)
1222 #endif
1223 #ifdef O_PRIV
1224 IF_OPEN ("o_priv", &opt_o_priv)
1225 #endif
1226 IF_OPEN ("o_rdonly", &opt_o_rdonly)
1227 IF_OPEN ("o_rdwr", &opt_o_rdwr)
1228 #ifdef O_RSHARE
1229 IF_OPEN ("o_rshare", &opt_o_rshare)
1230 #endif
1231 #ifdef O_RSYNC
1232 IF_OPEN ("o_rsync", &opt_o_rsync)
1233 #endif
1234 #ifdef O_SYNC
1235 IF_OPEN ("o_sync", &opt_o_sync)
1236 #endif
1237 IF_OPEN ("o_wronly", &opt_o_wronly)
1238 #ifdef OCRNL
1239 IF_TERMIOS("ocrnl", &opt_ocrnl)
1240 #endif
1241 #ifdef OFDEL
1242 IF_TERMIOS("ofdel", &opt_ofdel)
1243 #endif
1244 #ifdef OFILL
1245 IF_TERMIOS("ofill", &opt_ofill)
1246 #endif
1247 #ifdef OLCUC
1248 IF_TERMIOS("olcuc", &opt_olcuc)
1249 #endif
1250 IF_TERMIOS("onlcr", &opt_onlcr)
1251 #ifdef ONLRET
1252 IF_TERMIOS("onlret", &opt_onlret)
1253 #endif
1254 #ifdef ONOCR
1255 IF_TERMIOS("onocr", &opt_onocr)
1256 #endif
1257 IF_SOCKET ("oobinline", &opt_so_oobinline)
1258 #if HAVE_OPENPTY
1259 IF_EXEC ("openpty", &opt_openpty)
1260 #endif /* HAVE_OPENPTY */
1261 IF_OPENSSL("openssl-cafile", &opt_openssl_cafile)
1262 IF_OPENSSL("openssl-capath", &opt_openssl_capath)
1263 IF_OPENSSL("openssl-certificate", &opt_openssl_certificate)
1264 IF_OPENSSL("openssl-cipherlist", &opt_openssl_cipherlist)
1265 IF_OPENSSL("openssl-commonname", &opt_openssl_commonname)
1266 #if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_COMP)
1267 IF_OPENSSL("openssl-compress", &opt_openssl_compress)
1268 #endif
1269 IF_OPENSSL("openssl-dhparam", &opt_openssl_dhparam)
1270 IF_OPENSSL("openssl-dhparams", &opt_openssl_dhparam)
1271 IF_OPENSSL("openssl-egd", &opt_openssl_egd)
1272 #if WITH_FIPS
1273 IF_OPENSSL("openssl-fips", &opt_openssl_fips)
1274 #endif
1275 IF_OPENSSL("openssl-key", &opt_openssl_key)
1276 #if HAVE_SSL_set_max_proto_version || defined(SSL_set_max_proto_version)
1277 IF_OPENSSL("openssl-max-proto-version", &opt_openssl_max_proto_version)
1278 #endif
1279 #if HAVE_SSL_CTX_set_tlsext_max_fragment_length || defined(SSL_CTX_set_tlsext_max_fragment_length)
1280 IF_OPENSSL("openssl-maxfraglen", &opt_openssl_maxfraglen)
1281 #endif
1282 #if HAVE_SSL_CTX_set_max_send_fragment || defined(SSL_CTX_set_max_send_fragment)
1283 IF_OPENSSL("openssl-maxsendfrag", &opt_openssl_maxsendfrag)
1284 #endif
1285 #if WITH_OPENSSL_METHOD
1286 IF_OPENSSL("openssl-method", &opt_openssl_method)
1287 #endif
1288 #if HAVE_SSL_set_min_proto_version || defined(SSL_set_min_proto_version)
1289 IF_OPENSSL("openssl-min-proto-version", &opt_openssl_min_proto_version)
1290 #endif
1291 #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
1292 IF_OPENSSL("openssl-no-sni", &opt_openssl_no_sni)
1293 #endif
1294 IF_OPENSSL("openssl-pseudo", &opt_openssl_pseudo)
1295 #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
1296 IF_OPENSSL("openssl-snihost", &opt_openssl_snihost)
1297 #endif
1298 IF_OPENSSL("openssl-verify", &opt_openssl_verify)
1299 IF_TERMIOS("opost", &opt_opost)
1300 #if HAVE_TERMIOS_OSPEED
1301 IF_TERMIOS("ospeed", &opt_ospeed)
1302 #endif
1303 IF_ANY ("owner", &opt_user)
1304 IF_TERMIOS("parenb", &opt_parenb)
1305 IF_TERMIOS("parmrk", &opt_parmrk)
1306 IF_TERMIOS("parodd", &opt_parodd)
1307 #ifdef SO_PASSCRED
1308 IF_SOCKET ("passcred", &opt_so_passcred)
1309 #endif
1310 #if defined(AI_PASSIVE )
1311 IF_IP ("passive", &opt_ai_passive)
1312 #endif
1313 IF_EXEC ("path", &opt_path)
1314 #ifdef TCP_PAWS /* OSF1 */
1315 IF_TCP ("paws", &opt_tcp_paws)
1316 #endif
1317 #ifdef SO_PEERCRED
1318 IF_SOCKET ("peercred", &opt_so_peercred)
1319 #endif
1320 #ifdef PENDIN
1321 IF_TERMIOS("pendin", &opt_pendin)
1322 #endif
1323 IF_ANY ("perm", &opt_perm)
1324 IF_NAMED ("perm-early", &opt_perm_early)
1325 IF_ANY ("perm-late", &opt_perm_late)
1326 IF_SOCKET ("pf", &opt_protocol_family)
1327 IF_EXEC ("pgid", &opt_setpgid)
1328 IF_EXEC ("pipes", &opt_pipes)
1329 #if WITH_PIPE && defined(F_SETPIPE_SZ)
1330 IF_ANY ("pipesz", &opt_f_setpipe_sz)
1331 #endif
1332 #ifdef IP_PKTINFO
1333 IF_IP ("pktinfo", &opt_ip_pktinfo)
1334 #endif
1335 #ifdef IP_PKTOPTIONS
1336 IF_IP ("pktoptions", &opt_ip_pktoptions)
1337 IF_IP ("pktopts", &opt_ip_pktoptions)
1338 #endif
1339 IF_INTERFACE("pointopoint", &opt_iff_pointopoint)
1340 #ifdef I_POP
1341 IF_ANY ("pop-all", &opt_streams_i_pop_all)
1342 #endif
1343 /*IF_IPAPP("port", &opt_port)*/
1344 #ifdef IFF_PORTSEL
1345 IF_INTERFACE("portsel", &opt_iff_portsel)
1346 #endif
1347 #if WITH_POSIXMQ
1348 IF_ANY ("posixmq-priority", &opt_posixmq_priority)
1349 #endif
1350 #if HAVE_RESOLV_H && WITH_RES_PRIMARY
1351 IF_RESOLVE("primary", &opt_res_primary)
1352 #endif
1353 #ifdef SO_PRIORITY
1354 IF_SOCKET ("priority", &opt_so_priority)
1355 #endif
1356 #ifdef O_PRIV
1357 IF_OPEN ("priv", &opt_o_priv)
1358 #endif
1359 IF_INTERFACE("promisc", &opt_iff_promisc)
1360 IF_READLINE("prompt", &opt_prompt)
1361 #ifdef SO_PROTOTYPE
1362 IF_SOCKET ("protocol", &opt_so_prototype)
1363 #endif
1364 IF_SOCKET ("protocol-family", &opt_protocol_family)
1365 #ifdef SO_PROTOTYPE
1366 IF_SOCKET ("prototype", &opt_so_prototype)
1367 #endif
1368 IF_PROXY ("proxy-auth", &opt_proxy_authorization)
1369 IF_PROXY ("proxy-authorization", &opt_proxy_authorization)
1370 IF_PROXY ("proxy-authorization-file", &opt_proxy_authorization_file)
1371 IF_PROXY ("proxy-resolve", &opt_proxy_resolve)
1372 IF_PROXY ("proxyauth", &opt_proxy_authorization)
1373 IF_PROXY ("proxyauthfile", &opt_proxy_authorization_file)
1374 IF_PROXY ("proxyport", &opt_proxyport)
1375 #ifdef ECHOPRT
1376 IF_TERMIOS("prterase", &opt_echoprt)
1377 #endif
1378 IF_OPENSSL("pseudo", &opt_openssl_pseudo)
1379 #if HAVE_DEV_PTMX || HAVE_DEV_PTC
1380 IF_EXEC ("ptmx", &opt_ptmx)
1381 #endif
1382 #if HAVE_PTY
1383 IF_EXEC ("pty", &opt_pty)
1384 #endif
1385 #if HAVE_PTY && HAVE_POLL
1386 IF_PTY ("pty-interval", &opt_pty_intervall)
1387 IF_PTY ("pty-intervall", &opt_pty_intervall)
1388 IF_PTY ("pty-wait-slave", &opt_pty_wait_slave)
1389 #endif /* HAVE_PTY && HAVE_POLL */
1390 #ifdef I_PUSH
1391 IF_ANY ("push", &opt_streams_i_push)
1392 #endif
1393 #ifdef TCP_QUICKACK
1394 IF_TCP ("quickack", &opt_tcp_quickack)
1395 #endif
1396 IF_TERMIOS("quit", &opt_vquit)
1397 IF_RANGE ("range", &opt_range)
1398 IF_TERMIOS("raw", &opt_raw)
1399 IF_TERMIOS("rawer", &opt_termios_rawer)
1400 IF_SOCKET ("rcvbuf", &opt_so_rcvbuf)
1401 IF_SOCKET ("rcvbuf-late", &opt_so_rcvbuf_late)
1402 #ifdef SO_RCVLOWAT
1403 IF_SOCKET ("rcvlowat", &opt_so_rcvlowat)
1404 #endif
1405 #ifdef SO_RCVTIMEO
1406 IF_SOCKET ("rcvtimeo", &opt_so_rcvtimeo)
1407 #endif
1408 IF_OPEN ("rdonly", &opt_o_rdonly)
1409 IF_OPEN ("rdwr", &opt_o_rdwr)
1410 IF_ANY ("readbytes", &opt_readbytes)
1411 #if HAVE_RESOLV_H
1412 IF_RESOLVE("recurse", &opt_res_recurse)
1413 #endif /* HAVE_RESOLV_H */
1414 #ifdef IP_RECVDSTADDR
1415 IF_IP ("recvdstaddr", &opt_ip_recvdstaddr)
1416 #endif
1417 #ifdef IPV6_RECVDSTOPTS
1418 IF_IP6 ("recvdstopts", &opt_ipv6_recvdstopts)
1419 #endif
1420 #ifdef IP_RECVERR
1421 IF_IP ("recverr", &opt_ip_recverr)
1422 #endif
1423 #ifdef IPV6_RECVHOPLIMIT
1424 IF_IP6 ("recvhoplimit", &opt_ipv6_recvhoplimit)
1425 #endif
1426 #ifdef IPV6_RECVHOPOPTS
1427 IF_IP6 ("recvhopopts", &opt_ipv6_recvhopopts)
1428 #endif
1429 #ifdef IP_RECVIF
1430 IF_IP ("recvif", &opt_ip_recvif)
1431 #endif
1432 #ifdef IP_RECVOPTS
1433 IF_IP ("recvopts", &opt_ip_recvopts)
1434 #endif
1435 #ifdef IPV6_RECVPKTINFO
1436 IF_IP6 ("recvpktinfo", &opt_ipv6_recvpktinfo)
1437 #endif
1438 #ifdef IPV6_RECVRTHDR
1439 IF_IP6 ("recvrthdr", &opt_ipv6_recvrthdr)
1440 #endif
1441 #ifdef IP_RECVTOS
1442 IF_IP ("recvtos", &opt_ip_recvtos)
1443 #endif
1444 #ifdef IP_RECVTTL
1445 IF_IP ("recvttl", &opt_ip_recvttl)
1446 #endif
1447 IF_NAMED ("remove", &opt_unlink)
1448 #ifdef VREPRINT
1449 IF_TERMIOS("reprint", &opt_vreprint)
1450 #endif
1451 #if HAVE_RESOLV_H
1452 # if WITH_AA_ONLY
1453 IF_RESOLVE("res-aaonly", &opt_res_aaonly)
1454 # endif
1455 IF_RESOLVE("res-debug", &opt_res_debug)
1456 IF_RESOLVE("res-defnames", &opt_res_defnames)
1457 IF_RESOLVE("res-dnsrch", &opt_res_dnsrch)
1458 IF_RESOLVE("res-igntc", &opt_res_igntc)
1459 # if HAVE_RES_RETRANS
1460 IF_RESOLVE("res-maxretrans", &opt_res_retrans)
1461 # endif
1462 # if HAVE_RES_RETRY
1463 IF_RESOLVE("res-maxretry", &opt_res_retry)
1464 # endif
1465 #if WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST
1466 IF_IP ("res-nsaddr", &opt_res_nsaddr)
1467 # endif
1468 # if WITH_RES_PRIMARY
1469 IF_RESOLVE("res-primary", &opt_res_primary)
1470 # endif
1471 IF_RESOLVE("res-recurse", &opt_res_recurse)
1472 # if HAVE_RES_RETRANS
1473 IF_RESOLVE("res-retrans", &opt_res_retrans)
1474 # endif
1475 # if HAVE_RES_RETRY
1476 IF_RESOLVE("res-retry", &opt_res_retry)
1477 # endif
1478 IF_RESOLVE("res-stayopen", &opt_res_stayopen)
1479 IF_RESOLVE("res-usevc", &opt_res_usevc)
1480 #endif /* HAVE_RESOLV_H */
1481 IF_PROXY ("resolv", &opt_proxy_resolve)
1482 IF_PROXY ("resolve", &opt_proxy_resolve)
1483 #ifdef IP_RETOPTS
1484 IF_IP ("retopts", &opt_ip_retopts)
1485 #endif
1486 # if HAVE_RES_RETRANS
1487 IF_RESOLVE("retrans", &opt_res_retrans)
1488 # endif
1489 #if WITH_INTERFACE && defined(PACKET_AUXDATA)
1490 IF_SOCKET ("retrieve-vlan", &opt_retrieve_vlan)
1491 #endif
1492 IF_RETRY ("retry", &opt_retry)
1493 IF_SOCKET ("reuseaddr", &opt_so_reuseaddr)
1494 #ifdef SO_REUSEPORT /* AIX 4.3.3 */
1495 IF_SOCKET ("reuseport", &opt_so_reuseport)
1496 #endif /* defined(SO_REUSEPORT) */
1497 #ifdef TCP_RFC1323
1498 IF_TCP ("rfc1323", &opt_tcp_rfc1323)
1499 #endif
1500 #ifdef IP_ROUTER_ALERT
1501 IF_IP ("routeralert", &opt_ip_router_alert)
1502 #endif
1503 #ifdef VREPRINT
1504 IF_TERMIOS("rprnt", &opt_vreprint)
1505 #endif
1506 #ifdef O_RSHARE
1507 IF_OPEN ("rshare", &opt_o_rshare)
1508 #endif
1509 #ifdef O_RSYNC
1510 IF_OPEN ("rsync", &opt_o_rsync)
1511 #endif
1512 #ifdef IPV6_RTHDR
1513 IF_IP6 ("rthdr", &opt_ipv6_rthdr)
1514 #endif
1515 IF_INTERFACE("running", &opt_iff_running)
1516 #ifdef TCP_SACK_DISABLE
1517 IF_TCP ("sack-disable", &opt_tcp_sack_disable)
1518 #endif
1519 #ifdef TCP_SACKENA /* OSF1 */
1520 IF_TCP ("sackena", &opt_tcp_sackena)
1521 #endif
1522 IF_TERMIOS("sane", &opt_sane)
1523 #ifdef SCTP_MAXSEG
1524 IF_SCTP ("sctp-maxseg", &opt_sctp_maxseg)
1525 IF_SCTP ("sctp-maxseg-late", &opt_sctp_maxseg_late)
1526 #endif
1527 #ifdef SCTP_NODELAY
1528 IF_SCTP ("sctp-nodelay", &opt_sctp_nodelay)
1529 #endif
1530 #if WITH_FS && defined(FS_SECRM_FL)
1531 IF_ANY ("secrm", &opt_fs_secrm)
1532 #endif
1533 #ifdef SO_SECURITY_AUTHENTICATION
1534 IF_SOCKET ("security-authentication", &opt_so_security_authentication)
1535 #endif
1536 #ifdef SO_SECURITY_ENCRYPTION_NETWORK
1537 IF_SOCKET ("security-encryption-network", &opt_so_security_encryption_network)
1538 #endif
1539 #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
1540 IF_SOCKET ("security-encryption-transport", &opt_so_security_encryption_transport)
1541 #endif
1542 #ifdef SO_SECURITY_AUTHENTICATION
1543 IF_SOCKET ("securityauthentication", &opt_so_security_authentication)
1544 #endif
1545 #ifdef SO_SECURITY_ENCRYPTION_NETWORK
1546 IF_SOCKET ("securityencryptionnetwork", &opt_so_security_encryption_network)
1547 #endif
1548 #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
1549 IF_SOCKET ("securityencryptiontransport", &opt_so_security_encryption_transport)
1550 #endif
1551 #if HAVE_LSEEK64
1552 IF_ANY ("seek", &opt_lseek64_set)
1553 IF_ANY ("seek-cur", &opt_lseek64_cur)
1554 IF_ANY ("seek-end", &opt_lseek64_end)
1555 IF_ANY ("seek-set", &opt_lseek64_set)
1556 #else
1557 IF_ANY ("seek", &opt_lseek32_set)
1558 IF_ANY ("seek-cur", &opt_lseek32_cur)
1559 IF_ANY ("seek-end", &opt_lseek32_end)
1560 IF_ANY ("seek-set", &opt_lseek32_set)
1561 #endif
1562 IF_ANY ("setgid", &opt_setgid)
1563 IF_ANY ("setgid-early", &opt_setgid_early)
1564 IF_ANY ("setlk", &opt_f_setlk_wr)
1565 IF_ANY ("setlk-rd", &opt_f_setlk_rd)
1566 IF_ANY ("setlk-wr", &opt_f_setlk_wr)
1567 IF_ANY ("setlkw", &opt_f_setlkw_wr)
1568 IF_ANY ("setlkw-rd", &opt_f_setlkw_rd)
1569 IF_ANY ("setlkw-wr", &opt_f_setlkw_wr)
1570 IF_EXEC ("setpgid", &opt_setpgid)
1571 #if WITH_EXEC || WITH_SYSTEM
1572 IF_EXEC ("setsid", &opt_setsid)
1573 #endif
1574 IF_SOCKET ("setsockopt", &opt_setsockopt)
1575 IF_SOCKET ("setsockopt-bin", &opt_setsockopt_bin)
1576 IF_SOCKET ("setsockopt-int", &opt_setsockopt_int)
1577 IF_SOCKET ("setsockopt-listen", &opt_setsockopt_listen)
1578 IF_SOCKET ("setsockopt-string", &opt_setsockopt_string)
1579 IF_ANY ("setuid", &opt_setuid)
1580 IF_ANY ("setuid-early", &opt_setuid_early)
1581 #if WITH_SHELL
1582 IF_ANY ("shell", &opt_shell)
1583 #endif
1584 IF_ANY ("shut-close", &opt_shut_close)
1585 IF_ANY ("shut-down", &opt_shut_down)
1586 IF_ANY ("shut-none", &opt_shut_none)
1587 IF_ANY ("shut-null", &opt_shut_null)
1588 #if WITH_EXEC || WITH_SYSTEM
1589 IF_ANY ("sid", &opt_setsid)
1590 #endif
1591 IF_EXEC ("sighup", &opt_sighup)
1592 IF_EXEC ("sigint", &opt_sigint)
1593 #ifdef TCP_SIGNATURE_ENABLE
1594 IF_TCP ("signature-enable", &opt_tcp_signature_enable)
1595 #endif
1596 IF_EXEC ("sigquit", &opt_sigquit)
1597 #ifdef SIOCSPGRP
1598 IF_SOCKET ("siocspgrp", &opt_siocspgrp)
1599 #endif
1600 IF_PTY ("sitout-eio", &opt_sitout_eio)
1601 #ifdef IFF_SLAVE
1602 IF_INTERFACE("slave", &opt_iff_slave)
1603 #endif
1604 IF_SOCKET ("sndbuf", &opt_so_sndbuf)
1605 IF_SOCKET ("sndbuf-late", &opt_so_sndbuf_late)
1606 #ifdef SO_SNDLOWAT
1607 IF_SOCKET ("sndlowat", &opt_so_sndlowat)
1608 #endif
1609 #ifdef SO_SNDTIMEO
1610 IF_SOCKET ("sndtimeo", &opt_so_sndtimeo)
1611 #endif
1612 #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
1613 IF_OPENSSL("snihost", &opt_openssl_snihost)
1614 #endif
1615 #ifdef SO_ACCEPTCONN /* AIX433 */
1616 IF_SOCKET ("so-acceptconn", &opt_so_acceptconn)
1617 #endif /* SO_ACCEPTCONN */
1618 #ifdef SO_ATTACH_FILTER
1619 IF_SOCKET ("so-attach-filter", &opt_so_attach_filter)
1620 #endif
1621 #ifdef SO_AUDIT /* AIX 4.3.3 */
1622 IF_SOCKET ("so-audit", &opt_so_audit)
1623 #endif /* SO_AUDIT */
1624 #ifdef SO_BINDTODEVICE
1625 IF_SOCKET ("so-bindtodevice", &opt_so_bindtodevice)
1626 #endif
1627 IF_SOCKET ("so-broadcast", &opt_so_broadcast)
1628 #ifdef SO_BSDCOMPAT
1629 IF_SOCKET ("so-bsdcompat", &opt_so_bsdcompat)
1630 #endif
1631 #ifdef SO_CKSUMRECV
1632 IF_SOCKET ("so-cksumrecv", &opt_so_cksumrecv)
1633 #endif /* SO_CKSUMRECV */
1634 IF_SOCKET ("so-debug", &opt_so_debug)
1635 #ifdef SO_DETACH_FILTER
1636 IF_SOCKET ("so-detach-filter", &opt_so_detach_filter)
1637 #endif
1638 #ifdef SO_DGRAM_ERRIND
1639 IF_SOCKET ("so-dgram-errind", &opt_so_dgram_errind)
1640 #endif
1641 #ifdef SO_DONTLINGER
1642 IF_SOCKET ("so-dontlinger", &opt_so_dontlinger)
1643 #endif
1644 IF_SOCKET ("so-dontroute", &opt_so_dontroute)
1645 IF_SOCKET ("so-error", &opt_so_error)
1646 IF_SOCKET ("so-keepalive", &opt_so_keepalive)
1647 #ifdef SO_KERNACCEPT /* AIX 4.3.3 */
1648 IF_SOCKET ("so-kernaccept", &opt_so_kernaccept)
1649 #endif /* SO_KERNACCEPT */
1650 IF_SOCKET ("so-linger", &opt_so_linger)
1651 #ifdef SO_NO_CHECK
1652 IF_SOCKET ("so-no-check", &opt_so_no_check)
1653 #endif
1654 #ifdef SO_NOREUSEADDR /* AIX 4.3.3 */
1655 IF_SOCKET ("so-noreuseaddr", &opt_so_noreuseaddr)
1656 #endif /* SO_NOREUSEADDR */
1657 IF_SOCKET ("so-oobinline", &opt_so_oobinline)
1658 #ifdef SO_PASSCRED
1659 IF_SOCKET ("so-passcred", &opt_so_passcred)
1660 #endif
1661 #ifdef SO_PEERCRED
1662 IF_SOCKET ("so-peercred", &opt_so_peercred)
1663 #endif
1664 #ifdef SO_PRIORITY
1665 IF_SOCKET ("so-priority", &opt_so_priority)
1666 #endif
1667 #ifdef SO_PROTOTYPE
1668 IF_SOCKET ("so-protocol", &opt_so_prototype)
1669 IF_SOCKET ("so-prototype", &opt_so_prototype)
1670 #endif
1671 IF_SOCKET ("so-rcvbuf", &opt_so_rcvbuf)
1672 IF_SOCKET ("so-rcvbuf-late", &opt_so_rcvbuf_late)
1673 #ifdef SO_RCVLOWAT
1674 IF_SOCKET ("so-rcvlowat", &opt_so_rcvlowat)
1675 #endif
1676 #ifdef SO_RCVTIMEO
1677 IF_SOCKET ("so-rcvtimeo", &opt_so_rcvtimeo)
1678 #endif
1679 IF_SOCKET ("so-reuseaddr", &opt_so_reuseaddr)
1680 #ifdef SO_REUSEPORT /* AIX 4.3.3 */
1681 IF_SOCKET ("so-reuseport", &opt_so_reuseport)
1682 #endif /* defined(SO_REUSEPORT) */
1683 #ifdef SO_SECURITY_AUTHENTICATION
1684 IF_SOCKET ("so-security-authentication", &opt_so_security_authentication)
1685 #endif
1686 #ifdef SO_SECURITY_ENCRYPTION_NETWORK
1687 IF_SOCKET ("so-security-encryption-network", &opt_so_security_encryption_network)
1688 #endif
1689 #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
1690 IF_SOCKET ("so-security-encryption-transport", &opt_so_security_encryption_transport)
1691 #endif
1692 IF_SOCKET ("so-sndbuf", &opt_so_sndbuf)
1693 IF_SOCKET ("so-sndbuf-late", &opt_so_sndbuf_late)
1694 #ifdef SO_SNDLOWAT
1695 IF_SOCKET ("so-sndlowat", &opt_so_sndlowat)
1696 #endif
1697 #ifdef SO_SNDTIMEO
1698 IF_SOCKET ("so-sndtimeo", &opt_so_sndtimeo)
1699 #endif
1700 #ifdef SO_TIMESTAMP
1701 IF_SOCKET ("so-timestamp", &opt_so_timestamp)
1702 #endif
1703 IF_SOCKET ("so-type", &opt_so_type)
1704 #ifdef SO_USE_IFBUFS
1705 IF_SOCKET ("so-use-ifbufs", &opt_so_use_ifbufs)
1706 #endif /* SO_USE_IFBUFS */
1707 #ifdef SO_USELOOPBACK /* AIX433, Solaris */
1708 IF_SOCKET ("so-useloopback", &opt_so_useloopback)
1709 #endif /* SO_USELOOPBACK */
1710 IF_SOCKET ("sockopt", &opt_setsockopt)
1711 IF_SOCKET ("sockopt-bin", &opt_setsockopt_bin)
1712 IF_SOCKET ("sockopt-int", &opt_setsockopt_int)
1713 IF_SOCKET ("sockopt-listen", &opt_setsockopt_listen)
1714 IF_SOCKET ("sockopt-string", &opt_setsockopt_string)
1715 IF_SOCKS4 ("socksport", &opt_socksport)
1716 IF_SOCKS4 ("socksuser", &opt_socksuser)
1717 IF_SOCKET ("socktype", &opt_so_type)
1718 #if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP)
1719 IF_IP ("source-membership", &opt_ip_add_source_membership)
1720 #endif
1721 IF_IPAPP ("sourceport", &opt_sourceport)
1722 IF_IPAPP ("sp", &opt_sourceport)
1723 IF_TERMIOS("start", &opt_vstart)
1724 #if HAVE_RESOLV_H
1725 IF_RESOLVE("stayopen", &opt_res_stayopen)
1726 #endif /* HAVE_RESOLV_H */
1727 IF_EXEC ("stderr", &opt_stderr)
1728 #ifdef TCP_STDURG
1729 IF_TCP ("stdurg", &opt_tcp_stdurg)
1730 #endif
1731 IF_TERMIOS("stop", &opt_vstop)
1732 #ifdef I_POP
1733 IF_ANY ("streams-i-pop-all", &opt_streams_i_pop_all)
1734 #endif
1735 #ifdef I_PUSH
1736 IF_ANY ("streams-i-push", &opt_streams_i_push)
1737 #endif
1738 IF_ANY ("su", &opt_substuser)
1739 #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
1740 IF_ANY ("su-d", &opt_substuser_delayed)
1741 #endif
1742 IF_ANY ("su-e", &opt_substuser_early)
1743 IF_ANY ("substuser", &opt_substuser)
1744 #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
1745 IF_ANY ("substuser-delayed", &opt_substuser_delayed)
1746 #endif
1747 IF_ANY ("substuser-early", &opt_substuser_early)
1748 IF_TERMIOS("susp", &opt_vsusp)
1749 #ifdef VSWTC
1750 IF_TERMIOS("swtc", &opt_vswtc)
1751 IF_TERMIOS("swtch", &opt_vswtc)
1752 #endif
1753 IF_PTY ("symbolic-link", &opt_symbolic_link)
1754 #ifdef O_SYNC
1755 IF_OPEN ("sync", &opt_o_sync)
1756 #elif FS_SYNC_FL
1757 IF_ANY ("sync", &opt_fs_sync)
1758 #endif
1759 #ifdef TCP_SYNCNT
1760 IF_TCP ("syncnt", &opt_tcp_syncnt)
1761 #endif
1762 #ifdef TABDLY
1763 # ifdef TAB0
1764 IF_TERMIOS("tab0", &opt_tab0)
1765 # endif
1766 # ifdef TAB1
1767 IF_TERMIOS("tab1", &opt_tab1)
1768 # endif
1769 # ifdef TAB2
1770 IF_TERMIOS("tab2", &opt_tab2)
1771 # endif
1772 # ifdef TAB3
1773 IF_TERMIOS("tab3", &opt_tab3)
1774 # endif
1775 # if TABDLY_SHIFT >= 0
1776 IF_TERMIOS("tabdly", &opt_tabdly)
1777 # endif
1778 #endif
1779 IF_TERMIOS("tandem", &opt_ixoff)
1780 #ifdef TCP_ABORT_THRESHOLD /* HP_UX */
1781 IF_TCP ("tcp-abort-threshold", &opt_tcp_abort_threshold)
1782 #endif
1783 #ifdef TCP_CONN_ABORT_THRESHOLD /* HP_UX */
1784 IF_TCP ("tcp-conn-abort-threshold", &opt_tcp_conn_abort_threshold)
1785 #endif
1786 #ifdef TCP_CORK
1787 IF_TCP ("tcp-cork", &opt_tcp_cork)
1788 #endif
1789 #ifdef TCP_DEFER_ACCEPT /* Linux 2.4.0 */
1790 IF_TCP ("tcp-defer-accept", &opt_tcp_defer_accept)
1791 #endif
1792 #ifdef TCP_INFO /* Linux 2.4.0 */
1793 IF_TCP ("tcp-info", &opt_tcp_info)
1794 #endif
1795 #ifdef TCP_KEEPCNT /* Linux 2.4.0 */
1796 IF_TCP ("tcp-keepcnt", &opt_tcp_keepcnt)
1797 #endif
1798 #ifdef TCP_KEEPIDLE /* Linux 2.4.0 */
1799 IF_TCP ("tcp-keepidle", &opt_tcp_keepidle)
1800 #endif
1801 #ifdef TCP_KEEPINIT /* OSF1 */
1802 IF_TCP ("tcp-keepinit", &opt_tcp_keepinit)
1803 #endif
1804 #ifdef TCP_KEEPINTVL /* Linux 2.4.0 */
1805 IF_TCP ("tcp-keepintvl", &opt_tcp_keepintvl)
1806 #endif
1807 #ifdef TCP_LINGER2 /* Linux 2.4.0 */
1808 IF_TCP ("tcp-linger2", &opt_tcp_linger2)
1809 #endif
1810 #ifdef TCP_MAXSEG
1811 IF_TCP ("tcp-maxseg", &opt_tcp_maxseg)
1812 IF_TCP ("tcp-maxseg-late", &opt_tcp_maxseg_late)
1813 #endif
1814 #ifdef TCP_MD5SIG
1815 IF_TCP ("tcp-md5sig", &opt_tcp_md5sig)
1816 #endif
1817 #ifdef TCP_NODELAY
1818 IF_TCP ("tcp-nodelay", &opt_tcp_nodelay)
1819 #endif
1820 #ifdef TCP_NOOPT
1821 IF_TCP ("tcp-noopt", &opt_tcp_noopt)
1822 #endif
1823 #ifdef TCP_NOPUSH
1824 IF_TCP ("tcp-nopush", &opt_tcp_nopush)
1825 #endif
1826 #ifdef TCP_PAWS /* OSF1 */
1827 IF_TCP ("tcp-paws", &opt_tcp_paws)
1828 #endif
1829 #ifdef TCP_QUICKACK
1830 IF_TCP ("tcp-quickack", &opt_tcp_quickack)
1831 #endif
1832 #ifdef TCP_RFC1323
1833 IF_TCP ("tcp-rfc1323", &opt_tcp_rfc1323)
1834 #endif
1835 #ifdef TCP_SACK_DISABLE
1836 IF_TCP ("tcp-sack-disable", &opt_tcp_sack_disable)
1837 #endif
1838 #ifdef TCP_SACKENA /* OSF1 */
1839 IF_TCP ("tcp-sackena", &opt_tcp_sackena)
1840 #endif
1841 #ifdef TCP_SIGNATURE_ENABLE
1842 IF_TCP ("tcp-signature-enable", &opt_tcp_signature_enable)
1843 #endif
1844 #ifdef TCP_STDURG
1845 IF_TCP ("tcp-stdurg", &opt_tcp_stdurg)
1846 #endif
1847 #ifdef TCP_SYNCNT /* Linux 2.4.0 */
1848 IF_TCP ("tcp-syncnt", &opt_tcp_syncnt)
1849 #endif
1850 #ifdef TCP_TSOPTENA /* OSF1 */
1851 IF_TCP ("tcp-tsoptena", &opt_tcp_tsoptena)
1852 #endif
1853 #ifdef TCP_WINDOW_CLAMP /* Linux 2.4.0 */
1854 IF_TCP ("tcp-window-clamp", &opt_tcp_window_clamp)
1855 #endif
1856 #if WITH_LIBWRAP
1857 IF_IPAPP ("tcpwrap", &opt_tcpwrappers)
1858 IF_IPAPP ("tcpwrap-dir", &opt_tcpwrap_etc)
1859 IF_IPAPP ("tcpwrap-etc", &opt_tcpwrap_etc)
1860 #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE)
1861 IF_IPAPP ("tcpwrap-hosts-allow-table", &opt_tcpwrap_hosts_allow_table)
1862 #endif
1863 #if WITH_LIBWRAP && defined(HAVE_HOSTS_DENY_TABLE)
1864 IF_IPAPP ("tcpwrap-hosts-deny-table", &opt_tcpwrap_hosts_deny_table)
1865 #endif
1866 IF_IPAPP ("tcpwrapper", &opt_tcpwrappers)
1867 IF_IPAPP ("tcpwrappers", &opt_tcpwrappers)
1868 #endif
1869 IF_TERMIOS("termios-cfmakeraw", &opt_termios_cfmakeraw)
1870 IF_TERMIOS("termios-rawer", &opt_termios_rawer)
1871 #ifdef O_TEXT
1872 IF_ANY ("text", &opt_o_text)
1873 #endif
1874 IF_UNIX ("tightsocklen", &xioopt_unix_tightsocklen)
1875 IF_TERMIOS("time", &opt_vtime)
1876 #ifdef SO_TIMESTAMP
1877 IF_SOCKET ("timestamp", &opt_so_timestamp)
1878 #endif
1879 IF_TERMIOS("tiocsctty", &opt_tiocsctty)
1880 #if WITH_FS && defined(FS_TOPDIR_FL)
1881 IF_ANY ("topdir", &opt_fs_topdir)
1882 #endif
1883 IF_IP ("tos", &opt_ip_tos)
1884 IF_TERMIOS("tostop", &opt_tostop)
1885 #ifdef IP_TRANSPARENT
1886 IF_IP ("transparent", &opt_ip_transparent)
1887 #endif
1888 IF_OPEN ("trunc", &opt_o_trunc)
1889 #if HAVE_FTRUNCATE64
1890 IF_ANY ("truncate", &opt_ftruncate64)
1891 #else
1892 IF_ANY ("truncate", &opt_ftruncate32)
1893 #endif
1894 #ifdef TCP_TSOPTENA /* OSF1 */
1895 IF_TCP ("tsoptena", &opt_tcp_tsoptena)
1896 #endif
1897 IF_IP ("ttl", &opt_ip_ttl)
1898 IF_TUN ("tun-device", &opt_tun_device)
1899 IF_TUN ("tun-name", &opt_tun_name)
1900 IF_TUN ("tun-no-pi", &opt_iff_no_pi)
1901 IF_TUN ("tun-type", &opt_tun_type)
1902 IF_SOCKET ("type", &opt_so_type)
1903 IF_UDPLITE("udplite-recv-cscov", &xioopt_udplite_recv_cscov)
1904 IF_UDPLITE("udplite-send-cscov", &xioopt_udplite_send_cscov)
1905 IF_ANY ("uid", &opt_user)
1906 IF_NAMED ("uid-e", &opt_user_early)
1907 IF_ANY ("uid-l", &opt_user_late)
1908 IF_NAMED ("umask", &opt_umask)
1909 IF_IP6 ("unicast-hops", &opt_ipv6_unicast_hops)
1910 IF_UNIX ("unix-bind-tempname", &xioopt_unix_bind_tempname)
1911 IF_UNIX ("unix-tightsocklen", &xioopt_unix_tightsocklen)
1912 IF_NAMED ("unlink", &opt_unlink)
1913 IF_NAMED ("unlink-close", &opt_unlink_close)
1914 IF_NAMED ("unlink-early", &opt_unlink_early)
1915 IF_NAMED ("unlink-late", &opt_unlink_late)
1916 #if WITH_FS && defined(FS_UNRM_FL)
1917 IF_ANY ("unrm", &opt_fs_unrm)
1918 #endif
1919 IF_INTERFACE("up", &opt_iff_up)
1920 #ifdef SO_USE_IFBUFS
1921 IF_SOCKET ("use-ifbufs", &opt_so_use_ifbufs)
1922 IF_SOCKET ("useifbufs", &opt_so_use_ifbufs)
1923 #endif /* SO_USE_IFBUFS */
1924 #ifdef SO_USELOOPBACK /* AIX433, Solaris */
1925 IF_SOCKET ("useloopback", &opt_so_useloopback)
1926 #endif /* SO_USELOOPBACK */
1927 IF_ANY ("user", &opt_user)
1928 IF_NAMED ("user-early", &opt_user_early)
1929 IF_ANY ("user-late", &opt_user_late)
1930 #if HAVE_RESOLV_H
1931 IF_RESOLVE("usevc", &opt_res_usevc)
1932 #endif /* HAVE_RESOLV_H */
1933 #if defined(AI_V4MAPPED)
1934 IF_IP ("v4mapped", &opt_ai_v4mapped)
1935 #endif
1936 #ifdef IPV6_V6ONLY
1937 IF_IP6 ("v6only", &opt_ipv6_v6only)
1938 #endif
1939 #ifdef VDISCARD
1940 IF_TERMIOS("vdiscard", &opt_vdiscard)
1941 #endif
1942 #ifdef VDSUSP /* HP-UX */
1943 IF_TERMIOS("vdsusp", &opt_vdsusp)
1944 #endif
1945 IF_TERMIOS("veof", &opt_veof)
1946 IF_TERMIOS("veol", &opt_veol)
1947 IF_TERMIOS("veol2", &opt_veol2)
1948 IF_TERMIOS("verase", &opt_verase)
1949 IF_OPENSSL("verify", &opt_openssl_verify)
1950 IF_TERMIOS("vintr", &opt_vintr)
1951 IF_TERMIOS("vkill", &opt_vkill)
1952 IF_TERMIOS("vlnext", &opt_vlnext)
1953 IF_TERMIOS("vmin", &opt_vmin)
1954 IF_TERMIOS("vquit", &opt_vquit)
1955 #ifdef VREPRINT
1956 IF_TERMIOS("vreprint", &opt_vreprint)
1957 #endif
1958 IF_TERMIOS("vstart", &opt_vstart)
1959 IF_TERMIOS("vstop", &opt_vstop)
1960 IF_TERMIOS("vsusp", &opt_vsusp)
1961 #ifdef VSWTC
1962 IF_TERMIOS("vswtc", &opt_vswtc)
1963 #endif
1964 #ifdef VTDLY
1965 # ifdef VT0
1966 IF_TERMIOS("vt0", &opt_vt0)
1967 # endif
1968 # ifdef VT1
1969 IF_TERMIOS("vt1", &opt_vt1)
1970 # endif
1971 IF_TERMIOS("vtdly", &opt_vtdly)
1972 #endif
1973 IF_TERMIOS("vtime", &opt_vtime)
1974 #ifdef VWERASE
1975 IF_TERMIOS("vwerase", &opt_vwerase)
1976 #endif
1977 #if HAVE_PTY && HAVE_POLL
1978 IF_PTY ("wait-slave", &opt_pty_wait_slave)
1979 #endif /* HAVE_PTY && HAVE_POLL */
1980 IF_ANY ("waitlock", &opt_waitlock)
1981 #if HAVE_PTY && HAVE_POLL
1982 IF_PTY ("waitslave", &opt_pty_wait_slave)
1983 #endif /* HAVE_PTY && HAVE_POLL */
1984 #ifdef VWERASE
1985 IF_TERMIOS("werase", &opt_vwerase)
1986 #endif
1987 #ifdef TCP_WINDOW_CLAMP /* Linux 2.4.0 */
1988 IF_TCP ("window-clamp", &opt_tcp_window_clamp)
1989 #endif
1990 #if WITH_LIBWRAP
1991 IF_IPAPP ("wrap", &opt_tcpwrappers)
1992 #endif
1993 IF_OPEN ("wronly", &opt_o_wronly)
1994 #ifdef XCASE
1995 IF_TERMIOS("xcase", &opt_xcase)
1996 #endif
1997 #if defined(TABDLY) && defined(XTABS)
1998 IF_TERMIOS("xtabs", &opt_xtabs)
1999 #endif
2000 { NULL }
2004 /* walks the text argument a and writes its options that conform to groups
2005 to the array opts. Uses the option table 'optionnames'.
2006 returns 0 on success, -1 on error, 1 on unknown/wrong option
2008 int parseopts(const char **a, groups_t groups, struct opt **opts) {
2010 return parseopts_table(a, groups, opts, optionnames,
2011 sizeof(optionnames)/sizeof(struct optname)-1);
2015 /* walks the text argument a and writes its options that conform to groups
2016 to the array opts. Uses the specified option table.
2017 returns 0 on success, -1 on error, 1 on unknown/wrong option
2019 int parseopts_table(const char **a, groups_t groups, struct opt **opts,
2020 const struct optname optionnames[], size_t optionnum) {
2021 int i=0;
2022 struct opt *opt;
2023 bool assign;
2024 const char *a0 = *a;
2025 unsigned long ulongval;
2026 long slongval;
2027 long long slonglongval;
2028 char token[2048], *tokp; size_t len;
2029 int parsres;
2030 int result;
2031 uint8_t optbuf[256]; size_t optlen;
2032 const char *endkey[6+1];
2033 const char *endval[5+1];
2034 const char *assign_str = "=";
2035 const char *hquotes[] = {
2036 "'",
2037 NULL
2039 const char *squotes[] = {
2040 "\"",
2041 NULL
2043 const char *nests[] = {
2044 "(", ")",
2045 "[", "]",
2046 "{", "}",
2047 NULL
2050 i = 0;
2051 /*endkey[i++] = xioparms.chainsep;*/ /* default: "|" */
2052 endkey[i++] = xioparms.pipesep; /* default: "!!" */
2053 endkey[i++] = ","/*xioparms.comma*/; /* default: "," */
2054 endkey[i++] = "=";
2055 endkey[i++] = NULL;
2057 i = 0;
2058 /*endval[i++] = xioparms.chainsep;*/ /* default: "|" */
2059 endval[i++] = xioparms.pipesep; /* default: "!!" */
2060 endval[i++] = ","/*xioparms.comma*/; /* default: "," */
2061 endval[i++] = NULL;
2063 i = 0;
2064 *opts = Malloc((i+8)*sizeof(struct opt));
2065 if (*opts == NULL) {
2066 return -1;
2068 if (*a == NULL) {
2069 (*opts)[i].desc = ODESC_END;
2070 return 0;
2073 while (true) {
2074 const struct optname *ent;
2076 if (a == NULL || *a == NULL || **a == '\0')
2077 break;
2079 while (!strncmp(*a, ",", strlen(","))) { (*a) += strlen(","); }
2080 a0 = *a;
2082 len = sizeof(token); tokp = token;
2083 parsres =
2084 nestlex(a, &tokp, &len, endkey, hquotes, squotes, nests,
2085 true, true, false);
2086 if (parsres < 0) {
2087 Error1("option too long: \"%s\"", *a);
2088 return -1;
2089 } else if (parsres > 0) {
2090 Error1("syntax error in \"%s\"", *a);
2091 return -1;
2093 if (tokp == token) {
2094 /* no option found */
2095 break;
2097 *tokp = '\0';
2099 ent = (struct optname *)
2100 keyw((struct wordent *)optionnames, token, optionnum);
2101 if (ent == NULL) {
2102 Error1("parseopts_table(): unknown option \"%s\"", token);
2103 continue;
2106 if (!(ent->desc->group & groups) && !(ent->desc->group & GROUP_ANY) &&
2107 (ent->desc->group != GROUP_ADDR) && !xioopts_ignoregroups) {
2108 Error1("parseopts_table(): option \"%s\" not supported with this address type",
2109 token /*a0*/);
2110 Info2("parseopts_table() groups="F_groups_t", ent->group="F_groups_t,
2111 groups, ent->desc->group);
2112 #if 0
2113 continue;
2114 #endif
2116 (*opts)[i].desc = ent->desc;
2118 if (!strncmp(*a, assign_str, strlen(assign_str))) {
2119 /* there is an assignment (mostly "=") */
2120 (*a) += strlen(assign_str);
2121 len = sizeof(token); tokp = token;
2122 parsres =
2123 nestlex(a, &tokp, &len, endval, hquotes, squotes, nests,
2124 true, true, false);
2125 if (parsres < 0) {
2126 Error1("option too long: \"%s\"", *a);
2127 return -1;
2128 } else if (parsres > 0) {
2129 Error1("syntax error in \"%s\"", *a);
2130 return -1;
2132 *tokp = '\0';
2133 assign = true;
2135 } else {
2136 assign = false;
2138 opt = &(*opts)[i];
2140 switch (ent->desc->type) {
2141 case TYPE_CONST:
2142 if (assign) {
2143 Error1("no value permitted for option \"%s\"",
2144 ent->desc->defname);
2145 continue;
2147 Info1("setting option \"%s\"", ent->desc->defname);
2148 break;
2149 case TYPE_BIN:
2150 if (!assign) { Error1("option \"%s\": value required", a0);
2151 continue; }
2152 optlen = 0;
2153 if ((result = dalan(token, optbuf, &optlen, sizeof(optbuf), 'i')) != 0) {
2154 Error1("parseopts_table(): problem with \"%s\" data", token);
2155 continue;
2157 if (((*opts)[i].value.u_bin.b_data = memdup(optbuf, optlen)) == NULL) {
2158 Error1("memdup(, "F_Zu"): out of memory", optlen);
2159 return -1;
2161 (*opts)[i].value.u_bin.b_len = optlen;
2162 break;
2163 case TYPE_BYTE:
2164 if (assign) {
2165 unsigned long ul;
2166 char *rest;
2167 ul = Strtoul(token, &rest, 0, a0);
2168 if (ul > UCHAR_MAX) {
2169 Error3("parseopts(): option \"%s\": byte value exceeds limit (%lu vs. %u), using max",
2170 a0, ul, UCHAR_MAX);
2171 (*opts)[i].value.u_byte = UCHAR_MAX;
2172 } else {
2173 (*opts)[i].value.u_byte = ul;
2175 } else {
2176 (*opts)[i].value.u_byte = 1;
2178 Info2("setting option \"%s\" to %d", ent->desc->defname,
2179 (*opts)[i].value.u_byte);
2180 break;
2181 #if HAVE_BASIC_OFF_T==3
2182 case TYPE_OFF32:
2183 #endif
2184 case TYPE_INT:
2185 if (assign) {
2186 char *rest;
2187 (*opts)[i].value.u_int = Strtoul(token, &rest, 0, a0);
2188 } else {
2189 (*opts)[i].value.u_int = 1;
2191 Info2("setting option \"%s\" to %d", ent->desc->defname,
2192 (*opts)[i].value.u_int);
2193 break;
2194 case TYPE_INT_NULL:
2195 (*opts)[i].value2.u_bool = true;
2196 if (assign && token[0] != '\0') {
2197 char *rest;
2198 (*opts)[i].value.u_int = Strtoul(token, &rest, 0, a0);
2199 } else if (assign) {
2200 (*opts)[i].value2.u_bool = false; /* NULL / no value */
2201 Info1("setting option \"%s\" to NULL", ent->desc->defname);
2202 break;
2203 } else {
2204 (*opts)[i].value.u_int = 1;
2206 Info2("setting option \"%s\" to %d", ent->desc->defname,
2207 (*opts)[i].value.u_int);
2208 break;
2209 case TYPE_BOOL:
2210 if (!assign) {
2211 (*opts)[i].value.u_bool = 1;
2212 } else {
2213 char *rest;
2214 (*opts)[i].value.u_bool = Strtoul(token, &rest, 0, a0);
2216 Info2("setting option \"%s\" to %d", ent->desc->defname,
2217 (*opts)[i].value.u_bool);
2218 break;
2220 #if HAVE_BASIC_SIZE_T==4
2221 case TYPE_SIZE_T:
2222 #endif
2223 case TYPE_UINT:
2224 if (!assign) {
2225 (*opts)[i].value.u_uint = 1;
2226 } else {
2227 char *rest;
2228 ulongval = Strtoul(token, &rest, 0, a0);
2229 (*opts)[i].value.u_uint = ulongval;
2231 Info2("setting option \"%s\" to %u", ent->desc->defname,
2232 (*opts)[i].value.u_uint);
2233 break;
2235 #if HAVE_BASIC_SIZE_T==2
2236 case TYPE_SIZE_T:
2237 #endif
2238 case TYPE_USHORT:
2239 if (!assign) {
2240 (*opts)[i].value.u_ushort = 1;
2241 } else {
2242 char *rest;
2243 ulongval = Strtoul(token, &rest, 0, a0);
2244 (*opts)[i].value.u_ushort = ulongval;
2246 Info2("setting option \"%s\" to %u", ent->desc->defname,
2247 (*opts)[i].value.u_ushort);
2248 break;
2250 #if HAVE_BASIC_OFF_T==5
2251 case TYPE_OFF32:
2252 #endif
2253 #if HAVE_STAT64 && defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T==5
2254 case TYPE_OFF64:
2255 #endif
2256 case TYPE_LONG:
2257 if (!assign) {
2258 (*opts)[i].value.u_long = 1;
2259 } else {
2260 char *rest;
2261 slongval = Strtoul(token, &rest, 0, a0);
2262 (*opts)[i].value.u_long = slongval;
2264 Info2("setting option \"%s\" to %lu", ent->desc->defname,
2265 (*opts)[i].value.u_long);
2266 break;
2268 #if HAVE_BASIC_SIZE_T==6
2269 case TYPE_SIZE_T:
2270 #endif
2271 case TYPE_ULONG:
2272 if (!assign) {
2273 (*opts)[i].value.u_ulong = 1;
2274 } else {
2275 char *rest;
2276 ulongval = Strtoul(token, &rest, 0, a0);
2277 (*opts)[i].value.u_ulong = ulongval;
2279 Info2("setting option \"%s\" to %lu", ent->desc->defname,
2280 (*opts)[i].value.u_ulong);
2281 break;
2283 #if HAVE_BASIC_OFF_T==7
2284 case TYPE_OFF32:
2285 #endif
2286 #if HAVE_TYPE_LONGLONG
2287 case TYPE_LONGLONG:
2288 # if HAVE_STAT64 && defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T==7
2289 case TYPE_OFF64:
2290 # endif
2291 if (!assign) {
2292 (*opts)[i].value.u_longlong = 1;
2293 } else {
2294 char *rest;
2295 # if HAVE_STRTOLL
2296 slonglongval = Strtoll(token, &rest, 0, a0);
2297 # else
2298 /* in this case, input value range is limited */
2299 slonglongval = Strtol(token, &rest, 0, a0);
2300 # endif /* HAVE_STRTOLL */
2301 if (*rest != '\0') {
2302 Error1("parseopts(): trailing garbage in numerical arg of option \"%s\"", a0);
2304 (*opts)[i].value.u_longlong = slonglongval;
2306 Info2("setting option \"%s\" to %Lu", ent->desc->defname,
2307 (*opts)[i].value.u_longlong);
2308 break;
2309 #endif /* HAVE_TYPE_LONGLONG */
2311 case TYPE_UIDT:
2312 if (!assign) {
2313 Error1("option \"%s\": value required", a0);
2314 continue;
2316 if (isdigit((*token)&0xff)) {
2317 char *rest;
2318 (*opts)[i].value.u_uidt = Strtoul(token, &rest, 0, a0);
2319 } else {
2320 struct passwd *pwd;
2321 if ((pwd = getpwnam(token)) == NULL) {
2322 Error1("getpwnam(\"%s\"): no such user", token);
2323 continue;
2325 (*opts)[i].value.u_uidt = getpwnam(token)->pw_uid;
2327 Info2("setting option \"%s\" to %u", ent->desc->defname,
2328 (*opts)[i].value.u_uidt);
2329 break;
2331 case TYPE_GIDT:
2332 if (!assign) { Error1("option \"%s\": value required", a0);
2333 continue; }
2334 if (isdigit((token[0])&0xff)) {
2335 char *rest;
2336 (*opts)[i].value.u_gidt = Strtoul(token, &rest, 0, a0);
2337 } else {
2338 struct group *grp;
2339 grp = getgrnam(token);
2340 if (grp == NULL) {
2341 Error1("getgrnam(\"%s\"): no such group", token);
2342 continue;
2344 (*opts)[i].value.u_gidt = grp->gr_gid;
2346 Info2("setting option \"%s\" to %u", ent->desc->defname,
2347 (*opts)[i].value.u_gidt);
2348 break;
2350 case TYPE_MODET:
2351 if (!assign) { Error1("option \"%s\": value required", a0);
2352 continue;
2355 char *rest;
2356 (*opts)[i].value.u_modet = Strtoul(token, &rest, 8, a0);
2358 Info2("setting option \"%s\" to %u", ent->desc->defname,
2359 (*opts)[i].value.u_modet);
2360 break;
2362 case TYPE_STRING:
2363 if (!assign) {
2364 Error1("option \"%s\": value required", a0);
2365 continue;
2367 if (((*opts)[i].value.u_string = strdup(token)) == NULL) {
2368 Error("out of memory"); return -1;
2370 Info2("setting option \"%s\" to \"%s\"", ent->desc->defname,
2371 (*opts)[i].value.u_string);
2372 break;
2374 case TYPE_STRING_NULL:
2375 if (!assign) {
2376 (*opts)[i].value.u_string = NULL;
2377 Info1("setting option \"%s\" to NULL", ent->desc->defname);
2378 } else {
2379 (*opts)[i].value.u_string = strdup(token);
2380 Info2("setting option \"%s\" to \"%s\"", ent->desc->defname,
2381 (*opts)[i].value.u_string);
2383 break;
2385 #if LATER
2386 case TYPE_INT3:
2388 break;
2389 #endif
2391 case TYPE_TIMEVAL:
2392 if (!assign) {
2393 Error1("option \"%s\": value required", a0);
2394 continue;
2395 } else {
2396 double val;
2397 char *rest;
2398 val = Strtod(token, &rest, a0);
2399 if (val == HUGE_VAL || val == -HUGE_VAL ||
2400 val == 0.0 && errno == ERANGE) {
2401 Error2("strtod(\"%s\", NULL): %s", token, strerror(errno));
2402 val = 0.0;
2404 (*opts)[i].value.u_timeval.tv_sec = val;
2405 (*opts)[i].value.u_timeval.tv_usec =
2406 (val-(*opts)[i].value.u_timeval.tv_sec+0.0000005) * 1000000;
2408 break;
2410 #if HAVE_STRUCT_TIMESPEC
2411 case TYPE_TIMESPEC:
2412 if (!assign) {
2413 Error1("option \"%s\": value required", a0);
2414 continue;
2415 } else {
2416 double val;
2417 char *rest;
2418 val = Strtod(token, &rest, a0);
2419 if (val == HUGE_VAL || val == -HUGE_VAL ||
2420 val == 0.0 && errno == ERANGE) {
2421 Error2("strtod(\"%s\", NULL): %s", token, strerror(errno));
2422 val = 0.0;
2424 (*opts)[i].value.u_timespec.tv_sec = val;
2425 (*opts)[i].value.u_timespec.tv_nsec =
2426 (val-(*opts)[i].value.u_timespec.tv_sec) * 1000000000.;
2428 break;
2429 #endif /* HAVE_STRUCT_TIMESPEC */
2431 #if HAVE_STRUCT_LINGER
2432 case TYPE_LINGER:
2433 if (!assign) {
2434 Error1("option \"%s\": value required", a0);
2435 continue;
2437 (*opts)[i].value.u_linger.l_onoff = 1;
2439 char *rest;
2440 (*opts)[i].value.u_linger.l_linger = Strtoul(token, &rest, 0, a0);
2442 Info3("setting option \"%s\" to {%d,%d}", ent->desc->defname,
2443 (*opts)[i].value.u_linger.l_onoff,
2444 (*opts)[i].value.u_linger.l_linger);
2445 break;
2446 #endif /* HAVE_STRUCT_LINGER */
2448 case TYPE_INT_INT:
2449 case TYPE_INT_INTP:
2450 if (!assign) {
2451 Error1("option \"%s\": values required", a0);
2452 continue;
2455 char *rest;
2456 (*opts)[i].value.u_int = strtoul(token, &rest, 0);
2457 if (token == rest) {
2458 Error1("parseopts(): missing numerical value of option \"%s\"", a0);
2460 if (*rest == '\0') {
2461 Error1("parseopts(): option \"%s\": 2 arguments required",
2462 ent->desc->defname);
2464 ++rest;
2465 (*opts)[i].value2.u_int = Strtoul(rest, &rest, 0, a0);
2467 Info3("setting option \"%s\" to %d:%d", ent->desc->defname,
2468 (*opts)[i].value.u_int, (*opts)[i].value2.u_int);
2469 break;
2471 case TYPE_INT_BIN:
2472 if (!assign) {
2473 Error1("option \"%s\": values required", a0);
2474 continue;
2477 char *rest;
2478 (*opts)[i].value.u_int = strtoul(token, &rest, 0);
2479 if (token == rest) {
2480 Error1("parseopts(): missing numerical value of option \"%s\"", a0);
2482 if (*rest != ':') {
2483 Error1("parseopts(): trailing garbage in numerical arg of option \"%s\"", a0);
2485 if (*rest == '\0') {
2486 Error1("parseopts(): option \"%s\": 2 arguments required",
2487 ent->desc->defname);
2489 ++rest;
2490 optlen = 0;
2491 if ((result = dalan(rest, optbuf, &optlen, sizeof(optbuf), 'i')) != 0) {
2492 Error1("parseopts_table(): problem with \"%s\" data", rest);
2493 continue;
2495 if (((*opts)[i].value2.u_bin.b_data = memdup(optbuf, optlen)) == NULL) {
2496 Error1("memdup(, "F_Zu"): out of memory", optlen);
2497 return -1;
2499 (*opts)[i].value2.u_bin.b_len = optlen;
2501 Info2("setting option \"%s\" to %d:..."/*!!!*/, ent->desc->defname,
2502 (*opts)[i].value.u_int);
2503 break;
2505 case TYPE_INT_STRING:
2506 if (!assign) {
2507 Error1("option \"%s\": values required", a0);
2508 continue;
2511 char *rest;
2512 (*opts)[i].value.u_int = strtoul(token, &rest, 0);
2513 if (token == rest) {
2514 Error1("parseopts(): missing numerical value of option \"%s\"", a0);
2516 if (*rest != ':') {
2517 Error1("parseopts(): trailing garbage in numerical arg of option \"%s\"", a0);
2519 if (*rest == '\0') {
2520 Error1("parseopts(): option \"%s\": 2 arguments required",
2521 ent->desc->defname);
2523 ++rest;
2524 if (((*opts)[i].value2.u_string = strdup(rest)) == NULL) {
2525 Error("out of memory"); return -1;
2528 Info3("setting option \"%s\" to %d:\"%s\"", ent->desc->defname,
2529 (*opts)[i].value.u_int, (*opts)[i].value2.u_string);
2530 break;
2532 case TYPE_INT_INT_INT:
2533 if (!assign) {
2534 Error1("option \"%s\": values required", a0);
2535 continue;
2538 char *rest;
2539 (*opts)[i].value.u_int = strtoul(token, &rest, 0);
2540 if (token == rest) {
2541 Error1("parseopts(): missing numerical value of option \"%s\"", a0);
2543 if (*rest == '\0') {
2544 Error1("parseopts(): option \"%s\": 3 arguments required", ent->desc->defname);
2546 if (*rest != ':') {
2547 Error1("parseopts(): trailing garbage in 1st numerical arg of option \"%s\"", a0);
2549 ++rest;
2550 (*opts)[i].value2.u_int = strtoul(rest, &rest, 0);
2551 if (token == rest) {
2552 Error1("parseopts(): missing numerical value of option \"%s\"", a0);
2554 if (*rest == '\0') {
2555 Error1("parseopts(): option \"%s\": 3 arguments required", ent->desc->defname);
2557 if (*rest != ':') {
2558 Error1("parseopts(): trailing garbage in 2nd numerical arg of option \"%s\"", a0);
2560 ++rest;
2561 (*opts)[i].value3.u_int = Strtoul(rest, &rest, 0, a0);
2563 Info4("setting option \"%s\" to %d:%d:%d", ent->desc->defname,
2564 (*opts)[i].value.u_int, (*opts)[i].value2.u_int, (*opts)[i].value3.u_int);
2565 break;
2567 case TYPE_INT_INT_BIN:
2568 case TYPE_INT_INT_GENERIC:
2569 if (!assign) {
2570 Error1("option \"%s\": values required", a0);
2571 continue;
2574 char *rest;
2575 (*opts)[i].value.u_int = strtoul(token, &rest, 0);
2576 if (token == rest) {
2577 Error1("parseopts(): missing numerical value of option \"%s\"", a0);
2579 if (*rest == '\0') {
2580 Error1("option \"%s\": 3 arguments required",
2581 ent->desc->defname);
2583 if (*rest != ':') {
2584 Error1("parseopts(): trailing garbage in 1st numerical arg of option \"%s\"", a0);
2586 ++rest;
2587 (*opts)[i].value2.u_int = strtoul(rest, &rest, 0);
2588 if (token == rest) {
2589 Error1("parseopts(): missing numerical value of option \"%s\"", a0);
2591 if (*rest == '\0') {
2592 Error1("option \"%s\": 3 arguments required",
2593 ent->desc->defname);
2595 if (*rest != ':') {
2596 Error1("parseopts(): trailing garbage in 2nd numerical arg of option \"%s\"", a0);
2598 ++rest;
2599 optlen = 0;
2600 if ((result = dalan(rest, optbuf, &optlen, sizeof(optbuf), 'i')) != 0) {
2601 Error1("parseopts_table(): problem with \"%s\" data", rest);
2602 continue;
2604 if (((*opts)[i].value3.u_bin.b_data = memdup(optbuf, optlen)) == NULL) {
2605 Error1("memdup(, "F_Zu"): out of memory", optlen);
2606 return -1;
2608 (*opts)[i].value3.u_bin.b_len = optlen;
2610 Info3("setting option \"%s\" to %d:%d:..."/*!!!*/, ent->desc->defname,
2611 (*opts)[i].value.u_int, (*opts)[i].value2.u_int);
2612 break;
2614 case TYPE_INT_INT_STRING:
2615 if (!assign) {
2616 Error1("option \"%s\": values required", a0);
2617 continue;
2620 char *rest;
2621 (*opts)[i].value.u_int = strtoul(token, &rest, 0);
2622 if (token == rest) {
2623 Error1("parseopts(): missing numerical value of option \"%s\"", a0);
2625 if (*rest == '\0') {
2626 Error1("parseopts(): option \"%s\": 3 arguments required",
2627 ent->desc->defname);
2629 if (*rest != ':') {
2630 Error1("parseopts(): trailing garbage in 1st numerical arg of option \"%s\"", a0);
2632 ++rest;
2633 (*opts)[i].value2.u_int = strtoul(rest, &rest, 0);
2634 if (token == rest) {
2635 Error1("parseopts(): missing numerical value of option \"%s\"", a0);
2637 if (*rest == '\0') {
2638 Error1("parseopts(): option \"%s\": 3 arguments required",
2639 ent->desc->defname);
2641 if (*rest != ':') {
2642 Error1("parseopts(): trailing garbage in 2nd numerical arg of option \"%s\"", a0);
2644 ++rest;
2645 if (((*opts)[i].value3.u_string = strdup(rest)) == NULL) {
2646 Error("out of memory"); return -1;
2649 Info4("setting option \"%s\" to %d:%d:\"%s\"", ent->desc->defname,
2650 (*opts)[i].value.u_int, (*opts)[i].value2.u_int,
2651 (*opts)[i].value3.u_string);
2652 break;
2654 #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)
2655 case TYPE_IP_MREQN:
2656 xiotype_ip_add_membership(token, ent, opt);
2657 break;
2658 #endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */
2660 #if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP)
2661 case TYPE_IP_MREQ_SOURCE:
2662 xiotype_ip_add_source_membership(token, ent, opt);
2663 break;
2664 #endif
2666 #if WITH_IP6 && HAVE_STRUCT_GROUP_SOURCE_REQ
2667 case TYPE_GROUP_SOURCE_REQ:
2668 xiotype_ip6_join_source_group(token, ent, opt);
2669 break;
2670 #endif
2672 #if WITH_IP4
2673 case TYPE_IP4NAME:
2675 /*! On a good day merge this with code in retropt_bind() */
2676 struct sockaddr_in sa; socklen_t salen = sizeof(sa);
2677 const char *ends[] = { NULL };
2678 const char *nests[] = { "[","]", NULL };
2679 char buff[512], *buffp=buff; size_t bufspc = sizeof(buff)-1;
2681 tokp = token;
2682 parsres =
2683 nestlex((const char **)&tokp, &buffp, &bufspc,
2684 ends, NULL, NULL, nests,
2685 true, false, false);
2686 if (parsres < 0) {
2687 Error1("option too long: \"%s\"", *a);
2688 return -1;
2689 } else if (parsres > 0) {
2690 Error1("syntax error in \"%s\"", *a);
2691 return -1;
2693 if (*tokp != '\0') {
2694 Error1("trailing data in option \"%s\"", token);
2696 *buffp = '\0';
2697 if (xioresolve(buff, NULL, AF_INET, SOCK_DGRAM, IPPROTO_IP,
2698 (union sockaddr_union *)&sa, &salen, NULL)
2699 != STAT_OK) {
2700 opt->desc = ODESC_ERROR; continue;
2702 opt->value.u_ip4addr = sa.sin_addr;
2704 break;
2705 case TYPE_IP4SOCK:
2707 /*! On a good day merge this with code for TYPE_IP4NAME */
2708 struct sockaddr_in sa; socklen_t salen = sizeof(sa);
2709 const char portsep[] = ":";
2710 const char *ends[] = { portsep, NULL };
2711 const char *nests[] = { "[","]", NULL };
2712 char hostname[512], *hostp = hostname, *portp = NULL;
2713 size_t hostlen = sizeof(hostname)-1;
2715 tokp = token;
2716 parsres =
2717 nestlex((const char **)&tokp, &hostp, &hostlen,
2718 ends, NULL, NULL, nests,
2719 true, false, false);
2720 if (parsres < 0) {
2721 Error1("option too long: \"%s\"", *a);
2722 return -1;
2723 } else if (parsres > 0) {
2724 Error1("syntax error in \"%s\"", *a);
2725 return -1;
2727 *hostp++ = '\0';
2728 if (!strncmp(tokp, portsep, strlen(portsep))) {
2729 portp = tokp + strlen(portsep);
2731 if (xioresolve(hostname, portp, AF_INET, SOCK_DGRAM, IPPROTO_IP,
2732 (union sockaddr_union *)&sa, &salen, 0)
2733 != STAT_OK) {
2734 opt->desc = ODESC_ERROR; continue;
2736 opt->value.u_ip4sock = sa;
2738 break;
2739 #endif /* defined(WITH_IP4) */
2741 #if LATER
2742 case TYPE_GENERIC:
2743 if (!assign) {
2744 (*opts)[i].value.u_int = 1;
2745 } else {
2746 int rc;
2747 size_t binlen = 64; /*!!!*/
2748 if (((*opts[i]).value.u_bin.b_data = Malloc(binlen)) == NULL) Error("!!!");
2749 (*opts)[i].value.u_bin.b_len = 0;
2750 rc = dalan(token, (*opts)[i].value.u_bin.b_data,
2751 &(*opts)[i].value.u_bin.b_len, binlen, 'i');
2752 if (rc != 0) {
2753 Error("!!!");
2755 //(*opts)[i].value.u_bin.b_len
2757 break;
2758 #endif /* LATER */
2760 default:
2761 Error2("parseopts_table(): internal error on option \"%s\": unimplemented type %d",
2762 ent->desc->defname, ent->desc->type);
2763 continue;
2766 ++i;
2767 if ((i % 8) == 0) {
2768 *opts = Realloc(*opts, (i+8) * sizeof(struct opt));
2769 if (*opts == NULL) {
2770 return -1;
2775 /*(*opts)[i+1].desc = ODESC_END;*/
2776 (*opts)[i].desc = ODESC_END;
2777 return 0;
2781 /* look for an option with the given properties
2782 return a pointer to the first matching valid option in the list
2783 Returns NULL when no matching option found */
2784 const struct opt *searchopt(const struct opt *opts, groups_t groups, enum e_phase from, enum e_phase to,
2785 enum e_func func) {
2786 int i;
2788 if (!opts) return NULL;
2790 /* remember: struct opt are in an array */
2791 i = 0;
2792 while (opts[i].desc != ODESC_END) {
2793 if (opts[i].desc != ODESC_DONE &&
2794 (groups == 0 || (groups && (opts[i].desc->group&groups))) &&
2795 (from == 0 || (from <= opts[i].desc->phase)) &&
2796 (to == 0 || (opts[i].desc->phase <= to)) &&
2797 (func == 0 || (opts[i].desc->func == func))) {
2798 return &opts[i];
2800 ++i;
2802 return NULL;
2805 /* copy the already parsed options for repeated application, but only those
2806 matching groups ANY and <groups> */
2807 struct opt *copyopts(const struct opt *opts, groups_t groups) {
2808 struct opt *new;
2809 int i, j, n;
2811 if (!opts) return NULL;
2813 /* just count the options in the array */
2814 i = 0; while (opts[i].desc != ODESC_END) {
2815 ++i;
2817 n = i+1;
2819 new = Malloc(n * sizeof(struct opt));
2820 if (new == NULL) {
2821 return NULL;
2824 i = 0, j = 0;
2825 while (i < n-1) {
2826 if (opts[i].desc == ODESC_DONE) {
2827 new[j].desc = ODESC_DONE;
2828 } else if ((opts[i].desc->group & (GROUP_ANY&~GROUP_PROCESS)) ||
2829 (opts[i].desc->group & groups)) {
2830 new[j++] = opts[i];
2832 ++i;
2834 new[j].desc = ODESC_END;
2835 return new;
2838 /* move options to a new options list
2839 move only those matching <groups> */
2840 struct opt *moveopts(struct opt *opts, groups_t groups) {
2841 struct opt *new;
2842 int i, j, n;
2844 if (!opts) return NULL;
2846 /* just count the options in the array */
2847 i = 0; j = 0; while (opts[i].desc != ODESC_END) {
2848 if (opts[i].desc != ODESC_DONE &&
2849 opts[i].desc != ODESC_ERROR)
2850 ++j;
2851 ++i;
2853 n = i;
2855 new = Malloc((j+1) * sizeof(struct opt));
2856 if (new == NULL) {
2857 return NULL;
2860 i = 0, j = 0;
2861 while (i < n) {
2862 if (opts[i].desc == ODESC_DONE ||
2863 opts[i].desc == ODESC_ERROR) {
2864 ++i; continue;
2865 } else if (opts[i].desc->group & groups) {
2866 new[j++] = opts[i];
2867 opts[i].desc = ODESC_DONE;
2869 ++i;
2871 new[j].desc = ODESC_END;
2872 return new;
2875 /* return the number of yet unconsumed options; -1 on error */
2876 int leftopts(const struct opt *opts) {
2877 const struct opt *opt = opts;
2878 int num = 0;
2880 if (!opts) return 0;
2882 while (opt->desc != ODESC_END) {
2883 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR) {
2884 ++num;
2886 ++opt;
2888 return num;
2891 /* show as warning which options are still unused */
2892 int showleft(const struct opt *opts) {
2893 const struct opt *opt = opts;
2895 while (opt->desc != ODESC_END) {
2896 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR) {
2897 Warn1("showleft(): option \"%s\" not inquired", opt->desc->defname);
2899 ++opt;
2901 return 0;
2905 /* determines the address group from mode_t */
2906 /* does not set GROUP_FD; cannot determine GROUP_TERMIOS ! */
2907 groups_t _groupbits(mode_t mode) {
2908 groups_t result = 0;
2910 switch ((mode&S_IFMT)>>12) {
2911 case (S_IFIFO>>12): /* 1, FIFO */
2912 result = GROUP_FIFO; break;
2913 case (S_IFCHR>>12): /* 2, character device */
2914 result = GROUP_CHR|GROUP_TERMIOS; break;
2915 case (S_IFDIR>>12): /* 4, directory !!! not supported */
2916 result = GROUP_NONE; break;
2917 case (S_IFBLK>>12): /* 6, block device */
2918 result = GROUP_BLK; break;
2919 case (S_IFREG>>12): /* 8, regular file */
2920 result = GROUP_REG; break;
2921 case (S_IFLNK>>12): /* 10, symbolic link !!! not supported */
2922 result = GROUP_NONE; break;
2923 #ifdef S_IFSOCK
2924 case (S_IFSOCK>>12): /* 12, socket */
2925 result = GROUP_SOCKET|GROUP_SOCK_UNIX; break;
2926 #else
2927 default: /* some systems (pure POSIX.1) do not know S_IFSOCK */
2928 result = GROUP_SOCKET|GROUP_SOCK_UNIX; break;
2929 #endif
2931 Debug2("_groupbits("F_mode") -> "F_groups_t, mode, result);
2932 return result;
2935 /* does not set GROUP_FD */
2936 groups_t groupbits(int fd) {
2937 #if HAVE_STAT64
2938 struct stat64 buf;
2939 #else
2940 struct stat buf;
2941 #endif /* !HAVE_STAT64 */
2942 groups_t result;
2944 if (
2945 #if HAVE_STAT64
2946 Fstat64(fd, &buf) < 0
2947 #else
2948 Fstat(fd, &buf) < 0
2949 #endif /* !HAVE_STAT64 */
2951 Error4("groupbits(%d): fstat(%d, %p): %s",
2952 fd, fd, &buf, strerror(errno));
2953 return -1;
2955 result = _groupbits(buf.st_mode&S_IFMT);
2956 if (result == GROUP_CHR) {
2957 if (Isatty(fd) > 0) {
2958 result |= GROUP_TERMIOS;
2961 return result;
2964 #if 0 /* currently not used */
2965 int retropt(struct opt *opts, int optcode, union integral *result) {
2966 struct opt *opt = opts;
2968 while (opt->desc != ODESC_END) {
2969 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
2970 opt->desc->optcode == optcode) {
2971 *result = opt->value;
2972 opt->desc = ODESC_DONE;
2973 return 0;
2975 ++opt;
2977 return -1;
2979 #endif
2981 static struct opt *xio_findopt(struct opt *opts, int optcode) {
2982 struct opt *opt = opts;
2984 while (opt->desc != ODESC_END) {
2985 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
2986 opt->desc->optcode == optcode) {
2987 return opt;
2989 ++opt;
2991 return NULL;
2994 int retropt_timespec(struct opt *opts, int optcode, struct timespec *result) {
2995 struct opt *opt;
2997 if (!(opt = xio_findopt(opts, optcode))) {
2998 return -1;
3000 *result = opt->value.u_timespec;
3001 opt->desc = ODESC_DONE;
3002 return 0;
3006 /* Looks for the first option of type <optcode>. If the option is found,
3007 this function stores its bool value in *result, "consumes" the
3008 option, and returns 0.
3009 If the option is not found, *result is not modified, and -1 is returned. */
3010 int retropt_bool(struct opt *opts, int optcode, bool *result) {
3011 struct opt *opt = opts;
3013 while (opt->desc != ODESC_END) {
3014 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
3015 opt->desc->optcode == optcode) {
3016 *result = opt->value.u_bool;
3017 opt->desc = ODESC_DONE;
3018 return 0;
3020 ++opt;
3022 return -1;
3025 #if 0 /* currently not used */
3026 /* Looks for the first option of type <optcode>. If the option is found,
3027 this function stores its short value in *result, "consumes" the
3028 option, and returns 0.
3029 If the option is not found, *result is not modified, and -1 is returned. */
3030 int retropt_short(struct opt *opts, int optcode, short *result) {
3031 struct opt *opt = opts;
3033 while (opt->desc != ODESC_END) {
3034 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
3035 opt->desc->optcode == optcode) {
3036 *result = opt->value.u_short;
3037 opt->desc = ODESC_DONE;
3038 return 0;
3040 ++opt;
3042 return -1;
3044 #endif
3046 /* Looks for the first option of type <optcode>. If the option is found,
3047 this function stores its unsigned short value in *result, "consumes" the
3048 option, and returns 0.
3049 If the option is not found, *result is not modified, and -1 is returned. */
3050 int retropt_ushort(struct opt *opts, int optcode, unsigned short *result) {
3051 struct opt *opt = opts;
3053 while (opt->desc != ODESC_END) {
3054 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
3055 opt->desc->optcode == optcode) {
3056 *result = opt->value.u_ushort;
3057 opt->desc = ODESC_DONE;
3058 return 0;
3060 ++opt;
3062 return -1;
3065 /* Looks for the first option of type <optcode>. If the option is found,
3066 this function stores its int value in *result, "consumes" the
3067 option, and returns 0.
3068 If the option is not found, *result is not modified, and -1 is returned. */
3069 int retropt_int(struct opt *opts, int optcode, int *result) {
3070 struct opt *opt = opts;
3072 while (opt->desc != ODESC_END) {
3073 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
3074 opt->desc->optcode == optcode) {
3075 char *rest;
3076 switch (opt->desc->type) {
3077 case TYPE_INT: *result = opt->value.u_int; break;
3078 case TYPE_STRING: *result = strtol(opt->value.u_string, &rest, 0);
3079 if (*rest != '\0') {
3080 Error1("retropts_int(): trailing garbage in numerical arg of option \"%s\"",
3081 opt->desc->defname);
3083 break;
3084 default: Error2("cannot convert type %d of option %s to int",
3085 opt->desc->type, opt->desc->defname);
3086 opt->desc = ODESC_ERROR;
3087 return -1;
3089 opt->desc = ODESC_DONE;
3090 return 0;
3092 ++opt;
3094 return -1;
3097 /* Looks for the first option of type <optcode>. If the option is found,
3098 this function stores its int value in *result, "consumes" the
3099 option, and returns 0.
3100 If the option is not found, *result is not modified, and -1 is returned. */
3101 int retropt_2integrals(struct opt *opts, int optcode,
3102 union integral *value1, union integral *value2)
3104 struct opt *opt = opts;
3106 while (opt->desc != ODESC_END) {
3107 if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
3108 switch (opt->desc->type) {
3109 case TYPE_INT_NULL:
3110 /* ...and many more types */
3111 *value1 = opt->value;
3112 *value2 = opt->value2;
3113 break;
3114 default: Error2("cannot convert type %d of option %s to int/NULL",
3115 opt->desc->type, opt->desc->defname);
3116 opt->desc = ODESC_ERROR;
3117 return -1;
3119 opt->desc = ODESC_DONE;
3120 return 0;
3122 ++opt;
3124 return -1;
3127 /* Looks for the first option of type <optcode>. If the option is found,
3128 this function stores its unsigned int value in *result, "consumes" the
3129 option, and returns 0.
3130 If the option is not found, *result is not modified, and -1 is returned. */
3131 int retropt_uint(struct opt *opts, int optcode, unsigned int *result) {
3132 struct opt *opt = opts;
3134 while (opt->desc != ODESC_END) {
3135 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
3136 opt->desc->optcode == optcode) {
3137 *result = opt->value.u_uint;
3138 opt->desc = ODESC_DONE;
3139 return 0;
3141 ++opt;
3143 return -1;
3146 /* Looks for the first option of type <optcode>. If the option is found,
3147 this function stores its long value in *result, "consumes" the option,
3148 and returns 0.
3149 If the option is not found, *result is not modified, and -1 is returned. */
3150 int retropt_long(struct opt *opts, int optcode, long *result) {
3151 struct opt *opt = opts;
3153 while (opt->desc != ODESC_END) {
3154 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
3155 opt->desc->optcode == optcode) {
3156 *result = opt->value.u_long;
3157 opt->desc = ODESC_DONE;
3158 return 0;
3160 ++opt;
3162 return -1;
3165 /* Looks for the first option of type <optcode>. If the option is found,
3166 this function stores its unsigned long value in *result, "consumes" the
3167 option, and returns 0.
3168 If the option is not found, *result is not modified, and -1 is returned. */
3169 int retropt_ulong(struct opt *opts, int optcode, unsigned long *result) {
3170 struct opt *opt = opts;
3172 while (opt->desc != ODESC_END) {
3173 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
3174 opt->desc->optcode == optcode) {
3175 *result = opt->value.u_ulong;
3176 opt->desc = ODESC_DONE;
3177 return 0;
3179 ++opt;
3181 return -1;
3184 #if 0 /* currently not used */
3185 /* get the value of a FLAG typed option, and apply it to the appropriate
3186 bit position. Mark the option as consumed (done). return 0 if options was found and successfully applied,
3187 or -1 if option was not in opts */
3188 int retropt_flag(struct opt *opts, int optcode, flags_t *result) {
3189 struct opt *opt = opts;
3191 while (opt->desc != ODESC_END) {
3192 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
3193 opt->desc->optcode == optcode) {
3194 if (opt->value.u_bool) {
3195 *result |= opt->desc->major;
3196 } else {
3197 *result &= ~opt->desc->major;
3199 opt->desc = ODESC_DONE;
3200 return 0;
3202 ++opt;
3204 return -1;
3206 #endif
3208 /* Looks for the first option of type <optcode>. If the option is found,
3209 this function stores its character pointer value in *result, "consumes" the
3210 option, and returns 0. Note that, for options of type STRING_NULL, the
3211 character pointer might degenerate to NULL.
3212 The resulting string is malloc'ed and should be freed after use.
3213 If the option is not found, *result is not modified, and -1 is returned.
3215 int retropt_string(struct opt *opts, int optcode, char **result) {
3216 struct opt *opt = opts;
3218 while (opt->desc != ODESC_END) {
3219 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
3220 opt->desc->optcode == optcode) {
3221 if (opt->value.u_string == NULL) {
3222 *result = NULL;
3223 } else if ((*result = strdup(opt->value.u_string)) == NULL) {
3224 Error1("strdup("F_Zu"): out of memory",
3225 strlen(opt->value.u_string));
3226 return -1;
3228 opt->desc = ODESC_DONE;
3229 return 0;
3231 ++opt;
3233 return -1;
3237 #if _WITH_SOCKET
3238 /* looks for a bind option and, if found, overwrites the complete contents of
3239 sa with the appropriate value(s).
3240 returns STAT_OK if option exists and could be resolved,
3241 STAT_NORETRY if option exists but had error,
3242 or STAT_NOACTION if it does not exist */
3243 /* currently only for IP (v4, v6) and raw (PF_UNSPEC) */
3244 int retropt_bind(struct opt *opts,
3245 int af,
3246 int socktype,
3247 int ipproto,
3248 struct sockaddr *sa,
3249 socklen_t *salen,
3250 int feats, /* TCP etc: 1..address allowed,
3251 3..address and port allowed
3252 UNIX (or'd): 1..tight
3253 2..abstract
3254 4..templatename
3256 const int ai_flags[2])
3258 const char portsep[] = ":";
3259 const char *ends[] = { portsep, NULL };
3260 const char *nests[] = { "[", "]", NULL };
3261 bool portallowed;
3262 char *bindname, *bindp;
3263 char hostname[512], *hostp = hostname, *portp = NULL;
3264 size_t hostlen = sizeof(hostname)-1;
3265 int parsres;
3266 int ai_flags2[2];
3267 int result;
3269 if (retropt_string(opts, OPT_BIND, &bindname) < 0) {
3270 return STAT_NOACTION;
3272 bindp = bindname;
3274 switch (af) {
3276 case AF_UNSPEC:
3278 size_t p = 0;
3279 dalan(bindname, (uint8_t *)sa->sa_data, &p, *salen-sizeof(sa->sa_family), 'i');
3280 *salen = p + sizeof(sa->sa_family);
3281 *salen = p +
3282 #if HAVE_STRUCT_SOCKADDR_SALEN
3283 sizeof(sa->sa_len) +
3284 #endif
3285 sizeof(sa->sa_family);
3286 #if HAVE_STRUCT_SOCKADDR_SALEN
3287 sa->sa_len = *salen;
3288 #endif
3290 break;
3292 #if WITH_IP4 || WITH_IP6 || WITH_VSOCK
3293 #if WITH_VSOCK
3294 case AF_VSOCK:
3295 #endif
3296 #if WITH_IP4
3297 case AF_INET:
3298 #endif
3299 #if WITH_IP6
3300 case AF_INET6:
3301 #endif /*WITH_IP6 */
3302 portallowed = (feats>=2);
3303 parsres =
3304 nestlex((const char **)&bindp, &hostp, &hostlen, ends, NULL, NULL, nests,
3305 true, false, false);
3306 if (parsres < 0) {
3307 Error1("option too long: \"%s\"", bindp);
3308 return STAT_NORETRY;
3309 } else if (parsres > 0) {
3310 Error1("syntax error in \"%s\"", bindp);
3311 return STAT_NORETRY;
3313 *hostp++ = '\0';
3314 if (!strncmp(bindp, portsep, strlen(portsep))) {
3315 if (!portallowed) {
3316 Error("port specification not allowed in this bind option");
3317 return STAT_NORETRY;
3318 } else {
3319 portp = bindp + strlen(portsep);
3323 /* Set AI_PASSIVE, except when it is explicitely disabled */
3324 ai_flags2[0] = ai_flags[0];
3325 ai_flags2[1] = ai_flags[1];
3326 if (!(ai_flags2[1] & AI_PASSIVE))
3327 ai_flags2[0] |= AI_PASSIVE;
3329 if ((result =
3330 xioresolve(hostname[0]!='\0'?hostname:NULL, portp,
3331 af, socktype, ipproto,
3332 (union sockaddr_union *)sa, salen, ai_flags2))
3333 != STAT_OK) {
3334 Error("error resolving bind option");
3335 return STAT_NORETRY;
3337 break;
3338 #endif /* WITH_IP4 || WITH_IP6 */
3340 #if WITH_UNIX
3341 case AF_UNIX:
3343 bool abstract = (feats&2);
3344 bool tight = (feats&1);
3345 bool templatename = (feats&4);
3346 struct sockaddr_un *s_un = (struct sockaddr_un *)sa;
3347 if (templatename) {
3348 int i = 0;
3349 srandom(getpid());
3350 for (; i < strlen(bindname); i++) {
3351 if (bindname[i] == 'X') {
3352 bindname[i] = 'a' + (char) (random() % ('z' - 'a'));
3356 *salen = xiosetunix(af, s_un, bindname, abstract, tight);
3358 break;
3359 #endif /* WITH_UNIX */
3361 default:
3362 Error1("bind: unknown address family %d", af);
3363 return STAT_NORETRY;
3365 return STAT_OK;
3367 #endif /* _WITH_SOCKET */
3370 int applyopt_seek32(
3371 int fd,
3372 struct opt *opt)
3374 if (Lseek(fd, opt->value.u_off, opt->desc->major) < 0) {
3375 Error4("lseek(%d, "F_off", %d): %s",
3376 fd, opt->value.u_off, opt->desc->major, strerror(errno));
3377 return -1;
3379 return 0;
3382 #if HAVE_LSEEK64
3383 int applyopt_seek64(
3384 int fd,
3385 struct opt *opt)
3387 /*! this depends on off64_t atomic type */
3388 if (Lseek64(fd, opt->value.u_off64, opt->desc->major) < 0) {
3389 Error4("lseek64(%d, "F_off64", %d): %s",
3390 fd, opt->value.u_off64, opt->desc->major,
3391 strerror(errno));
3392 return -1;
3394 return 0;
3396 #endif /* HAVE_LSEEK64 */
3398 int applyopt_fcntl(
3399 int fd,
3400 struct opt *opt)
3402 int flag;
3404 if (opt->desc->type == TYPE_BOOL) {
3405 /* Retrieve existing flag settings */
3406 if ((flag = Fcntl(fd, opt->desc->major-1)) < 0) {
3407 Error3("fcntl(%d, %d): %s",
3408 fd, opt->desc->major, strerror(errno));
3409 return -1;
3411 if (opt->value.u_bool) {
3412 flag |= opt->desc->minor;
3413 } else {
3414 flag &= ~opt->desc->minor;
3416 if (Fcntl_i(fd, opt->desc->major, flag) < 0) {
3417 Error4("fcntl(%d, %d, 0x%x): %s",
3418 fd, opt->desc->major, flag, strerror(errno));
3419 return -1;
3422 } else if (opt->desc->type == TYPE_INT) {
3423 if (Fcntl_i(fd, opt->desc->major, opt->value.u_int) < 0) {
3424 Error4("fcntl(%d, %d, 0x%x): %s",
3425 fd, opt->desc->major, opt->value.u_int, strerror(errno));
3426 return -1;
3428 } else {
3429 Error2("applyopt_fcntl(\"%s\", ...): INTERNAL: type %d not implemented",
3430 opt->desc->defname, opt->desc->type);
3431 return -1;
3433 return 0;
3436 int applyopt_ioctl(
3437 int fd,
3438 struct opt *opt)
3440 if (Ioctl(fd, opt->desc->major, (void *)&opt->value) < 0) {
3441 Error4("ioctl(%d, 0x%x, %p): %s",
3442 fd, opt->desc->major, (void *)&opt->value, strerror(errno));
3443 return -1;
3445 return 0;
3448 int applyopt_ioctl_mask_long(
3449 int fd,
3450 struct opt *opt)
3452 long val;
3453 int getreq = opt->desc->major;
3454 int setreq = opt->desc->minor;
3455 long mask = opt->desc->arg3;
3457 if (Ioctl(fd, getreq, (void *)&val) < 0) {
3458 Error4("ioctl(%d, 0x%x, %p): %s",
3459 fd, opt->desc->major, (void *)&val, strerror(errno));
3460 return -1;
3462 val &= ~mask;
3463 if (opt->value.u_bool)
3464 val |= mask;
3465 if (Ioctl(fd, setreq, (void *)&val) < 0) {
3466 Error4("ioctl(%d, 0x%x, %p): %s",
3467 fd, opt->desc->major, (void *)&val, strerror(errno));
3468 return -1;
3470 return 0;
3473 int applyopt_ioctl_generic(
3474 int fd,
3475 struct opt *opt)
3477 switch (opt->desc->type) {
3478 case TYPE_INT:
3479 if (Ioctl(fd, opt->value.u_int, NULL) < 0) {
3480 Error3("ioctl(%d, 0x%x, NULL): %s",
3481 fd, opt->value.u_int, strerror(errno));
3482 return -1;
3484 break;
3485 case TYPE_INT_INT:
3486 if (Ioctl_int(fd, opt->value.u_int, opt->value2.u_int) < 0) {
3487 Error4("ioctl(%d, 0x%x, 0x%x): %s",
3488 fd, opt->value.u_int, opt->value2.u_int, strerror(errno));
3489 return -1;
3491 break;
3492 case TYPE_INT_INTP:
3493 if (Ioctl(fd, opt->value.u_int, (void *)&opt->value2.u_int) < 0) {
3494 Error4("ioctl(%d, 0x%x, %p): %s",
3495 fd, opt->value.u_int, (void *)&opt->value2.u_int, strerror(errno));
3496 return -1;
3498 break;
3499 case TYPE_INT_BIN:
3500 if (Ioctl(fd, opt->value.u_int, (void *)opt->value2.u_bin.b_data) < 0) {
3501 Error4("ioctl(%d, 0x%x, %p): %s",
3502 fd, opt->value.u_int, (void *)opt->value2.u_bin.b_data, strerror(errno));
3503 return -1;
3505 break;
3506 case TYPE_INT_STRING:
3507 if (Ioctl(fd, opt->value.u_int, (void *)opt->value2.u_string) < 0) {
3508 Error4("ioctl(%d, 0x%x, %p): %s",
3509 fd, opt->value.u_int, (void *)opt->value2.u_string, strerror(errno));
3510 return -1;
3512 break;
3513 default:
3514 Error3("%s(opt:%s) data type %d not implemented",
3515 __func__, opt->desc->defname, opt->desc->type);
3516 return -1;
3518 return 0;
3521 int applyopt_sockopt(
3522 int fd,
3523 struct opt *opt)
3525 #if 0 && HAVE_STRUCT_LINGER
3526 if (opt->desc->optcode == OPT_SO_LINGER) {
3527 struct linger lingstru;
3528 lingstru.l_onoff = (opt->value.u_int>=0 ? 1 : 0);
3529 lingstru.l_linger = opt->value.u_int;
3530 if (Setsockopt(fd, opt->desc->major, opt->desc->minor, &lingstru,
3531 sizeof(lingstru)) < 0) {
3532 Error6("setsockopt(%d, %d, %d, {%d,%d}, "F_Zu,
3533 fd, opt->desc->major, opt->desc->minor, lingstru.l_onoff,
3534 lingstru.l_linger, sizeof(lingstru));
3535 return -1;
3538 return 0;
3539 #endif /* HAVE_STRUCT_LINGER */
3541 switch (opt->desc->type) {
3542 case TYPE_BIN:
3543 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3544 opt->value.u_bin.b_data, opt->value.u_bin.b_len)
3545 < 0) {
3546 Error6("setsockopt(%d, %d, %d, %p, "F_Zu"): %s",
3547 fd, opt->desc->major, opt->desc->minor,
3548 opt->value.u_bin.b_data, opt->value.u_bin.b_len,
3549 strerror(errno));
3550 return -1;
3552 break;
3553 case TYPE_BOOL:
3554 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3555 &opt->value.u_bool, sizeof(opt->value.u_bool))
3556 < 0) {
3557 Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu"): %s", fd,
3558 opt->desc->major, opt->desc->minor,
3559 opt->value.u_bool, sizeof(opt->value.u_bool),
3560 strerror(errno));
3561 return -1;
3563 break;
3564 case TYPE_BYTE:
3565 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3566 &opt->value.u_byte, sizeof(uint8_t)) < 0) {
3567 Error6("setsockopt(%d, %d, %d, {%u}, "F_Zu"): %s",
3568 fd, opt->desc->major, opt->desc->minor,
3569 opt->value.u_byte, sizeof(uint8_t), strerror(errno));
3570 return -1;
3572 break;
3573 case TYPE_INT:
3574 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3575 &opt->value.u_int, sizeof(int)) < 0) {
3576 Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu"): %s",
3577 fd, opt->desc->major, opt->desc->minor,
3578 opt->value.u_int, sizeof(int), strerror(errno));
3579 return -1;
3581 break;
3582 case TYPE_INT_NULL:
3583 if (opt->value2.u_bool &&
3584 Setsockopt(fd, opt->desc->major, opt->desc->minor,
3585 &opt->value.u_int, sizeof(int)) < 0) {
3586 Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu"): %s",
3587 fd, opt->desc->major, opt->desc->minor,
3588 opt->value.u_int, sizeof(int), strerror(errno));
3589 return -1;
3591 break;
3592 case TYPE_LONG:
3593 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3594 &opt->value.u_long, sizeof(long)) < 0) {
3595 Error6("setsockopt(%d, %d, %d, {%ld}, "F_Zu"): %s",
3596 fd, opt->desc->major, opt->desc->minor,
3597 opt->value.u_long, sizeof(long), strerror(errno));
3598 return -1;
3600 break;
3601 case TYPE_STRING:
3602 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3603 opt->value.u_string,
3604 strlen(opt->value.u_string)+1) < 0) {
3605 Error6("setsockopt(%d, %d, %d, \"%s\", "F_Zu"): %s",
3606 fd, opt->desc->major, opt->desc->minor,
3607 opt->value.u_string, strlen(opt->value.u_string)+1,
3608 strerror(errno));
3609 return -1;
3611 break;
3612 case TYPE_UINT:
3613 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3614 &opt->value.u_uint, sizeof(unsigned int)) < 0) {
3615 Error6("setsockopt(%d, %d, %d, {%u}, "F_Zu"): %s",
3616 fd, opt->desc->major, opt->desc->minor,
3617 opt->value.u_uint, sizeof(unsigned int),
3618 strerror(errno));
3619 return -1;
3621 break;
3622 case TYPE_TIMEVAL:
3623 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3624 &opt->value.u_timeval, sizeof(struct timeval)) < 0) {
3625 Error7("setsockopt(%d, %d, %d, {%ld,%ld}, "F_Zu"): %s",
3626 fd, opt->desc->major, opt->desc->minor,
3627 opt->value.u_timeval.tv_sec, opt->value.u_timeval.tv_usec,
3628 sizeof(struct timeval), strerror(errno));
3629 return -1;
3631 break;
3632 #if HAVE_STRUCT_LINGER
3633 case TYPE_LINGER:
3635 struct linger lingstru;
3636 lingstru.l_onoff = (opt->value.u_linger.l_onoff>=0 ? 1 : 0);
3637 lingstru.l_linger = opt->value.u_linger.l_linger;
3638 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3639 &lingstru, sizeof(lingstru)) < 0) {
3640 Error6("setsockopt(%d, %d, %d, {%d,%d}): %s",
3641 fd, opt->desc->major, opt->desc->minor,
3642 lingstru.l_onoff, lingstru.l_linger,
3643 strerror(errno));
3644 return -1;
3647 break;
3648 #endif /* HAVE_STRUCT_LINGER */
3649 #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)
3650 case TYPE_IP_MREQN:
3651 /* handled in applyopts_single */
3652 break;
3653 #endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */
3655 #if defined(HAVE_STRUCT_GROUP_SOURCE_REQ)
3656 case TYPE_GROUP_SOURCE_REQ:
3657 /* handled in applyopts_single */
3658 break;
3659 #endif /* defined(HAVE_STRUCT_GROUP_SOURCE_REQ) */
3661 /*! still many types missing; implement on demand */
3662 #if WITH_IP4
3663 case TYPE_IP4NAME:
3664 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3665 &opt->value.u_ip4addr, sizeof(opt->value.u_ip4addr)) < 0) {
3666 Error6("setsockopt(%d, %d, %d, {0x%x}, "F_Zu"): %s",
3667 fd, opt->desc->major, opt->desc->minor,
3668 *(uint32_t *)&opt->value.u_ip4addr, sizeof(opt->value.u_ip4addr),
3669 strerror(errno));
3670 return -1;
3672 break;
3673 #endif /* defined(WITH_IP4) */
3674 default:
3675 #if !NDEBUG
3676 Error3("%s(opt:\"%s\"): type %d no implemented",
3677 __func__, opt->desc->defname, opt->desc->type);
3678 #else
3679 Warn3("%s(opt:\"%s\"): type %d no implemented",
3680 __func__, opt->desc->defname, opt->desc->type);
3681 #endif
3682 return -1;
3684 return 0;
3687 /* Appends the provided data to the current value of this sockopt.
3688 Used (e.g.) for IP_OPTIONS.
3690 int applyopt_sockopt_append(
3691 int fd,
3692 struct opt *opt)
3694 switch (opt->desc->type) {
3695 uint8_t data[256];
3696 socklen_t oldlen, newlen;
3697 case TYPE_BIN:
3698 oldlen = sizeof(data);
3699 if (Getsockopt(fd, opt->desc->major, opt->desc->minor,
3700 data, &oldlen)
3701 < 0) {
3702 Error6("getsockopt(%d, %d, %d, %p, {"F_socklen"}): %s",
3703 fd, opt->desc->major, opt->desc->minor, data, oldlen,
3704 strerror(errno));
3705 return -1;
3707 memcpy(&data[oldlen], opt->value.u_bin.b_data,
3708 MIN(opt->value.u_bin.b_len, sizeof(data)-oldlen));
3709 newlen = oldlen + MIN(opt->value.u_bin.b_len, sizeof(data)-oldlen);
3710 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3711 data, newlen)
3712 < 0) {
3713 Error6("setsockopt(%d, %d, %d, %p, %d): %s",
3714 fd, opt->desc->major, opt->desc->minor, data, newlen,
3715 strerror(errno));
3716 return -1;
3718 break;
3719 default:
3720 Error2("internal: option \"%s\": unimplemented type %d",
3721 opt->desc->defname, opt->desc->type);
3722 break;
3724 return 0;
3727 int applyopt_sockopt_generic(
3728 int fd,
3729 struct opt *opt)
3731 switch (opt->desc->type) {
3732 case TYPE_INT_INT_INT:
3733 if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int,
3734 &opt->value3.u_int, sizeof(int)) < 0) {
3735 Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu"): %s",
3736 fd, opt->value.u_int, opt->value2.u_int,
3737 opt->value3.u_int, sizeof(int), strerror(errno));
3738 return -1;
3740 break;
3741 case TYPE_INT_INT_BIN:
3742 if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int,
3743 opt->value3.u_bin.b_data, opt->value3.u_bin.b_len) < 0) {
3744 Error5("setsockopt(%d, %d, %d, {...}, "F_Zu"): %s",
3745 fd, opt->value.u_int, opt->value2.u_int,
3746 opt->value3.u_bin.b_len, strerror(errno));
3747 return -1;
3749 break;
3750 case TYPE_INT_INT_STRING:
3751 if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int,
3752 opt->value3.u_string,
3753 strlen(opt->value3.u_string)+1) < 0) {
3754 Error6("setsockopt(%d, %d, %d, \"%s\", "F_Zu"): %s",
3755 fd, opt->value.u_int, opt->value2.u_int,
3756 opt->value3.u_string, strlen(opt->value3.u_string)+1,
3757 strerror(errno));
3758 return -1;
3760 break;
3761 default:
3762 Error3("%s(opt:\"%s\"): INTERNAL: data type %d not implemented",
3763 __func__, opt->desc->defname, opt->desc->type);
3764 return -1;
3766 return 0;
3769 int applyopt_flock(
3770 int fd,
3771 struct opt *opt)
3773 if (Flock(fd, opt->desc->major) < 0) {
3774 Error3("flock(%d, %d): %s",
3775 fd, opt->desc->major, strerror(errno));
3776 return -1;
3778 return 0;
3781 /* Applies an option that needs handling specific to its OPT_* setting.
3782 Does not overwrite the option instance with ODESC_DONE or ODESC_ERROR,
3783 instead:
3784 Returns 0 if option was just applied (caller has to ODESC_DONE);
3785 returns -1 if a problem occurred (caller has to ODESC_ERROR);
3786 returns 1 if the instance has to be kept, this happens when the option desc has
3787 been overwritten to, e.g., undo the option in a later phase. */
3788 int applyopt_spec(
3789 struct single *sfd,
3790 int fd,
3791 struct opt *opt)
3793 if (fd < 0 && sfd != NULL)
3794 fd = sfd->fd;
3796 switch (opt->desc->optcode) {
3797 case OPT_USER:
3798 case OPT_USER_LATE:
3799 if (Fchown(fd, opt->value.u_uidt, -1) < 0) {
3800 Error3("fchown(%d, "F_uid", -1): %s",
3801 fd, opt->value.u_uidt, strerror(errno));
3802 return -1;
3804 break;
3805 case OPT_GROUP:
3806 case OPT_GROUP_LATE:
3807 if (Fchown(fd, -1, opt->value.u_gidt) < 0) {
3808 Error3("fchown(%d, -1, "F_gid"): %s",
3809 fd, opt->value.u_gidt, strerror(errno));
3810 return -1;
3812 break;
3813 case OPT_PERM:
3814 case OPT_PERM_LATE:
3815 if (Fchmod(fd, opt->value.u_modet) < 0) {
3816 Error3("fchmod(%d, %u): %s",
3817 fd, opt->value.u_modet, strerror(errno));
3818 return -1;
3820 break;
3821 case OPT_FTRUNCATE32:
3822 if (Ftruncate(fd, opt->value.u_off) < 0) {
3823 Error3("ftruncate(%d, "F_off"): %s",
3824 fd, opt->value.u_off, strerror(errno));
3825 return -1;
3827 break;
3828 #if HAVE_FTRUNCATE64
3829 case OPT_FTRUNCATE64:
3830 if (Ftruncate64(fd, opt->value.u_off64) < 0) {
3831 Error3("ftruncate64(%d, "F_off64"): %s",
3832 fd, opt->value.u_off64, strerror(errno));
3833 return -1;
3835 #endif /* HAVE_FTRUNCATE64 */
3836 break;
3837 case OPT_F_SETLK_RD:
3838 case OPT_F_SETLK_WR:
3839 case OPT_F_SETLKW_RD:
3840 case OPT_F_SETLKW_WR:
3842 struct flock l; /* Linux: <asm/fcntl.h> */
3843 l.l_type = opt->desc->minor;
3844 l.l_whence = SEEK_SET;
3845 l.l_start = 0;
3846 l.l_len = LONG_MAX;
3847 l.l_pid = 0; /* hope this uses our current process */
3848 if (Fcntl_lock(fd, opt->desc->major, &l) < 0) {
3849 Error3("fcntl(%d, %d, {type=F_WRLCK,whence=SEEK_SET,start=0,len=LONG_MAX,pid=0}): %s", fd, opt->desc->major, strerror(errno));
3850 return -1;
3853 break;
3854 case OPT_SETUID_EARLY:
3855 case OPT_SETUID:
3856 if (Setuid(opt->value.u_uidt) < 0) {
3857 Error2("setuid("F_uid"): %s", opt->value.u_uidt,
3858 strerror(errno));
3859 return -1;
3861 break;
3862 case OPT_SETGID_EARLY:
3863 case OPT_SETGID:
3864 if (Setgid(opt->value.u_gidt) < 0) {
3865 Error2("setgid("F_gid"): %s", opt->value.u_gidt,
3866 strerror(errno));
3867 return -1;
3869 break;
3870 case OPT_SUBSTUSER_EARLY:
3871 case OPT_SUBSTUSER:
3873 struct passwd *pwd;
3874 if ((pwd = getpwuid(opt->value.u_uidt)) == NULL) {
3875 Error1("getpwuid("F_uid"): no such user",
3876 opt->value.u_uidt);
3877 return -1;
3879 if (Initgroups(pwd->pw_name, pwd->pw_gid) < 0) {
3880 Error3("initgroups(%s, "F_gid"): %s",
3881 pwd->pw_name, pwd->pw_gid, strerror(errno));
3882 return -1;
3884 if (Setgid(pwd->pw_gid) < 0) {
3885 Error2("setgid("F_gid"): %s", pwd->pw_gid,
3886 strerror(errno));
3887 return -1;
3889 if (Setuid(opt->value.u_uidt) < 0) {
3890 Error2("setuid("F_uid"): %s", opt->value.u_uidt,
3891 strerror(errno));
3892 return -1;
3894 #if 1
3895 if (setenv("USER", pwd->pw_name, 1) < 0) {
3896 Error1("setenv(\"USER\", \"%s\", 1): insufficient space",
3897 pwd->pw_name);
3898 return -1;
3900 if (setenv("LOGNAME", pwd->pw_name, 1) < 0) {
3901 Error1("setenv(\"LOGNAME\", \"%s\", 1): insufficient space",
3902 pwd->pw_name);
3903 return -1;
3905 if (setenv("HOME", pwd->pw_dir, 1) < 0) {
3906 Error1("setenv(\"HOME\", \"%s\", 1): insufficient space",
3907 pwd->pw_dir);
3908 return -1;
3910 if (setenv("SHELL", pwd->pw_shell, 1) < 0) {
3911 Error1("setenv(\"SHELL\", \"%s\", 1): insufficient space",
3912 pwd->pw_shell);
3913 return -1;
3915 #endif
3917 break;
3918 #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
3919 case OPT_SUBSTUSER_DELAYED:
3921 struct passwd *pwd;
3923 if ((pwd = getpwuid(opt->value.u_uidt)) == NULL) {
3924 Error1("getpwuid("F_uid"): no such user",
3925 opt->value.u_uidt);
3926 return -1;
3928 delayeduser_uid = opt->value.u_uidt;
3929 delayeduser_gid = pwd->pw_gid;
3930 if ((delayeduser_name = strdup(pwd->pw_name)) == NULL) {
3931 Error1("strdup("F_Zu"): out of memory",
3932 strlen(pwd->pw_name)+1);
3933 return -1;
3935 if ((delayeduser_dir = strdup(pwd->pw_dir)) == NULL) {
3936 Error1("strdup("F_Zu"): out of memory",
3937 strlen(pwd->pw_dir)+1);
3938 return -1;
3940 if ((delayeduser_shell = strdup(pwd->pw_shell)) == NULL) {
3941 Error1("strdup("F_Zu"): out of memory",
3942 strlen(pwd->pw_shell)+1);
3943 return -1;
3945 /* function to get all supplementary groups of user */
3946 delayeduser_ngids = sizeof(delayeduser_gids)/sizeof(gid_t);
3947 getusergroups(delayeduser_name, delayeduser_gids,
3948 &delayeduser_ngids);
3949 delayeduser = true;
3951 break;
3952 #endif
3953 case OPT_CHROOT_EARLY:
3954 case OPT_CHROOT:
3955 if (Chroot(opt->value.u_string) < 0) {
3956 Error2("chroot(\"%s\"): %s", opt->value.u_string,
3957 strerror(errno));
3958 return -1;
3960 if (Chdir("/") < 0) {
3961 Error1("chdir(\"/\"): %s", strerror(errno));
3962 return -1;
3964 break;
3965 case OPT_SETSID:
3966 if (Setsid() < 0) {
3967 Warn1("setsid(): %s", strerror(errno));
3968 if (Setpgid(getpid(), getppid()) < 0) {
3969 Warn3("setpgid(%d, %d): %s",
3970 getpid(), getppid(), strerror(errno));
3971 } else {
3972 if (Setsid() < 0) {
3973 Error1("setsid(): %s", strerror(errno));
3974 return -1;
3978 break;
3979 case OPT_SETPGID:
3980 if (Setpgid(0, opt->value.u_int) < 0) {
3981 Warn2("setpgid(0, "F_pid"): %s",
3982 opt->value.u_int, strerror(errno));
3984 break;
3985 case OPT_TIOCSCTTY:
3987 int mytty;
3988 /* this code idea taken from ssh/pty.c: make pty controlling term. */
3989 if ((mytty = Open("/dev/tty", O_NOCTTY, 0640)) < 0) {
3990 Warn1("open(\"/dev/tty\", O_NOCTTY, 0640): %s", strerror(errno));
3991 } else {
3992 /*0 Info1("open(\"/dev/tty\", O_NOCTTY, 0640) -> %d", mytty);*/
3993 #ifdef TIOCNOTTY
3994 if (Ioctl(mytty, TIOCNOTTY, NULL) < 0) {
3995 Warn2("ioctl(%d, TIOCNOTTY, NULL): %s",
3996 mytty, strerror(errno));
3998 #endif
3999 if (Close(mytty) < 0) {
4000 Info2("close(%d): %s",
4001 mytty, strerror(errno));
4004 #ifdef TIOCSCTTY
4005 if (Ioctl(fd, TIOCSCTTY, NULL) < 0) {
4006 Warn2("ioctl(%d, TIOCSCTTY, NULL): %s", fd, strerror(errno));
4008 #endif
4009 if (Tcsetpgrp(0, getpid()) < 0) {
4010 Warn2("tcsetpgrp("F_pid"): %s", getpid(), strerror(errno));
4013 break;
4015 #if _WITH_SOCKET
4016 #if WITH_IP4 && (defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN))
4017 case OPT_IP_ADD_MEMBERSHIP:
4018 return xioapply_ip_add_membership(sfd, opt);
4019 #endif /* WITH_IP4 && (defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)) */
4021 #if WITH_IP4 && defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP)
4022 case OPT_IP_ADD_SOURCE_MEMBERSHIP:
4023 return xioapply_ip_add_source_membership(sfd, opt);
4024 #endif /* WITH_IP4 && defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP) */
4026 #if WITH_IP6 && defined(HAVE_STRUCT_IPV6_MREQ)
4027 case OPT_IPV6_JOIN_GROUP:
4028 return xioapply_ipv6_join_group(sfd, opt);
4029 #endif /* WITH_IP6 && defined(HAVE_STRUCT_IPV6_MREQ) */
4031 #if WITH_IP6 && defined(HAVE_STRUCT_GROUP_SOURCE_REQ)
4032 case OPT_IPV6_JOIN_SOURCE_GROUP:
4033 return xioapply_ip6_join_source_group(sfd, opt);
4034 #endif /* WITH_IP6 && defined(HAVE_STRUCT_IPV6_MREQ) */
4035 #endif /* _WITH_SOCKET */
4037 default: Error1("applyopt_spec(opt:%s): INTERNAL option not implemented",
4038 opt->desc->defname);
4039 return -1;
4041 return 0;
4044 int applyopts_termios_value(
4045 int fd,
4046 struct opt *opt)
4048 if (((opt->value.u_uint << opt->desc->arg3) & opt->desc->minor) !=
4049 (opt->value.u_uint << opt->desc->arg3)) {
4050 Error2("option %s: invalid value %u",
4051 opt->desc->defname, opt->value.u_uint);
4052 return -1;
4054 if (xiotermios_value(fd, opt->desc->major, opt->desc->minor,
4055 (opt->value.u_uint << opt->desc->arg3) & opt->desc->minor) < 0) {
4056 return -1;
4058 return 0;
4061 /* Note: not all options can be applied this way (e.g. OFUNC_SPEC with PH_OPEN)
4062 implemented are: OFUNC_FCNTL, OFUNC_SOCKOPT (probably not all types),
4063 OFUNC_TERMIOS_FLAG, OFUNC_TERMIOS_PATTERN, and some OFUNC_SPEC */
4064 int applyopts(struct single *sfd, int fd, struct opt *opts, enum e_phase phase)
4066 struct opt *opt;
4067 int rc = 0;
4069 opt = opts;
4070 while (opt && opt->desc != ODESC_END) {
4071 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
4072 (phase == PH_ALL || phase == opt->desc->phase)) {
4073 if (applyopt(sfd, fd, opt) < 0)
4074 rc = -1;
4076 ++opt;
4079 #if WITH_TERMIOS
4080 if ((phase == PH_FD || phase == PH_ALL) && (fd >= 0 || sfd != NULL)) {
4081 xiotermios_flush(fd >= 0 ? fd : sfd->fd);
4083 #endif /* WITH_TERMIOS */
4084 return rc;
4087 /* applies to fd all options belonging to phases */
4088 /* note: not all options can be applied this way (e.g. OFUNC_SPEC with PH_OPEN)
4089 implemented are: OFUNC_FCNTL, OFUNC_SOCKOPT (probably not all types),
4090 OFUNC_TERMIOS_FLAG, OFUNC_TERMIOS_PATTERN, and some OFUNC_SPEC */
4091 int applyopts2(
4092 struct single *sfd,
4093 int fd,
4094 struct opt *opts,
4095 unsigned int from,
4096 unsigned int to) {
4097 unsigned int ph;
4098 int rc = 0;
4100 for (ph = from; ph <= to; ++ph) {
4101 rc |= applyopts(sfd, fd, opts, ph);
4103 return rc;
4106 int applyopts_optgroup(
4107 struct single *sfd,
4108 int fd,
4109 struct opt *opts,
4110 groups_t groups)
4112 int i;
4113 int rc = 0;
4115 if (opts == NULL)
4116 return 0;
4118 i = 0;
4119 while (opts[i].desc != ODESC_END) {
4120 if (opts[i].desc == ODESC_DONE &&
4121 opts[i].desc == ODESC_ERROR) {
4122 ++i;
4123 continue;
4125 if (opts[i].desc->group & groups) {
4126 rc |= applyopt(sfd, sfd->fd, &opts[i]);
4128 ++i;
4130 return rc;
4133 /* apply and consume all options of type FLAG and group.
4134 Return 0 if everything went right, or -1 if an error occurred. */
4135 int applyopts_flags(struct opt *opts, groups_t group, flags_t *result) {
4136 struct opt *opt = opts;
4138 if (!opts) return 0;
4140 while (opt->desc != ODESC_END) {
4141 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
4142 (opt->desc->group & group)) {
4143 if (opt->desc->func == OFUNC_FLAG) {
4144 if (opt->value.u_bool) {
4145 *result |= opt->desc->major;
4146 } else {
4147 *result &= ~opt->desc->major;
4149 opt->desc = ODESC_DONE;
4150 } else if (opt->desc->func == OFUNC_FLAG_PATTERN) {
4151 *result &= ~opt->desc->minor;
4152 *result |= opt->desc->major;
4153 opt->desc = ODESC_DONE;
4156 ++opt;
4158 return 0;
4162 /* set the FD_CLOEXEC fcntl if the options do not set it to 0 */
4163 int applyopts_cloexec(int fd, struct opt *opts) {
4164 bool docloexec = 1;
4166 if (!opts) return 0;
4168 retropt_bool(opts, OPT_CLOEXEC, &docloexec);
4169 if (docloexec) {
4170 if (Fcntl_l(fd, F_SETFD, FD_CLOEXEC) < 0) {
4171 Warn2("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", fd, strerror(errno));
4174 return 0;
4177 int applyopts_fchown(int fd, struct opt *opts) {
4178 uid_t user = -1;
4179 gid_t group = -1;
4181 retropt_uidt(opts, OPT_USER, &user);
4182 retropt_gidt(opts, OPT_GROUP, &group);
4184 if (user != (uid_t)-1 || group != (gid_t)-1) {
4185 if (Fchown(fd, user, group) < 0) {
4186 Error4("fchown(%d, "F_uid", "F_gid"): %s", fd, user, group,
4187 strerror(errno));
4188 return STAT_RETRYLATER;
4191 return 0;
4194 /* caller must make sure that option is not yet consumed */
4195 static int applyopt_offset(struct single *sfd, struct opt *opt) {
4196 unsigned char *ptr;
4198 ptr = (unsigned char *)sfd + opt->desc->major;
4199 switch (opt->desc->type) {
4200 case TYPE_BOOL:
4201 *(bool *)ptr = opt->value.u_bool; break;
4202 case TYPE_INT:
4203 *(int *)ptr = opt->value.u_int; break;
4204 case TYPE_DOUBLE:
4205 *(double *)ptr = opt->value.u_double; break;
4206 case TYPE_TIMEVAL:
4207 *(struct timeval *)ptr = opt->value.u_timeval; break;
4208 case TYPE_STRING_NULL:
4209 if (opt->value.u_string == NULL) {
4210 *(char **)ptr = NULL;
4211 break;
4213 /* PASSTHROUGH */
4214 case TYPE_STRING:
4215 if ((*(char **)ptr = strdup(opt->value.u_string)) == NULL) {
4216 Error1("strdup("F_Zu"): out of memory",
4217 strlen(opt->value.u_string)+1);
4219 break;
4220 case TYPE_CONST:
4221 *(int *)ptr = opt->desc->minor;
4222 break;
4223 case TYPE_IP4NAME:
4224 memset(ptr, 0, sizeof(struct sockaddr_in));
4225 ((struct sockaddr_in *)ptr)->sin_addr = opt->value.u_ip4addr;
4226 ((struct sockaddr_in *)ptr)->sin_family = PF_INET;
4227 break;
4228 case TYPE_IP4SOCK:
4229 memset(ptr, 0, sizeof(struct sockaddr_in));
4230 *(struct sockaddr_in *)ptr = opt->value.u_ip4sock;
4231 break;
4232 default:
4233 Error2("applyopt_offset(opt:%s): type %s not implemented",
4234 opt->desc->defname, xiohelp_opttypename(opt->desc->type));
4235 return -1;
4237 opt->desc = ODESC_DONE;
4238 return 0;
4241 int applyopts_offset(struct single *sfd, struct opt *opts) {
4242 struct opt *opt;
4244 opt = opts; while (opt->desc != ODESC_END) {
4245 if ((opt->desc == ODESC_DONE || opt->desc == ODESC_ERROR) ||
4246 opt->desc->func != OFUNC_OFFSET) {
4247 ++opt; continue; }
4249 applyopt_offset(sfd, opt);
4250 opt->desc = ODESC_DONE;
4251 ++opt;
4253 return 0;
4256 /* applies to sfd all OFUNC_EXT options belonging to phase
4257 returns -1 if an error occurred */
4258 int applyopts_single(struct single *sfd, struct opt *opts, enum e_phase phase) {
4259 struct opt *opt;
4260 int rc = 0;
4262 if (!opts)
4263 return 0;
4265 opt = opts; while (opt->desc != ODESC_END) {
4266 if ((opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR) &&
4267 (opt->desc->phase == phase && phase != PH_ALL)) {
4268 if (opt->desc->func < OFUNC_XIO) {
4269 rc = applyopt(NULL, sfd->fd, opt);
4270 } else {
4271 rc = applyopt(sfd, -1, opt);
4273 if (rc == 0)
4274 opt->desc = ODESC_DONE;
4275 else
4276 opt->desc = ODESC_ERROR;
4278 ++opt;
4280 return rc;
4283 /* Applies to sfd or fd the given option.
4284 Note: not all options can be applied this way.
4285 Returns 0.
4287 static int applyopt(
4288 struct single *sfd,
4289 int fd,
4290 struct opt *opt)
4292 int lockrc;
4293 int rc = 0;
4295 if (opt->desc == ODESC_DONE || opt->desc == ODESC_ERROR)
4296 return 0;
4298 if (sfd != NULL && fd < 0)
4299 fd = sfd->fd;
4301 switch (opt->desc->func) {
4303 case OFUNC_SPEC:
4304 rc = applyopt_spec(sfd, fd, opt);
4305 break;
4306 case OFUNC_SEEK32:
4307 rc = applyopt_seek32(fd, opt);
4308 break;
4310 #if HAVE_LSEEK64
4311 case OFUNC_SEEK64:
4312 rc = applyopt_seek64(fd, opt);
4313 break;
4314 #endif /* HAVE_LSEEK64 */
4316 case OFUNC_FCNTL:
4317 rc = applyopt_fcntl(fd, opt);
4318 break;
4320 case OFUNC_IOCTL:
4321 rc = applyopt_ioctl(fd, opt);
4322 break;
4324 case OFUNC_IOCTL_MASK_LONG:
4325 rc = applyopt_ioctl_mask_long(fd, opt);
4326 break;
4328 case OFUNC_IOCTL_GENERIC:
4329 rc = applyopt_ioctl_generic(fd, opt);
4330 break;
4332 #if _WITH_SOCKET
4333 case OFUNC_SOCKOPT:
4334 rc = applyopt_sockopt(fd, opt);
4335 break;
4337 case OFUNC_SOCKOPT_APPEND:
4338 rc = applyopt_sockopt_append(fd, opt);
4339 break;
4341 case OFUNC_SOCKOPT_GENERIC:
4342 rc = applyopt_sockopt_generic(fd, opt);
4343 break;
4344 #endif /* _WITH_SOCKET */
4346 #if HAVE_FLOCK
4347 case OFUNC_FLOCK:
4348 rc = applyopt_flock(fd, opt);
4349 break;
4350 #endif /* defined(HAVE_FLOCK) */
4352 #if WITH_TERMIOS
4353 case OFUNC_TERMIOS_FLAG:
4354 rc = xiotermiosflag_applyopt(fd, opt);
4355 break;
4357 case OFUNC_TERMIOS_VALUE:
4358 rc = applyopts_termios_value(fd, opt);
4359 break;
4361 case OFUNC_TERMIOS_PATTERN:
4362 rc = xiotermios_value(fd, opt->desc->major,
4363 opt->desc->arg3, opt->desc->minor);
4364 break;
4366 case OFUNC_TERMIOS_CHAR:
4367 rc = xiotermios_char(fd, opt->desc->major, opt->value.u_byte);
4368 break;
4370 #ifdef HAVE_TERMIOS_ISPEED
4371 case OFUNC_TERMIOS_SPEED:
4372 rc = xiotermios_speed(fd, opt->desc->major, opt->value.u_uint);
4373 break;
4374 #endif /* HAVE_TERMIOS_ISPEED */
4376 case OFUNC_TERMIOS_SPEC:
4377 rc = xiotermios_spec(fd, opt->desc->optcode);
4378 break;
4379 #endif /* WITH_TERMIOS */
4381 #if WITH_STREAMS
4382 #define ENABLE_APPLYOPT
4383 #include "xio-streams.c"
4384 #undef ENABLE_APPLYOPT
4385 #endif /* WITH_STREAMS */
4387 case OFUNC_OFFSET:
4388 rc = applyopt_offset(sfd, opt);
4389 break;
4391 case OFUNC_EXT:
4392 switch (opt->desc->optcode) {
4393 #if 0
4394 case OPT_IGNOREEOF:
4395 sfd->ignoreeof = true;
4396 return 0;
4397 case OPT_CR:
4398 sfd->lineterm = LINETERM_CR;
4399 return 0;
4400 case OPT_CRNL:
4401 sfd->lineterm = LINETERM_CRNL;
4402 return 0;
4403 #endif /* 0 */
4404 case OPT_READBYTES:
4405 sfd->readbytes = opt->value.u_sizet;
4406 sfd->actbytes = sfd->readbytes;
4407 break;
4409 case OPT_LOCKFILE:
4410 if (sfd->lock.lockfile) {
4411 Error("only one use of options lockfile and waitlock allowed");
4413 sfd->lock.lockfile = strdup(opt->value.u_string);
4414 sfd->lock.intervall.tv_sec = 1;
4415 sfd->lock.intervall.tv_nsec = 0;
4417 if ((lockrc = xiolock(&sfd->lock)) < 0) {
4418 /* error message already printed */
4419 rc = -1;
4421 if (lockrc) {
4422 Error1("could not obtain lock \"%s\"", sfd->lock.lockfile);
4423 rc = -1;
4424 } else {
4425 sfd->havelock = true;
4427 break;
4429 case OPT_WAITLOCK:
4430 if (sfd->lock.lockfile) {
4431 Error("only one use of options lockfile and waitlock allowed");
4433 sfd->lock.lockfile = strdup(opt->value.u_string);
4434 sfd->lock.waitlock = true;
4435 sfd->lock.intervall.tv_sec = 1;
4436 sfd->lock.intervall.tv_nsec = 0;
4438 /*! this should be integrated into central select()/poll() loop */
4439 rc = xiolock(&sfd->lock);
4440 if (rc < 0)
4441 break;
4442 sfd->havelock = true;
4443 break;
4445 default:
4446 /* just store the value in the correct component of struct single */
4447 if (opt->desc->type == TYPE_CONST) {
4448 /* only for integral types compatible to int */
4449 *(int *)(&((char *)sfd)[opt->desc->major]) = opt->desc->arg3;
4450 } else {
4451 memcpy(&((char *)sfd)[opt->desc->major], &opt->value, opt->desc->minor);
4454 break;
4456 case OFUNC_OFFSET_MASK:
4457 /* Currently not used */
4458 /* Data target is some integer with independent bits in sfd;
4459 set or unset the specified bits. */
4461 void *mask = (char *)sfd + opt->desc->major;
4462 size_t masksize = opt->desc->minor;
4463 unsigned long bit = opt->desc->arg3;
4464 switch (masksize) {
4465 case sizeof(int):
4466 if (opt->value.u_bool) {
4467 (*(int *)mask) |= bit;
4468 } else {
4469 (*(int *)mask) &= ~bit;
4471 break;
4472 default:
4473 Info1("sizeof(int)="F_Zu, sizeof(int));
4474 Error2("applyopts_single(opt:%s): INTERNAL: OFUNC_OFFSET_MASK size "F_Zu" not implemented",
4475 opt->desc->defname, masksize);
4478 break;
4480 case OFUNC_OFFSET_MASKS:
4481 /* An external (e.g. library) variable with independent bits is to be
4482 manipulated. Here the data target is an array with size 2, the first
4483 element holds the bit mask to be set, the second one those to be
4484 cleared. Each related option sets or unsets a specific bit. */
4486 void *masks = (char *)sfd + opt->desc->major;
4487 size_t masksize = opt->desc->minor;
4488 unsigned long bit = opt->desc->arg3;
4489 switch (masksize>>1) {
4490 case sizeof(uint16_t):
4491 if (opt->value.u_bool) {
4492 ((uint16_t *)masks)[0] |= bit;
4493 } else {
4494 ((uint16_t *)masks)[1] |= bit;
4496 break;
4497 case sizeof(uint32_t):
4498 if (opt->value.u_bool) {
4499 ((uint32_t *)masks)[0] |= bit;
4500 } else {
4501 ((uint32_t *)masks)[1] |= bit;
4503 break;
4504 case sizeof(uint64_t):
4505 if (opt->value.u_bool) {
4506 ((uint64_t *)masks)[0] |= bit;
4507 } else {
4508 ((uint64_t *)masks)[1] |= bit;
4510 break;
4511 default:
4512 Info1("sizeof(uint32_t)="F_Zu, sizeof(uint32_t));
4513 Error2("applyopts_single(opt:%s): INTERNAL: OFUNC_OFFSET_MASKS size "F_Zu" not implemented",
4514 opt->desc->defname, masksize);
4515 rc = -1;
4516 break;
4519 break;
4521 case OFUNC_SIGNAL:
4522 rc = xio_opt_signal(sfd->para.exec.pid, opt->desc->major);
4523 break;
4525 default:
4526 Error2("applyopt(opt:%s): INTERNAL: ofunc %d not implemented",
4527 opt->desc->defname, opt->desc->func);
4528 rc = -1;
4529 break;
4531 if (rc == 0)
4532 opt->desc = ODESC_DONE;
4533 else if (rc < 0)
4534 opt->desc = ODESC_ERROR;
4535 /* rc > 0: no action */
4537 return 0;
4541 /* apply remaining options to file descriptor, and tell us if something is
4542 still unused */
4543 int _xio_openlate(struct single *sfd, struct opt *opts) {
4544 int numleft;
4545 int result;
4547 _xioopen_setdelayeduser();
4549 if ((result = applyopts(sfd, sfd->fd, opts, PH_LATE)) < 0) {
4550 return result;
4552 if ((result = applyopts_single(sfd, opts, PH_LATE)) < 0) {
4553 return result;
4555 if ((result = applyopts(sfd, sfd->fd, opts, PH_LATE2)) < 0) {
4556 return result;
4558 if ((result = applyopts(sfd, sfd->fd, opts, PH_PASTEXEC)) < 0) {
4559 return result;
4562 if ((numleft = leftopts(opts)) > 0) {
4563 showleft(opts);
4564 Error1("INTERNAL: %d option(s) remained unused", numleft);
4565 return -1;
4567 return 0;
4570 int dropopts(struct opt *opts, unsigned int phase) {
4571 struct opt *opt;
4573 if (phase == PH_ALL) {
4574 opts[0].desc = ODESC_END;
4575 return 0;
4577 opt = opts; while (opt && opt->desc != ODESC_END) {
4578 if (opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR &&
4579 opt->desc->phase == phase) {
4580 Debug1("ignoring option \"%s\"", opt->desc->defname);
4581 opt->desc = ODESC_DONE;
4583 ++opt;
4585 return 0;
4588 int dropopts2(struct opt *opts, unsigned int from, unsigned int to) {
4589 unsigned int i;
4591 for (i = from; i <= to; ++i) {
4592 dropopts(opts, i);
4594 return 0;
4597 int dumpopts(struct opt *opts)
4599 int i;
4601 if (opts == NULL) {
4602 Warn("dumpopts: NULL");
4603 return 0;
4605 i = 0;
4606 while (opts[i].desc != ODESC_END) {
4607 if (opts[i].desc != ODESC_DONE &&
4608 opts[i].desc != ODESC_ERROR) {
4609 Warn2("dumpopts(): %d %s", i, opts[i].desc->defname);
4611 ++i;
4613 return 0;