New option ip-add-source-membership
[socat.git] / xioopts.c
blob7a104b6a52b18505934603c7a6d4fe4c3bd01e20
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"
16 bool xioopts_ignoregroups;
18 #define IF_ANY(a,b) {a,b},
20 #if WITH_NAMED
21 # define IF_NAMED(a,b) {a,b},
22 #else
23 # define IF_NAMED(a,b)
24 #endif
26 #if WITH_PIPE || WITH_GOPEN
27 # define IF_OPEN(a,b) {a,b},
28 #else
29 # define IF_OPEN(a,b)
30 #endif
32 #if WITH_TERMIOS
33 # define IF_TERMIOS(a,b) {a,b},
34 #else
35 # define IF_TERMIOS(a,b)
36 #endif
38 #if WITH_EXEC
39 # define IF_EXEC(a,b) {a,b},
40 #else
41 # define IF_EXEC(a,b)
42 #endif
44 #if _WITH_SOCKET
45 # define IF_SOCKET(a,b) {a,b},
46 #else
47 # define IF_SOCKET(a,b)
48 #endif
50 #if WITH_LISTEN
51 # define IF_LISTEN(a,b) {a,b},
52 #else
53 # define IF_LISTEN(a,b)
54 #endif
56 #if (WITH_UDP || WITH_TCP) && WITH_LISTEN
57 # define IF_RANGE(a,b) {a,b},
58 #else
59 # define IF_RANGE(a,b)
60 #endif
62 #if WITH_IP4 || WITH_IP6
63 # define IF_IP(a,b) {a,b},
64 #else
65 # define IF_IP(a,b)
66 #endif
68 #if WITH_IP6
69 # define IF_IP6(a,b) {a,b},
70 #else
71 # define IF_IP6(a,b)
72 #endif
74 #if WITH_TCP|WITH_UDP
75 # define IF_IPAPP(a,b) {a,b},
76 #else
77 # define IF_IPAPP(a,b)
78 #endif
80 #if WITH_TCP
81 # define IF_TCP(a,b) {a,b},
82 #else
83 # define IF_TCP(a,b)
84 #endif
86 #if WITH_SCTP
87 # define IF_SCTP(a,b) {a,b},
88 #else
89 # define IF_SCTP(a,b)
90 #endif
92 #if WITH_SOCKS4
93 # define IF_SOCKS4(a,b) {a,b},
94 #else
95 # define IF_SOCKS4(a,b)
96 #endif
98 #if WITH_PROXY
99 # define IF_PROXY(a,b) {a,b},
100 #else
101 # define IF_PROXY(a,b)
102 #endif
104 #if WITH_READLINE
105 # define IF_READLINE(a,b) {a,b},
106 #else
107 # define IF_READLINE(a,b)
108 #endif
110 #if WITH_PTY
111 # define IF_PTY(a,b) {a,b},
112 #else
113 # define IF_PTY(a,b)
114 #endif
116 #if WITH_OPENSSL
117 # define IF_OPENSSL(a,b) {a,b},
118 #else
119 # define IF_OPENSSL(a,b)
120 #endif
122 #if WITH_TUN
123 # define IF_TUN(a,b) {a,b},
124 #else
125 # define IF_TUN(a,b)
126 #endif
128 #if WITH_UNIX
129 # define IF_UNIX(a,b) {a,b},
130 #else
131 # define IF_UNIX(a,b)
132 #endif
134 #if WITH_RETRY
135 # define IF_RETRY(a,b) {a,b},
136 #else
137 # define IF_RETRY(a,b)
138 #endif
141 static int applyopt_offset(struct single *xfd, struct opt *opt);
144 /* address options - keep this array strictly alphabetically sorted for
145 binary search! */
146 /* NULL terminated */
147 const struct optname optionnames[] = {
148 #if HAVE_RESOLV_H && WITH_RES_AAONLY
149 IF_IP ("aaonly", &opt_res_aaonly)
150 #endif
151 #ifdef TCP_ABORT_THRESHOLD /* HP_UX */
152 IF_TCP ("abort-threshold", &opt_tcp_abort_threshold)
153 #endif
154 IF_SOCKET ("accept-timeout", &opt_accept_timeout)
155 #ifdef SO_ACCEPTCONN /* AIX433 */
156 IF_SOCKET ("acceptconn", &opt_so_acceptconn)
157 #endif /* SO_ACCEPTCONN */
158 #ifdef IP_ADD_MEMBERSHIP
159 IF_IP ("add-membership", &opt_ip_add_membership)
160 #endif
161 #ifdef IP_ADD_SOURCE_MEMBERSHIP
162 IF_IP ("add-source-membership", &opt_ip_add_source_membership)
163 #endif
164 IF_TUN ("allmulti", &opt_iff_allmulti)
165 #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE)
166 IF_IPAPP ("allow-table", &opt_tcpwrap_hosts_allow_table)
167 #endif
168 IF_ANY ("append", &opt_append)
169 #ifdef O_ASYNC
170 IF_ANY ("async", &opt_async)
171 #endif
172 #ifdef SO_ATTACH_FILTER
173 IF_SOCKET ("attach-filter", &opt_so_attach_filter)
174 IF_SOCKET ("attachfilter", &opt_so_attach_filter)
175 #endif
176 #ifdef SO_AUDIT /* AIX 4.3.3 */
177 IF_SOCKET ("audit", &opt_so_audit)
178 #endif /* SO_AUDIT */
179 #ifdef IPV6_AUTHHDR
180 IF_IP6 ("authhdr", &opt_ipv6_authhdr)
181 #endif
182 IF_TUN ("automedia", &opt_iff_automedia)
183 #ifdef CBAUD
184 IF_TERMIOS("b0", &opt_b0)
185 #ifdef B1000000
186 IF_TERMIOS("b1000000", &opt_b1000000)
187 #endif
188 IF_TERMIOS("b110", &opt_b110)
189 #ifdef B115200
190 IF_TERMIOS("b115200", &opt_b115200)
191 #endif
192 #ifdef B1152000
193 IF_TERMIOS("b1152000", &opt_b1152000)
194 #endif
195 IF_TERMIOS("b1200", &opt_b1200)
196 IF_TERMIOS("b134", &opt_b134)
197 IF_TERMIOS("b150", &opt_b150)
198 #ifdef B1500000
199 IF_TERMIOS("b1500000", &opt_b1500000)
200 #endif
201 IF_TERMIOS("b1800", &opt_b1800)
202 IF_TERMIOS("b19200", &opt_b19200)
203 IF_TERMIOS("b200", &opt_b200)
204 #ifdef B2000000
205 IF_TERMIOS("b2000000", &opt_b2000000)
206 #endif
207 #ifdef B230400
208 IF_TERMIOS("b230400", &opt_b230400)
209 #endif
210 IF_TERMIOS("b2400", &opt_b2400)
211 #ifdef B2500000
212 IF_TERMIOS("b2500000", &opt_b2500000)
213 #endif
214 IF_TERMIOS("b300", &opt_b300)
215 #ifdef B3000000
216 IF_TERMIOS("b3000000", &opt_b3000000)
217 #endif
218 #ifdef B3500000
219 IF_TERMIOS("b3500000", &opt_b3500000)
220 #endif
221 #ifdef B3600 /* HP-UX */
222 IF_TERMIOS("b3600", &opt_b3600)
223 #endif
224 IF_TERMIOS("b38400", &opt_b38400)
225 #ifdef B4000000
226 IF_TERMIOS("b4000000", &opt_b4000000)
227 #endif
228 #ifdef B460800
229 IF_TERMIOS("b460800", &opt_b460800)
230 #endif
231 IF_TERMIOS("b4800", &opt_b4800)
232 IF_TERMIOS("b50", &opt_b50)
233 #ifdef B500000
234 IF_TERMIOS("b500000", &opt_b500000)
235 #endif
236 #ifdef B57600
237 IF_TERMIOS("b57600", &opt_b57600)
238 #endif
239 #ifdef B576000
240 IF_TERMIOS("b576000", &opt_b576000)
241 #endif
242 IF_TERMIOS("b600", &opt_b600)
243 #ifdef B7200 /* HP-UX */
244 IF_TERMIOS("b7200", &opt_b7200)
245 #endif
246 IF_TERMIOS("b75", &opt_b75)
247 #ifdef B900 /* HP-UX */
248 IF_TERMIOS("b900", &opt_b900)
249 #endif
250 #ifdef B921600
251 IF_TERMIOS("b921600", &opt_b921600)
252 #endif
253 IF_TERMIOS("b9600", &opt_b9600)
254 #endif /* defined(CBAUD) */
255 IF_LISTEN ("backlog", &opt_backlog)
256 #ifdef O_BINARY
257 IF_OPEN ("bin", &opt_o_binary)
258 IF_OPEN ("binary", &opt_o_binary)
259 #endif
260 IF_SOCKET ("bind", &opt_bind)
261 #ifdef SO_BINDTODEVICE
262 IF_SOCKET ("bindtodevice", &opt_so_bindtodevice)
263 #endif
264 IF_TERMIOS("brkint", &opt_brkint)
265 IF_SOCKET ("broadcast", &opt_so_broadcast)
266 #ifdef BSDLY
267 # ifdef BS0
268 IF_TERMIOS("bs0", &opt_bs0)
269 # endif
270 # ifdef BS1
271 IF_TERMIOS("bs1", &opt_bs1)
272 # endif
273 #endif
274 #ifdef SO_BSDCOMPAT
275 IF_SOCKET ("bsdcompat", &opt_so_bsdcompat)
276 #endif
277 #ifdef BSDLY
278 IF_TERMIOS("bsdly", &opt_bsdly)
279 #endif
280 IF_ANY ("bytes", &opt_readbytes)
281 IF_OPENSSL("cafile", &opt_openssl_cafile)
282 IF_OPENSSL("capath", &opt_openssl_capath)
283 IF_OPENSSL("cert", &opt_openssl_certificate)
284 IF_OPENSSL("certificate", &opt_openssl_certificate)
285 IF_TERMIOS("cfmakeraw", &opt_termios_cfmakeraw)
286 IF_ANY ("chroot", &opt_chroot)
287 IF_ANY ("chroot-early", &opt_chroot_early)
288 /*IF_TERMIOS("cibaud", &opt_cibaud)*/
289 IF_OPENSSL("cipher", &opt_openssl_cipherlist)
290 IF_OPENSSL("cipherlist", &opt_openssl_cipherlist)
291 IF_OPENSSL("ciphers", &opt_openssl_cipherlist)
292 #ifdef SO_CKSUMRECV
293 IF_SOCKET ("cksumrecv", &opt_so_cksumrecv)
294 #endif /* SO_CKSUMRECV */
295 /*IF_NAMED ("cleanup", &opt_cleanup)*/
296 IF_TERMIOS("clocal", &opt_clocal)
297 IF_ANY ("cloexec", &opt_cloexec)
298 IF_ANY ("close", &opt_end_close)
299 IF_OPENSSL("cn", &opt_openssl_commonname)
300 IF_OPENSSL("commonname", &opt_openssl_commonname)
301 #if WITH_FS && defined(FS_COMPR_FL)
302 IF_ANY ("compr", &opt_fs_compr)
303 #endif
304 #if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_COMP)
305 IF_OPENSSL("compress", &opt_openssl_compress)
306 #endif
307 #ifdef TCP_CONN_ABORT_THRESHOLD /* HP_UX */
308 IF_TCP ("conn-abort-threshold", &opt_tcp_conn_abort_threshold)
309 #endif
310 IF_SOCKET ("connect-timeout", &opt_connect_timeout)
311 IF_LISTEN ("cool-write", &opt_cool_write)
312 IF_LISTEN ("coolwrite", &opt_cool_write)
313 #ifdef TCP_CORK
314 IF_TCP ("cork", &opt_tcp_cork)
315 #endif
316 IF_ANY ("cr", &opt_cr)
317 #ifdef CRDLY
318 # ifdef CR0
319 IF_TERMIOS("cr0", &opt_cr0)
320 # endif
321 # ifdef CR1
322 IF_TERMIOS("cr1", &opt_cr1)
323 # endif
324 # ifdef CR2
325 IF_TERMIOS("cr2", &opt_cr2)
326 # endif
327 # ifdef CR3
328 IF_TERMIOS("cr3", &opt_cr3)
329 # endif
330 # if CRDLY_SHIFT >= 0
331 IF_TERMIOS("crdly", &opt_crdly)
332 # endif
333 #endif /* defined(CRDLY) */
334 IF_TERMIOS("cread", &opt_cread)
335 IF_OPEN ("creat", &opt_o_create)
336 IF_OPEN ("create", &opt_o_create)
337 IF_ANY ("crlf", &opt_crnl)
338 IF_ANY ("crnl", &opt_crnl)
339 IF_TERMIOS("crterase", &opt_echoe)
340 IF_TERMIOS("crtkill", &opt_echoke)
341 #ifdef CRTSCTS
342 IF_TERMIOS("crtscts", &opt_crtscts)
343 #endif
344 IF_TERMIOS("cs5", &opt_cs5)
345 IF_TERMIOS("cs6", &opt_cs6)
346 IF_TERMIOS("cs7", &opt_cs7)
347 IF_TERMIOS("cs8", &opt_cs8)
348 #if CSIZE_SHIFT >= 0
349 IF_TERMIOS("csize", &opt_csize)
350 #endif
351 IF_TERMIOS("cstopb", &opt_cstopb)
352 IF_TERMIOS("ctlecho", &opt_echoctl)
353 IF_TERMIOS("ctty", &opt_tiocsctty)
354 IF_EXEC ("dash", &opt_dash)
355 IF_SOCKET ("debug", &opt_so_debug)
356 /*IF_IP ("debug", &opt_res_debug)*/
357 #ifdef O_DEFER
358 IF_OPEN ("defer", &opt_o_defer)
359 #endif
360 #ifdef TCP_DEFER_ACCEPT /* Linux 2.4.0 */
361 IF_TCP ("defer-accept", &opt_tcp_defer_accept)
362 #endif
363 #if HAVE_RESOLV_H
364 IF_IP ("defnames", &opt_res_defnames)
365 #endif /* HAVE_RESOLV_H */
366 #ifdef O_DELAY
367 IF_OPEN ("delay", &opt_o_delay)
368 #endif
369 IF_NAMED ("delete", &opt_unlink)
370 #if WITH_LIBWRAP && defined(HAVE_HOSTS_DENY_TABLE)
371 IF_IPAPP ("deny-table", &opt_tcpwrap_hosts_deny_table)
372 #endif
373 #ifdef SO_DETACH_FILTER
374 IF_SOCKET ("detach-filter", &opt_so_detach_filter)
375 IF_SOCKET ("detachfilter", &opt_so_detach_filter)
376 #endif
377 #ifdef SO_DGRAM_ERRIND
378 IF_SOCKET ("dgram-errind", &opt_so_dgram_errind)
379 IF_SOCKET ("dgramerrind", &opt_so_dgram_errind)
380 #endif
381 IF_OPENSSL("dh", &opt_openssl_dhparam)
382 IF_OPENSSL("dhparam", &opt_openssl_dhparam)
383 IF_OPENSSL("dhparams", &opt_openssl_dhparam)
384 #ifdef O_DIRECT
385 IF_OPEN ("direct", &opt_o_direct)
386 #endif
387 #ifdef O_DIRECTORY
388 IF_OPEN ("directory", &opt_o_directory)
389 #endif
390 #if WITH_FS && defined(FS_DIRSYNC_FL)
391 IF_ANY ("dirsync", &opt_fs_dirsync)
392 #endif
393 #ifdef VDISCARD
394 IF_TERMIOS("discard", &opt_vdiscard)
395 #endif
396 #if HAVE_RESOLV_H
397 IF_IP ("dnsrch", &opt_res_dnsrch)
398 #endif /* HAVE_RESOLV_H */
399 #ifdef SO_DONTLINGER
400 IF_SOCKET ("dontlinger", &opt_so_dontlinger)
401 #endif
402 IF_SOCKET ("dontroute", &opt_so_dontroute)
403 #ifdef IPV6_DSTOPTS
404 IF_IP6 ("dstopts", &opt_ipv6_dstopts)
405 #endif
406 #ifdef VDSUSP /* HP-UX */
407 IF_TERMIOS("dsusp", &opt_vdsusp)
408 #endif
409 #ifdef O_DSYNC
410 IF_OPEN ("dsync", &opt_o_dsync)
411 #endif
412 IF_TERMIOS("echo", &opt_echo)
413 IF_TERMIOS("echoctl", &opt_echoctl)
414 IF_TERMIOS("echoe", &opt_echoe)
415 IF_TERMIOS("echok", &opt_echok)
416 IF_TERMIOS("echoke", &opt_echoke)
417 IF_TERMIOS("echonl", &opt_echonl)
418 #ifdef ECHOPRT
419 IF_TERMIOS("echoprt", &opt_echoprt)
420 #endif
421 IF_OPENSSL("egd", &opt_openssl_egd)
422 IF_ANY ("end-close", &opt_end_close)
423 IF_TERMIOS("eof", &opt_veof)
424 IF_TERMIOS("eol", &opt_veol)
425 IF_TERMIOS("eol2", &opt_veol2)
426 IF_TERMIOS("erase", &opt_verase)
427 IF_SOCKET ("error", &opt_so_error)
428 IF_ANY ("escape", &opt_escape)
429 IF_OPEN ("excl", &opt_o_excl)
430 #if WITH_FS && defined(FS_APPEND_FL)
431 IF_ANY ("ext2-append", &opt_fs_append)
432 #endif
433 #if WITH_FS && defined(FS_COMPR_FL)
434 IF_ANY ("ext2-compr", &opt_fs_compr)
435 #endif
436 #if WITH_FS && defined(FS_DIRSYNC_FL)
437 IF_ANY ("ext2-dirsync", &opt_fs_dirsync)
438 #endif
439 #if WITH_FS && defined(FS_IMMUTABLE_FL)
440 IF_ANY ("ext2-immutable", &opt_fs_immutable)
441 #endif
442 #if WITH_FS && defined(FS_JOURNAL_DATA_FL)
443 IF_ANY ("ext2-journal-data", &opt_fs_journal_data)
444 #endif
445 #if WITH_FS && defined(FS_NOATIME_FL)
446 IF_ANY ("ext2-noatime", &opt_fs_noatime)
447 #endif
448 #if WITH_FS && defined(FS_NODUMP_FL)
449 IF_ANY ("ext2-nodump", &opt_fs_nodump)
450 #endif
451 #if WITH_FS && defined(FS_NOTAIL_FL)
452 IF_ANY ("ext2-notail", &opt_fs_notail)
453 #endif
454 #if WITH_FS && defined(FS_SECRM_FL)
455 IF_ANY ("ext2-secrm", &opt_fs_secrm)
456 #endif
457 #if WITH_FS && defined(FS_SYNC_FL)
458 IF_ANY ("ext2-sync", &opt_fs_sync)
459 #endif
460 #if WITH_FS && defined(FS_TOPDIR_FL)
461 IF_ANY ("ext2-topdir", &opt_fs_topdir)
462 #endif
463 #if WITH_FS && defined(FS_UNRM_FL)
464 IF_ANY ("ext2-unrm", &opt_fs_unrm)
465 #endif
466 #if WITH_FS && defined(FS_APPEND_FL)
467 IF_ANY ("ext3-append", &opt_fs_append)
468 #endif
469 #if WITH_FS && defined(FS_COMPR_FL)
470 IF_ANY ("ext3-compr", &opt_fs_compr)
471 #endif
472 #if WITH_FS && defined(FS_DIRSYNC_FL)
473 IF_ANY ("ext3-dirsync", &opt_fs_dirsync)
474 #endif
475 #if WITH_FS && defined(FS_IMMUTABLE_FL)
476 IF_ANY ("ext3-immutable", &opt_fs_immutable)
477 #endif
478 #if WITH_FS && defined(FS_JOURNAL_DATA_FL)
479 IF_ANY ("ext3-journal-data", &opt_fs_journal_data)
480 #endif
481 #if WITH_FS && defined(FS_NOATIME_FL)
482 IF_ANY ("ext3-noatime", &opt_fs_noatime)
483 #endif
484 #if WITH_FS && defined(FS_NODUMP_FL)
485 IF_ANY ("ext3-nodump", &opt_fs_nodump)
486 #endif
487 #if WITH_FS && defined(FS_NOTAIL_FL)
488 IF_ANY ("ext3-notail", &opt_fs_notail)
489 #endif
490 #if WITH_FS && defined(FS_SECRM_FL)
491 IF_ANY ("ext3-secrm", &opt_fs_secrm)
492 #endif
493 #if WITH_FS && defined(FS_SYNC_FL)
494 IF_ANY ("ext3-sync", &opt_fs_sync)
495 #endif
496 #if WITH_FS && defined(FS_TOPDIR_FL)
497 IF_ANY ("ext3-topdir", &opt_fs_topdir)
498 #endif
499 #if WITH_FS && defined(FS_UNRM_FL)
500 IF_ANY ("ext3-unrm", &opt_fs_unrm)
501 #endif
502 IF_ANY ("f-setlk", &opt_f_setlk_wr)
503 IF_ANY ("f-setlk-rd", &opt_f_setlk_rd)
504 IF_ANY ("f-setlk-wr", &opt_f_setlk_wr)
505 IF_ANY ("f-setlkw", &opt_f_setlkw_wr)
506 IF_ANY ("f-setlkw-rd", &opt_f_setlkw_rd)
507 IF_ANY ("f-setlkw-wr", &opt_f_setlkw_wr)
508 IF_EXEC ("fdin", &opt_fdin)
509 IF_EXEC ("fdout", &opt_fdout)
510 #ifdef FFDLY
511 # ifdef FF0
512 IF_TERMIOS("ff0", &opt_ff0)
513 # endif
514 # ifdef FF1
515 IF_TERMIOS("ff1", &opt_ff1)
516 # endif
517 IF_TERMIOS("ffdly", &opt_ffdly)
518 #endif
519 #ifdef FIOSETOWN
520 IF_SOCKET ("fiosetown", &opt_fiosetown)
521 #endif
522 #if WITH_FIPS
523 IF_OPENSSL("fips", &opt_openssl_fips)
524 #endif
525 #if HAVE_FLOCK
526 IF_ANY ("flock", &opt_flock_ex)
527 IF_ANY ("flock-ex", &opt_flock_ex)
528 IF_ANY ("flock-ex-nb", &opt_flock_ex_nb)
529 IF_ANY ("flock-nb", &opt_flock_ex_nb)
530 IF_ANY ("flock-sh", &opt_flock_sh)
531 IF_ANY ("flock-sh-nb", &opt_flock_sh_nb)
532 #endif
533 #ifdef IPV4_FLOWINFO
534 IF_IP6 ("flowinfo", &opt_ipv6_flowinfo)
535 #endif
536 IF_TERMIOS("flusho", &opt_flusho)
537 IF_RETRY ("forever", &opt_forever)
538 IF_LISTEN ("fork", &opt_fork)
539 #ifdef IP_FREEBIND
540 IF_IP ("freebind", &opt_ip_freebind)
541 #endif
542 #if WITH_FS && defined(FS_APPEND_FL)
543 IF_ANY ("fs-append", &opt_fs_append)
544 #endif
545 #if WITH_FS && defined(FS_COMPR_FL)
546 IF_ANY ("fs-compr", &opt_fs_compr)
547 #endif
548 #if WITH_FS && defined(FS_DIRSYNC_FL)
549 IF_ANY ("fs-dirsync", &opt_fs_dirsync)
550 #endif
551 #if WITH_FS && defined(FS_IMMUTABLE_FL)
552 IF_ANY ("fs-immutable", &opt_fs_immutable)
553 #endif
554 #if WITH_FS && defined(FS_JOURNAL_DATA_FL)
555 IF_ANY ("fs-journal-data", &opt_fs_journal_data)
556 #endif
557 #if WITH_FS && defined(FS_NOATIME_FL)
558 IF_ANY ("fs-noatime", &opt_fs_noatime)
559 #endif
560 #if WITH_FS && defined(FS_NODUMP_FL)
561 IF_ANY ("fs-nodump", &opt_fs_nodump)
562 #endif
563 #if WITH_FS && defined(FS_NOTAIL_FL)
564 IF_ANY ("fs-notail", &opt_fs_notail)
565 #endif
566 #if WITH_FS && defined(FS_SECRM_FL)
567 IF_ANY ("fs-secrm", &opt_fs_secrm)
568 #endif
569 #if WITH_FS && defined(FS_SYNC_FL)
570 IF_ANY ("fs-sync", &opt_fs_sync)
571 #endif
572 #if WITH_FS && defined(FS_TOPDIR_FL)
573 IF_ANY ("fs-topdir", &opt_fs_topdir)
574 #endif
575 #if WITH_FS && defined(FS_UNRM_FL)
576 IF_ANY ("fs-unrm", &opt_fs_unrm)
577 #endif
578 #if HAVE_FTRUNCATE64
579 IF_ANY ("ftruncate", &opt_ftruncate64)
580 #else
581 IF_ANY ("ftruncate", &opt_ftruncate32)
582 #endif
583 IF_ANY ("ftruncate32", &opt_ftruncate32)
584 #if HAVE_FTRUNCATE64
585 IF_ANY ("ftruncate64", &opt_ftruncate64)
586 #endif
587 IF_ANY ("gid", &opt_group)
588 IF_NAMED ("gid-e", &opt_group_early)
589 IF_ANY ("gid-l", &opt_group_late)
590 IF_ANY ("group", &opt_group)
591 IF_NAMED ("group-early", &opt_group_early)
592 IF_ANY ("group-late", &opt_group_late)
593 #ifdef IP_HDRINCL
594 IF_IP ("hdrincl", &opt_ip_hdrincl)
595 #endif
596 IF_READLINE("history", &opt_history_file)
597 IF_READLINE("history-file", &opt_history_file)
598 #ifdef IPV6_HOPLIMIT
599 IF_IP6 ("hoplimit", &opt_ipv6_hoplimit)
600 #endif
601 #ifdef IPV6_HOPOPTS
602 IF_IP6 ("hopopts", &opt_ipv6_hopopts)
603 #endif
604 #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE)
605 IF_IPAPP ("hosts-allow", &opt_tcpwrap_hosts_allow_table)
606 #endif
607 #if WITH_LIBWRAP && defined(HAVE_HOSTS_DENY_TABLE)
608 IF_IPAPP ("hosts-deny", &opt_tcpwrap_hosts_deny_table)
609 #endif
610 IF_TERMIOS("hup", &opt_hupcl)
611 IF_TERMIOS("hupcl", &opt_hupcl)
612 #ifdef I_POP
613 IF_ANY ("i-pop-all", &opt_streams_i_pop_all)
614 #endif
615 #ifdef I_PUSH
616 IF_ANY ("i-push", &opt_streams_i_push)
617 #endif
618 IF_TERMIOS("icanon", &opt_icanon)
619 IF_TERMIOS("icrnl", &opt_icrnl)
620 IF_TERMIOS("iexten", &opt_iexten)
621 #ifdef SO_BINDTODEVICE
622 IF_SOCKET ("if", &opt_so_bindtodevice)
623 #endif
624 IF_TUN ("iff-allmulti", &opt_iff_allmulti)
625 IF_TUN ("iff-automedia", &opt_iff_automedia)
626 IF_TUN ("iff-broadcast", &opt_iff_broadcast)
627 IF_TUN ("iff-debug", &opt_iff_debug)
628 /*IF_TUN ("iff-dynamic", &opt_iff_dynamic)*/
629 IF_TUN ("iff-loopback", &opt_iff_loopback)
630 IF_TUN ("iff-master", &opt_iff_master)
631 IF_TUN ("iff-multicast", &opt_iff_multicast)
632 IF_TUN ("iff-no-pi", &opt_iff_no_pi)
633 IF_TUN ("iff-noarp", &opt_iff_noarp)
634 IF_TUN ("iff-notrailers", &opt_iff_notrailers)
635 IF_TUN ("iff-pointopoint", &opt_iff_pointopoint)
636 IF_TUN ("iff-portsel", &opt_iff_portsel)
637 IF_TUN ("iff-promisc", &opt_iff_promisc)
638 IF_TUN ("iff-running", &opt_iff_running)
639 IF_TUN ("iff-slave", &opt_iff_slave)
640 IF_TUN ("iff-up", &opt_iff_up)
641 IF_TERMIOS("ignbrk", &opt_ignbrk)
642 IF_TERMIOS("igncr", &opt_igncr)
643 /* you might need to terminate socat manually if you use this option: */
644 IF_PROXY ("ignorecr", &opt_ignorecr)
645 IF_ANY ("ignoreeof", &opt_ignoreeof)
646 IF_ANY ("ignoreof", &opt_ignoreeof)
647 IF_TERMIOS("ignpar", &opt_ignpar)
648 #if HAVE_RESOLV_H
649 IF_IP ("igntc", &opt_res_igntc)
650 #endif /* HAVE_RESOLV_H */
651 IF_TERMIOS("imaxbel", &opt_imaxbel)
652 #if WITH_FS && defined(FS_IMMUTABLE_FL)
653 IF_ANY ("immutable", &opt_fs_immutable)
654 #endif
655 #ifdef TCP_INFO /* Linux 2.4.0 */
656 IF_TCP ("info", &opt_tcp_info)
657 #endif
658 IF_TERMIOS("inlcr", &opt_inlcr)
659 IF_TERMIOS("inpck", &opt_inpck)
660 #ifdef SO_BINDTODEVICE
661 IF_SOCKET ("interface", &opt_so_bindtodevice)
662 #endif
663 IF_RETRY ("interval", &opt_intervall)
664 IF_RETRY ("intervall", &opt_intervall)
665 IF_TERMIOS("intr", &opt_vintr)
666 IF_ANY ("ioctl", &opt_ioctl_void)
667 IF_ANY ("ioctl-bin", &opt_ioctl_bin)
668 IF_ANY ("ioctl-int", &opt_ioctl_int)
669 IF_ANY ("ioctl-intp", &opt_ioctl_intp)
670 IF_ANY ("ioctl-string", &opt_ioctl_string)
671 IF_ANY ("ioctl-void", &opt_ioctl_void)
672 #ifdef IP_ADD_MEMBERSHIP
673 IF_IP ("ip-add-membership", &opt_ip_add_membership)
674 #endif
675 #ifdef IP_ADD_SOURCE_MEMBERSHIP
676 IF_IP ("ip-add-source-membership", &opt_ip_add_source_membership)
677 #endif
678 #ifdef IP_FREEBIND
679 IF_IP ("ip-freebind", &opt_ip_freebind)
680 #endif
681 #ifdef IP_HDRINCL
682 IF_IP ("ip-hdrincl", &opt_ip_hdrincl)
683 #endif
684 #ifdef IP_ADD_MEMBERSHIP
685 IF_IP ("ip-membership", &opt_ip_add_membership)
686 #endif
687 #ifdef IP_MTU
688 IF_IP ("ip-mtu", &opt_ip_mtu)
689 #endif
690 #ifdef IP_MTU_DISCOVER
691 IF_IP ("ip-mtu-discover", &opt_ip_mtu_discover)
692 #endif
693 IF_IP ("ip-multicast-if", &opt_ip_multicast_if)
694 IF_IP ("ip-multicast-loop", &opt_ip_multicast_loop)
695 IF_IP ("ip-multicast-ttl", &opt_ip_multicast_ttl)
696 #ifdef IP_OPTIONS
697 IF_IP ("ip-options", &opt_ip_options)
698 #endif
699 #ifdef IP_PKTINFO
700 IF_IP ("ip-pktinfo", &opt_ip_pktinfo)
701 #endif
702 #ifdef IP_PKTOPTIONS
703 IF_IP ("ip-pktoptions", &opt_ip_pktoptions)
704 #endif
705 #ifdef IP_RECVDSTADDR
706 IF_IP ("ip-recvdstaddr", &opt_ip_recvdstaddr)
707 #endif
708 #ifdef IP_RECVERR
709 IF_IP ("ip-recverr", &opt_ip_recverr)
710 #endif
711 #ifdef IP_RECVIF
712 IF_IP ("ip-recvif", &opt_ip_recvif)
713 #endif
714 #ifdef IP_RECVOPTS
715 IF_IP ("ip-recvopts", &opt_ip_recvopts)
716 #endif
717 #ifdef IP_RECVTOS
718 IF_IP ("ip-recvtos", &opt_ip_recvtos)
719 #endif
720 #ifdef IP_RECVTTL
721 IF_IP ("ip-recvttl", &opt_ip_recvttl)
722 #endif
723 #ifdef IP_RETOPTS
724 IF_IP ("ip-retopts", &opt_ip_retopts)
725 #endif
726 #ifdef IP_ROUTER_ALERT
727 IF_IP ("ip-router-alert", &opt_ip_router_alert)
728 #endif
729 IF_IP ("ip-tos", &opt_ip_tos)
730 #ifdef IP_TRANSPARENT
731 IF_IP ("ip-transparent", &opt_ip_transparent)
732 #endif
733 IF_IP ("ip-ttl", &opt_ip_ttl)
734 #ifdef IP_FREEBIND
735 IF_IP ("ipfreebind", &opt_ip_freebind)
736 #endif
737 #ifdef IP_HDRINCL
738 IF_IP ("iphdrincl", &opt_ip_hdrincl)
739 #endif
740 #ifdef IP_MTU
741 IF_IP ("ipmtu", &opt_ip_mtu)
742 #endif
743 #ifdef IP_MTU_DISCOVER
744 IF_IP ("ipmtudiscover", &opt_ip_mtu_discover)
745 #endif
746 IF_IP ("ipmulticastloop", &opt_ip_multicast_loop)
747 IF_IP ("ipmulticastttl", &opt_ip_multicast_ttl)
748 #ifdef IP_OPTIONS
749 IF_IP ("ipoptions", &opt_ip_options)
750 #endif
751 #ifdef IP_PKTINFO
752 IF_IP ("ippktinfo", &opt_ip_pktinfo)
753 #endif
754 #ifdef IP_PKTOPTIONS
755 IF_IP ("ippktoptions", &opt_ip_pktoptions)
756 #endif
757 #ifdef IP_RECVDSTADDR
758 IF_IP ("iprecvdstaddr", &opt_ip_recvdstaddr)
759 #endif
760 #ifdef IP_RECVERR
761 IF_IP ("iprecverr", &opt_ip_recverr)
762 #endif
763 #ifdef IP_RECVOPTS
764 IF_IP ("iprecvopts", &opt_ip_recvopts)
765 #endif
766 #ifdef IP_RECVTOS
767 IF_IP ("iprecvtos", &opt_ip_recvtos)
768 #endif
769 #ifdef IP_RECVTTL
770 IF_IP ("iprecvttl", &opt_ip_recvttl)
771 #endif
772 #ifdef IP_RETOPTS
773 IF_IP ("ipretopts", &opt_ip_retopts)
774 #endif
775 #ifdef IP_ROUTER_ALERT
776 IF_IP ("iprouteralert", &opt_ip_router_alert)
777 #endif
778 IF_IP ("iptos", &opt_ip_tos)
779 IF_IP ("ipttl", &opt_ip_ttl)
780 #ifdef IPV6_JOIN_GROUP
781 IF_IP6 ("ipv6-add-membership", &opt_ipv6_join_group)
782 #endif
783 #ifdef IPV6_AUTHHDR
784 IF_IP6 ("ipv6-authhdr", &opt_ipv6_authhdr)
785 #endif
786 #ifdef IPV6_DSTOPTS
787 IF_IP6 ("ipv6-dstopts", &opt_ipv6_dstopts)
788 #endif
789 #ifdef IPV4_FLOWINFO
790 IF_IP6 ("ipv6-flowinfo", &opt_ipv6_flowinfo)
791 #endif
792 #ifdef IPV6_HOPLIMIT
793 IF_IP6 ("ipv6-hoplimit", &opt_ipv6_hoplimit)
794 #endif
795 #ifdef IPV6_HOPOPTS
796 IF_IP6 ("ipv6-hopopts", &opt_ipv6_hopopts)
797 #endif
798 #ifdef IPV6_JOIN_GROUP
799 IF_IP6 ("ipv6-join-group", &opt_ipv6_join_group)
800 #endif
801 #ifdef IPV6_PKTINFO
802 IF_IP6 ("ipv6-pktinfo", &opt_ipv6_pktinfo)
803 #endif
804 #ifdef IPV6_RECVDSTOPTS
805 IF_IP6 ("ipv6-recvdstopts", &opt_ipv6_recvdstopts)
806 #endif
807 #ifdef IPV6_RECVERR
808 IF_IP6 ("ipv6-recverr", &opt_ipv6_recverr)
809 #endif
810 #ifdef IPV6_RECVHOPLIMIT
811 IF_IP6 ("ipv6-recvhoplimit", &opt_ipv6_recvhoplimit)
812 #endif
813 #ifdef IPV6_RECVHOPOPTS
814 IF_IP6 ("ipv6-recvhopopts", &opt_ipv6_recvhopopts)
815 #endif
816 #ifdef IPV6_PATHMTU
817 IF_IP6 ("ipv6-recvpathmtu", &opt_ipv6_recvpathmtu)
818 #endif
819 #ifdef IPV6_RECVPKTINFO
820 IF_IP6 ("ipv6-recvpktinfo", &opt_ipv6_recvpktinfo)
821 #endif
822 #ifdef IPV6_RECVRTHDR
823 IF_IP6 ("ipv6-recvrthdr", &opt_ipv6_recvrthdr)
824 #endif
825 #ifdef IPV6_RECVTCLASS
826 IF_IP6 ("ipv6-recvtclass", &opt_ipv6_recvtclass)
827 #endif
828 #ifdef IPV6_RTHDR
829 IF_IP6 ("ipv6-rthdr", &opt_ipv6_rthdr)
830 #endif
831 #ifdef IPV6_TCLASS
832 IF_IP6 ("ipv6-tclass", &opt_ipv6_tclass)
833 #endif
834 IF_IP6 ("ipv6-unicast-hops", &opt_ipv6_unicast_hops)
835 #ifdef IPV6_V6ONLY
836 IF_IP6 ("ipv6-v6only", &opt_ipv6_v6only)
837 IF_IP6 ("ipv6only", &opt_ipv6_v6only)
838 #endif
839 IF_TERMIOS("isig", &opt_isig)
840 #if HAVE_TERMIOS_ISPEED
841 IF_TERMIOS("ispeed", &opt_ispeed)
842 #endif
843 IF_TERMIOS("istrip", &opt_istrip)
844 #ifdef IUCLC
845 IF_TERMIOS("iuclc", &opt_iuclc)
846 #endif
847 IF_TERMIOS("ixany", &opt_ixany)
848 IF_TERMIOS("ixoff", &opt_ixoff)
849 IF_TERMIOS("ixon", &opt_ixon)
850 #ifdef IPV6_JOIN_GROUP
851 IF_IP6 ("join-group", &opt_ipv6_join_group)
852 #endif
853 #if WITH_FS && defined(FS_JOURNAL_DATA_FL)
854 IF_ANY ("journal", &opt_fs_journal_data)
855 IF_ANY ("journal-data", &opt_fs_journal_data)
856 #endif
857 IF_SOCKET ("keepalive", &opt_so_keepalive)
858 #ifdef TCP_KEEPCNT /* Linux 2.4.0 */
859 IF_TCP ("keepcnt", &opt_tcp_keepcnt)
860 #endif
861 #ifdef TCP_KEEPIDLE /* Linux 2.4.0 */
862 IF_TCP ("keepidle", &opt_tcp_keepidle)
863 #endif
864 #ifdef TCP_KEEPINIT /* OSF1 */
865 IF_TCP ("keepinit", &opt_tcp_keepinit)
866 #endif
867 #ifdef TCP_KEEPINTVL /* Linux 2.4.0 */
868 IF_TCP ("keepintvl", &opt_tcp_keepintvl)
869 #endif
870 #ifdef SO_KERNACCEPT /* AIX 4.3.3 */
871 IF_SOCKET ("kernaccept", &opt_so_kernaccept)
872 #endif /* SO_KERNACCEPT */
873 IF_OPENSSL("key", &opt_openssl_key)
874 IF_TERMIOS("kill", &opt_vkill)
875 #ifdef O_LARGEFILE
876 IF_OPEN ("largefile", &opt_o_largefile)
877 #endif
878 #if WITH_LIBWRAP
879 IF_IPAPP ("libwrap", &opt_tcpwrappers)
880 #endif
881 IF_SOCKET ("linger", &opt_so_linger)
882 #ifdef TCP_LINGER2 /* Linux 2.4.0 */
883 IF_TCP ("linger2", &opt_tcp_linger2)
884 #endif
885 IF_PTY ("link", &opt_symbolic_link)
886 IF_SOCKET ("listen-timeout", &opt_accept_timeout)
887 IF_TERMIOS("lnext", &opt_vlnext)
888 #if defined(F_SETLKW)
889 IF_ANY ("lock", &opt_f_setlkw_wr) /* POSIX, first choice */
890 #elif defined(HAVE_FLOCK)
891 IF_ANY ("lock", &opt_flock_ex) /* BSD, fallback */
892 #endif
893 IF_ANY ("lockfile", &opt_lockfile)
894 #if defined(F_SETLKW)
895 IF_ANY ("lockw", &opt_f_setlkw_wr) /* POSIX, first choice */
896 #elif defined(HAVE_FLOCK)
897 IF_ANY ("lockw", &opt_flock_ex_nb) /* BSD, fallback */
898 #endif
899 IF_EXEC ("login", &opt_dash)
900 IF_TUN ("loopback", &opt_iff_loopback)
901 IF_IPAPP ("lowport", &opt_lowport)
902 #if HAVE_LSEEK64
903 IF_ANY ("lseek", &opt_lseek64_set)
904 #else
905 IF_ANY ("lseek", &opt_lseek32_set)
906 #endif
907 IF_ANY ("lseek32", &opt_lseek32_set)
908 IF_ANY ("lseek32-cur", &opt_lseek32_cur)
909 IF_ANY ("lseek32-end", &opt_lseek32_end)
910 IF_ANY ("lseek32-set", &opt_lseek32_set)
911 #if HAVE_LSEEK64
912 IF_ANY ("lseek64", &opt_lseek64_set)
913 IF_ANY ("lseek64-cur", &opt_lseek64_cur)
914 IF_ANY ("lseek64-end", &opt_lseek64_end)
915 IF_ANY ("lseek64-set", &opt_lseek64_set)
916 #endif
917 IF_TUN ("master", &opt_iff_master)
918 IF_LISTEN ("max-children", &opt_max_children)
919 #if HAVE_SSL_set_max_proto_version || defined(SSL_set_max_proto_version)
920 IF_OPENSSL("max-version", &opt_openssl_max_proto_version)
921 #endif
922 IF_LISTEN ("maxchildren", &opt_max_children)
923 #ifdef TCP_MAXSEG
924 IF_TCP ("maxseg", &opt_tcp_maxseg)
925 IF_TCP ("maxseg-late", &opt_tcp_maxseg_late)
926 #endif
927 #ifdef TCP_MD5SUM
928 IF_TCP ("md5sig", &opt_tcp_md5sig)
929 #endif
930 #ifdef IP_ADD_MEMBERSHIP
931 IF_IP ("membership", &opt_ip_add_membership)
932 #endif
933 #if WITH_OPENSSL_METHOD
934 IF_OPENSSL("method", &opt_openssl_method)
935 #endif
936 IF_TERMIOS("min", &opt_vmin)
937 #if HAVE_SSL_set_min_proto_version || defined(SSL_set_min_proto_version)
938 IF_OPENSSL("min-version", &opt_openssl_min_proto_version)
939 #endif
940 IF_ANY ("mode", &opt_perm)
941 #ifdef TCP_MAXSEG
942 IF_TCP ("mss", &opt_tcp_maxseg)
943 IF_TCP ("mss-late", &opt_tcp_maxseg_late)
944 #endif
945 #ifdef IP_MTU
946 IF_IP ("mtu", &opt_ip_mtu)
947 #endif
948 #ifdef IP_MTU_DISCOVER
949 IF_IP ("mtudiscover", &opt_ip_mtu_discover)
950 #endif
951 IF_TUN ("multicast", &opt_iff_multicast)
952 IF_IP ("multicast-if", &opt_ip_multicast_if)
953 IF_IP ("multicast-loop", &opt_ip_multicast_loop)
954 IF_IP ("multicast-ttl", &opt_ip_multicast_ttl)
955 IF_IP ("multicastloop", &opt_ip_multicast_loop)
956 IF_IP ("multicastttl", &opt_ip_multicast_ttl)
957 #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK)
958 IF_ANY ("ndelay", &opt_o_ndelay)
959 #else
960 IF_ANY ("ndelay", &opt_nonblock)
961 #endif
962 IF_NAMED ("new", &opt_unlink_early)
963 #ifdef NLDLY
964 # ifdef NL0
965 IF_TERMIOS("nl0", &opt_nl0)
966 # endif
967 # ifdef NL1
968 IF_TERMIOS("nl1", &opt_nl1)
969 # endif
970 IF_TERMIOS("nldly", &opt_nldly)
971 #endif /* defined(NLDLY) */
972 #ifdef SO_NO_CHECK
973 IF_SOCKET ("no-check", &opt_so_no_check)
974 #endif
975 IF_TUN ("no-pi", &opt_iff_no_pi)
976 #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
977 IF_OPENSSL("no-sni", &opt_openssl_no_sni)
978 #endif
979 IF_TUN ("noarp", &opt_iff_noarp)
980 #ifdef O_NOATIME
981 IF_OPEN ("noatime", &opt_o_noatime)
982 #endif
983 #ifdef SO_NO_CHECK
984 IF_SOCKET ("nocheck", &opt_so_no_check)
985 #endif
986 IF_OPEN ("noctty", &opt_o_noctty)
987 #ifdef TCP_NODELAY
988 IF_TCP ("nodelay", &opt_tcp_nodelay)
989 #endif
990 #if WITH_FS && defined(FS_NODUMP_FL)
991 IF_ANY ("nodump", &opt_fs_nodump)
992 #endif
993 #if HAVE_REGEX_H
994 IF_READLINE("noecho", &opt_noecho)
995 #endif /* HAVE_REGEX_H */
996 IF_TERMIOS("noflsh", &opt_noflsh)
997 #ifdef O_NOFOLLOW
998 IF_OPEN ("nofollow", &opt_o_nofollow)
999 #endif
1000 IF_EXEC ("nofork", &opt_nofork)
1001 #ifdef O_NOINHERIT
1002 IF_ANY ("noinherit", &opt_o_noinherit)
1003 #endif
1004 IF_ANY ("nonblock", &opt_nonblock)
1005 #ifdef TCP_NOOPT
1006 IF_TCP ("noopt", &opt_tcp_noopt)
1007 #endif
1008 IF_READLINE("noprompt", &opt_noprompt)
1009 #ifdef TCP_NOPUSH
1010 IF_TCP ("nopush", &opt_tcp_nopush)
1011 #endif
1012 #ifdef SO_NOREUSEADDR /* AIX 4.3.3 */
1013 IF_SOCKET ("noreuseaddr", &opt_so_noreuseaddr)
1014 #endif /* SO_NOREUSEADDR */
1015 #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
1016 IF_OPENSSL("nosni", &opt_openssl_no_sni)
1017 #endif
1018 IF_TUN ("notrailers", &opt_iff_notrailers)
1019 #ifdef O_NSHARE
1020 IF_OPEN ("nshare", &opt_o_nshare)
1021 #endif
1022 IF_SOCKET ("null-eof", &opt_null_eof)
1023 IF_ANY ("o-append", &opt_append)
1024 #ifdef O_ASYNC
1025 IF_ANY ("o-async", &opt_async)
1026 #endif
1027 #ifdef O_BINARY
1028 IF_OPEN ("o-binary", &opt_o_binary)
1029 #endif
1030 IF_OPEN ("o-creat", &opt_o_create)
1031 IF_OPEN ("o-create", &opt_o_create)
1032 #ifdef O_DEFER
1033 IF_OPEN ("o-defer", &opt_o_defer)
1034 #endif
1035 #ifdef O_DELAY
1036 IF_OPEN ("o-delay", &opt_o_delay)
1037 #endif
1038 #ifdef O_DIRECT
1039 IF_OPEN ("o-direct", &opt_o_direct)
1040 #endif
1041 #ifdef O_DIRECTORY
1042 IF_OPEN ("o-directory", &opt_o_directory)
1043 #endif
1044 #ifdef O_DSYNC
1045 IF_OPEN ("o-dsync", &opt_o_dsync)
1046 #endif
1047 IF_OPEN ("o-excl", &opt_o_excl)
1048 #ifdef O_LARGEFILE
1049 IF_OPEN ("o-largefile", &opt_o_largefile)
1050 #endif
1051 #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK)
1052 IF_ANY ("o-ndelay", &opt_o_ndelay)
1053 #else
1054 IF_ANY ("o-ndelay", &opt_nonblock)
1055 #endif
1056 #ifdef O_NOATIME
1057 IF_OPEN ("o-noatime", &opt_o_noatime)
1058 #endif
1059 IF_OPEN ("o-noctty", &opt_o_noctty)
1060 #ifdef O_NOFOLLOW
1061 IF_OPEN ("o-nofollow", &opt_o_nofollow)
1062 #endif
1063 #ifdef O_NOINHERIT
1064 IF_ANY ("o-noinherit", &opt_o_noinherit)
1065 #endif
1066 IF_ANY ("o-nonblock", &opt_nonblock)
1067 #ifdef O_NSHARE
1068 IF_OPEN ("o-nshare", &opt_o_nshare)
1069 #endif
1070 #ifdef O_PRIV
1071 IF_OPEN ("o-priv", &opt_o_priv)
1072 #endif
1073 IF_OPEN ("o-rdonly", &opt_o_rdonly)
1074 IF_OPEN ("o-rdwr", &opt_o_rdwr)
1075 #ifdef O_RSHARE
1076 IF_OPEN ("o-rshare", &opt_o_rshare)
1077 #endif
1078 #ifdef O_RSYNC
1079 IF_OPEN ("o-rsync", &opt_o_rsync)
1080 #endif
1081 #ifdef O_SYNC
1082 IF_OPEN ("o-sync", &opt_o_sync)
1083 #endif
1084 #ifdef O_TEXT
1085 IF_ANY ("o-text", &opt_o_text)
1086 #endif
1087 IF_OPEN ("o-trunc", &opt_o_trunc)
1088 IF_OPEN ("o-wronly", &opt_o_wronly)
1089 IF_OPEN ("o_create", &opt_o_create)
1090 #ifdef O_DEFER
1091 IF_OPEN ("o_defer", &opt_o_defer)
1092 #endif
1093 #ifdef O_DELAY
1094 IF_OPEN ("o_delay", &opt_o_delay)
1095 #endif
1096 #ifdef O_DIRECT
1097 IF_OPEN ("o_direct", &opt_o_direct)
1098 #endif
1099 #ifdef O_DIRECTORY
1100 IF_OPEN ("o_directory", &opt_o_directory)
1101 #endif
1102 #ifdef O_DSYNC
1103 IF_OPEN ("o_dsync", &opt_o_dsync)
1104 #endif
1105 IF_OPEN ("o_excl", &opt_o_excl)
1106 #ifdef O_LARGEFILE
1107 IF_OPEN ("o_largefile", &opt_o_largefile)
1108 #endif
1109 #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK)
1110 IF_ANY ("o_ndelay", &opt_o_ndelay)
1111 #else
1112 IF_ANY ("o_ndelay", &opt_nonblock)
1113 #endif
1114 IF_OPEN ("o_noctty", &opt_o_noctty)
1115 #ifdef O_NOFOLLOW
1116 IF_OPEN ("o_nofollow", &opt_o_nofollow)
1117 #endif
1118 #ifdef O_NSHARE
1119 IF_OPEN ("o_nshare", &opt_o_nshare)
1120 #endif
1121 #ifdef O_PRIV
1122 IF_OPEN ("o_priv", &opt_o_priv)
1123 #endif
1124 IF_OPEN ("o_rdonly", &opt_o_rdonly)
1125 IF_OPEN ("o_rdwr", &opt_o_rdwr)
1126 #ifdef O_RSHARE
1127 IF_OPEN ("o_rshare", &opt_o_rshare)
1128 #endif
1129 #ifdef O_RSYNC
1130 IF_OPEN ("o_rsync", &opt_o_rsync)
1131 #endif
1132 #ifdef O_SYNC
1133 IF_OPEN ("o_sync", &opt_o_sync)
1134 #endif
1135 IF_OPEN ("o_wronly", &opt_o_wronly)
1136 #ifdef OCRNL
1137 IF_TERMIOS("ocrnl", &opt_ocrnl)
1138 #endif
1139 #ifdef OFDEL
1140 IF_TERMIOS("ofdel", &opt_ofdel)
1141 #endif
1142 #ifdef OFILL
1143 IF_TERMIOS("ofill", &opt_ofill)
1144 #endif
1145 #ifdef OLCUC
1146 IF_TERMIOS("olcuc", &opt_olcuc)
1147 #endif
1148 IF_TERMIOS("onlcr", &opt_onlcr)
1149 #ifdef ONLRET
1150 IF_TERMIOS("onlret", &opt_onlret)
1151 #endif
1152 #ifdef ONOCR
1153 IF_TERMIOS("onocr", &opt_onocr)
1154 #endif
1155 IF_SOCKET ("oobinline", &opt_so_oobinline)
1156 #if HAVE_OPENPTY
1157 IF_EXEC ("openpty", &opt_openpty)
1158 #endif /* HAVE_OPENPTY */
1159 IF_OPENSSL("openssl-cafile", &opt_openssl_cafile)
1160 IF_OPENSSL("openssl-capath", &opt_openssl_capath)
1161 IF_OPENSSL("openssl-certificate", &opt_openssl_certificate)
1162 IF_OPENSSL("openssl-cipherlist", &opt_openssl_cipherlist)
1163 IF_OPENSSL("openssl-commonname", &opt_openssl_commonname)
1164 #if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_COMP)
1165 IF_OPENSSL("openssl-compress", &opt_openssl_compress)
1166 #endif
1167 IF_OPENSSL("openssl-dhparam", &opt_openssl_dhparam)
1168 IF_OPENSSL("openssl-dhparams", &opt_openssl_dhparam)
1169 IF_OPENSSL("openssl-egd", &opt_openssl_egd)
1170 #if WITH_FIPS
1171 IF_OPENSSL("openssl-fips", &opt_openssl_fips)
1172 #endif
1173 IF_OPENSSL("openssl-key", &opt_openssl_key)
1174 #if HAVE_SSL_set_max_proto_version || defined(SSL_set_max_proto_version)
1175 IF_OPENSSL("openssl-max-proto-version", &opt_openssl_max_proto_version)
1176 #endif
1177 #if WITH_OPENSSL_METHOD
1178 IF_OPENSSL("openssl-method", &opt_openssl_method)
1179 #endif
1180 #if HAVE_SSL_set_min_proto_version || defined(SSL_set_min_proto_version)
1181 IF_OPENSSL("openssl-min-proto-version", &opt_openssl_min_proto_version)
1182 #endif
1183 #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
1184 IF_OPENSSL("openssl-no-sni", &opt_openssl_no_sni)
1185 #endif
1186 IF_OPENSSL("openssl-pseudo", &opt_openssl_pseudo)
1187 #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
1188 IF_OPENSSL("openssl-snihost", &opt_openssl_snihost)
1189 #endif
1190 IF_OPENSSL("openssl-verify", &opt_openssl_verify)
1191 IF_TERMIOS("opost", &opt_opost)
1192 #if HAVE_TERMIOS_OSPEED
1193 IF_TERMIOS("ospeed", &opt_ospeed)
1194 #endif
1195 IF_ANY ("owner", &opt_user)
1196 IF_TERMIOS("parenb", &opt_parenb)
1197 IF_TERMIOS("parmrk", &opt_parmrk)
1198 IF_TERMIOS("parodd", &opt_parodd)
1199 #ifdef SO_PASSCRED
1200 IF_SOCKET ("passcred", &opt_so_passcred)
1201 #endif
1202 IF_EXEC ("path", &opt_path)
1203 #ifdef TCP_PAWS /* OSF1 */
1204 IF_TCP ("paws", &opt_tcp_paws)
1205 #endif
1206 #ifdef SO_PEERCRED
1207 IF_SOCKET ("peercred", &opt_so_peercred)
1208 #endif
1209 #ifdef PENDIN
1210 IF_TERMIOS("pendin", &opt_pendin)
1211 #endif
1212 IF_ANY ("perm", &opt_perm)
1213 IF_NAMED ("perm-early", &opt_perm_early)
1214 IF_ANY ("perm-late", &opt_perm_late)
1215 IF_SOCKET ("pf", &opt_protocol_family)
1216 IF_EXEC ("pgid", &opt_setpgid)
1217 IF_EXEC ("pipes", &opt_pipes)
1218 #ifdef IP_PKTINFO
1219 IF_IP ("pktinfo", &opt_ip_pktinfo)
1220 #endif
1221 #ifdef IP_PKTOPTIONS
1222 IF_IP ("pktoptions", &opt_ip_pktoptions)
1223 IF_IP ("pktopts", &opt_ip_pktoptions)
1224 #endif
1225 IF_TUN ("pointopoint", &opt_iff_pointopoint)
1226 #ifdef I_POP
1227 IF_ANY ("pop-all", &opt_streams_i_pop_all)
1228 #endif
1229 /*IF_IPAPP("port", &opt_port)*/
1230 IF_TUN ("portsel", &opt_iff_portsel)
1231 #if HAVE_RESOLV_H && WITH_RES_PRIMARY
1232 IF_IP ("primary", &opt_res_primary)
1233 #endif
1234 #ifdef SO_PRIORITY
1235 IF_SOCKET ("priority", &opt_so_priority)
1236 #endif
1237 #ifdef O_PRIV
1238 IF_OPEN ("priv", &opt_o_priv)
1239 #endif
1240 IF_TUN ("promisc", &opt_iff_promisc)
1241 IF_READLINE("prompt", &opt_prompt)
1242 #ifdef SO_PROTOTYPE
1243 IF_SOCKET ("protocol", &opt_so_prototype)
1244 #endif
1245 IF_SOCKET ("protocol-family", &opt_protocol_family)
1246 #ifdef SO_PROTOTYPE
1247 IF_SOCKET ("prototype", &opt_so_prototype)
1248 #endif
1249 IF_PROXY ("proxy-auth", &opt_proxy_authorization)
1250 IF_PROXY ("proxy-authorization", &opt_proxy_authorization)
1251 IF_PROXY ("proxy-resolve", &opt_proxy_resolve)
1252 IF_PROXY ("proxyauth", &opt_proxy_authorization)
1253 IF_PROXY ("proxyport", &opt_proxyport)
1254 #ifdef ECHOPRT
1255 IF_TERMIOS("prterase", &opt_echoprt)
1256 #endif
1257 IF_OPENSSL("pseudo", &opt_openssl_pseudo)
1258 #if HAVE_DEV_PTMX || HAVE_DEV_PTC
1259 IF_EXEC ("ptmx", &opt_ptmx)
1260 #endif
1261 #if HAVE_PTY
1262 IF_EXEC ("pty", &opt_pty)
1263 #endif
1264 #if HAVE_PTY && HAVE_POLL
1265 IF_PTY ("pty-interval", &opt_pty_intervall)
1266 IF_PTY ("pty-intervall", &opt_pty_intervall)
1267 IF_PTY ("pty-wait-slave", &opt_pty_wait_slave)
1268 #endif /* HAVE_PTY && HAVE_POLL */
1269 #ifdef I_PUSH
1270 IF_ANY ("push", &opt_streams_i_push)
1271 #endif
1272 #ifdef TCP_QUICKACK
1273 IF_TCP ("quickack", &opt_tcp_quickack)
1274 #endif
1275 IF_TERMIOS("quit", &opt_vquit)
1276 IF_RANGE ("range", &opt_range)
1277 IF_TERMIOS("raw", &opt_raw)
1278 IF_TERMIOS("rawer", &opt_termios_rawer)
1279 IF_SOCKET ("rcvbuf", &opt_so_rcvbuf)
1280 IF_SOCKET ("rcvbuf-late", &opt_so_rcvbuf_late)
1281 #ifdef SO_RCVLOWAT
1282 IF_SOCKET ("rcvlowat", &opt_so_rcvlowat)
1283 #endif
1284 IF_OPEN ("rdonly", &opt_o_rdonly)
1285 IF_OPEN ("rdwr", &opt_o_rdwr)
1286 IF_ANY ("readbytes", &opt_readbytes)
1287 #if HAVE_RESOLV_H
1288 IF_IP ("recurse", &opt_res_recurse)
1289 #endif /* HAVE_RESOLV_H */
1290 #ifdef IP_RECVDSTADDR
1291 IF_IP ("recvdstaddr", &opt_ip_recvdstaddr)
1292 #endif
1293 #ifdef IPV6_RECVDSTOPTS
1294 IF_IP6 ("recvdstopts", &opt_ipv6_recvdstopts)
1295 #endif
1296 #ifdef IP_RECVERR
1297 IF_IP ("recverr", &opt_ip_recverr)
1298 #endif
1299 #ifdef IPV6_RECVHOPLIMIT
1300 IF_IP6 ("recvhoplimit", &opt_ipv6_recvhoplimit)
1301 #endif
1302 #ifdef IPV6_RECVHOPOPTS
1303 IF_IP6 ("recvhopopts", &opt_ipv6_recvhopopts)
1304 #endif
1305 #ifdef IP_RECVIF
1306 IF_IP ("recvif", &opt_ip_recvif)
1307 #endif
1308 #ifdef IP_RECVOPTS
1309 IF_IP ("recvopts", &opt_ip_recvopts)
1310 #endif
1311 #ifdef IPV6_RECVPKTINFO
1312 IF_IP6 ("recvpktinfo", &opt_ipv6_recvpktinfo)
1313 #endif
1314 #ifdef IPV6_RECVRTHDR
1315 IF_IP6 ("recvrthdr", &opt_ipv6_recvrthdr)
1316 #endif
1317 #ifdef IP_RECVTOS
1318 IF_IP ("recvtos", &opt_ip_recvtos)
1319 #endif
1320 #ifdef IP_RECVTTL
1321 IF_IP ("recvttl", &opt_ip_recvttl)
1322 #endif
1323 IF_NAMED ("remove", &opt_unlink)
1324 #ifdef VREPRINT
1325 IF_TERMIOS("reprint", &opt_vreprint)
1326 #endif
1327 #if HAVE_RESOLV_H
1328 # if WITH_AA_ONLY
1329 IF_IP ("res-aaonly", &opt_res_aaonly)
1330 # endif
1331 IF_IP ("res-debug", &opt_res_debug)
1332 IF_IP ("res-defnames", &opt_res_defnames)
1333 IF_IP ("res-dnsrch", &opt_res_dnsrch)
1334 IF_IP ("res-igntc", &opt_res_igntc)
1335 # if WITH_RES_PRIMARY
1336 IF_IP ("res-primary", &opt_res_primary)
1337 # endif
1338 IF_IP ("res-recurse", &opt_res_recurse)
1339 IF_IP ("res-stayopen", &opt_res_stayopen)
1340 IF_IP ("res-usevc", &opt_res_usevc)
1341 #endif /* HAVE_RESOLV_H */
1342 IF_PROXY ("resolv", &opt_proxy_resolve)
1343 IF_PROXY ("resolve", &opt_proxy_resolve)
1344 #ifdef IP_RETOPTS
1345 IF_IP ("retopts", &opt_ip_retopts)
1346 #endif
1347 IF_RETRY ("retry", &opt_retry)
1348 IF_SOCKET ("reuseaddr", &opt_so_reuseaddr)
1349 #ifdef SO_REUSEPORT /* AIX 4.3.3 */
1350 IF_SOCKET ("reuseport", &opt_so_reuseport)
1351 #endif /* defined(SO_REUSEPORT) */
1352 #ifdef TCP_RFC1323
1353 IF_TCP ("rfc1323", &opt_tcp_rfc1323)
1354 #endif
1355 #ifdef IP_ROUTER_ALERT
1356 IF_IP ("routeralert", &opt_ip_router_alert)
1357 #endif
1358 #ifdef VREPRINT
1359 IF_TERMIOS("rprnt", &opt_vreprint)
1360 #endif
1361 #ifdef O_RSHARE
1362 IF_OPEN ("rshare", &opt_o_rshare)
1363 #endif
1364 #ifdef O_RSYNC
1365 IF_OPEN ("rsync", &opt_o_rsync)
1366 #endif
1367 #ifdef IPV6_RTHDR
1368 IF_IP6 ("rthdr", &opt_ipv6_rthdr)
1369 #endif
1370 IF_TUN ("running", &opt_iff_running)
1371 #ifdef TCP_SACK_DISABLE
1372 IF_TCP ("sack-disable", &opt_tcp_sack_disable)
1373 #endif
1374 #ifdef TCP_SACKENA /* OSF1 */
1375 IF_TCP ("sackena", &opt_tcp_sackena)
1376 #endif
1377 IF_TERMIOS("sane", &opt_sane)
1378 #ifdef SCTP_MAXSEG
1379 IF_SCTP ("sctp-maxseg", &opt_sctp_maxseg)
1380 IF_SCTP ("sctp-maxseg-late", &opt_sctp_maxseg_late)
1381 #endif
1382 #ifdef SCTP_NODELAY
1383 IF_SCTP ("sctp-nodelay", &opt_sctp_nodelay)
1384 #endif
1385 #if WITH_FS && defined(FS_SECRM_FL)
1386 IF_ANY ("secrm", &opt_fs_secrm)
1387 #endif
1388 #ifdef SO_SECURITY_AUTHENTICATION
1389 IF_SOCKET ("security-authentication", &opt_so_security_authentication)
1390 #endif
1391 #ifdef SO_SECURITY_ENCRYPTION_NETWORK
1392 IF_SOCKET ("security-encryption-network", &opt_so_security_encryption_network)
1393 #endif
1394 #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
1395 IF_SOCKET ("security-encryption-transport", &opt_so_security_encryption_transport)
1396 #endif
1397 #ifdef SO_SECURITY_AUTHENTICATION
1398 IF_SOCKET ("securityauthentication", &opt_so_security_authentication)
1399 #endif
1400 #ifdef SO_SECURITY_ENCRYPTION_NETWORK
1401 IF_SOCKET ("securityencryptionnetwork", &opt_so_security_encryption_network)
1402 #endif
1403 #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
1404 IF_SOCKET ("securityencryptiontransport", &opt_so_security_encryption_transport)
1405 #endif
1406 #if HAVE_LSEEK64
1407 IF_ANY ("seek", &opt_lseek64_set)
1408 IF_ANY ("seek-cur", &opt_lseek64_cur)
1409 IF_ANY ("seek-end", &opt_lseek64_end)
1410 IF_ANY ("seek-set", &opt_lseek64_set)
1411 #else
1412 IF_ANY ("seek", &opt_lseek32_set)
1413 IF_ANY ("seek-cur", &opt_lseek32_cur)
1414 IF_ANY ("seek-end", &opt_lseek32_end)
1415 IF_ANY ("seek-set", &opt_lseek32_set)
1416 #endif
1417 IF_ANY ("setgid", &opt_setgid)
1418 IF_ANY ("setgid-early", &opt_setgid_early)
1419 IF_ANY ("setlk", &opt_f_setlk_wr)
1420 IF_ANY ("setlk-rd", &opt_f_setlk_rd)
1421 IF_ANY ("setlk-wr", &opt_f_setlk_wr)
1422 IF_ANY ("setlkw", &opt_f_setlkw_wr)
1423 IF_ANY ("setlkw-rd", &opt_f_setlkw_rd)
1424 IF_ANY ("setlkw-wr", &opt_f_setlkw_wr)
1425 IF_EXEC ("setpgid", &opt_setpgid)
1426 #if WITH_EXEC || WITH_SYSTEM
1427 IF_EXEC ("setsid", &opt_setsid)
1428 #endif
1429 IF_SOCKET ("setsockopt", &opt_setsockopt)
1430 IF_SOCKET ("setsockopt-bin", &opt_setsockopt_bin)
1431 IF_SOCKET ("setsockopt-int", &opt_setsockopt_int)
1432 IF_SOCKET ("setsockopt-listen", &opt_setsockopt_listen)
1433 IF_SOCKET ("setsockopt-string", &opt_setsockopt_string)
1434 IF_ANY ("setuid", &opt_setuid)
1435 IF_ANY ("setuid-early", &opt_setuid_early)
1436 IF_ANY ("shut-close", &opt_shut_close)
1437 IF_ANY ("shut-down", &opt_shut_down)
1438 IF_ANY ("shut-none", &opt_shut_none)
1439 IF_ANY ("shut-null", &opt_shut_null)
1440 #if WITH_EXEC || WITH_SYSTEM
1441 IF_ANY ("sid", &opt_setsid)
1442 #endif
1443 IF_EXEC ("sighup", &opt_sighup)
1444 IF_EXEC ("sigint", &opt_sigint)
1445 #ifdef TCP_SIGNATURE_ENABLE
1446 IF_TCP ("signature-enable", &opt_tcp_signature_enable)
1447 #endif
1448 IF_EXEC ("sigquit", &opt_sigquit)
1449 #ifdef SIOCSPGRP
1450 IF_SOCKET ("siocspgrp", &opt_siocspgrp)
1451 #endif
1452 IF_TUN ("slave", &opt_iff_slave)
1453 IF_SOCKET ("sndbuf", &opt_so_sndbuf)
1454 IF_SOCKET ("sndbuf-late", &opt_so_sndbuf_late)
1455 #ifdef SO_SNDLOWAT
1456 IF_SOCKET ("sndlowat", &opt_so_sndlowat)
1457 #endif
1458 #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
1459 IF_OPENSSL("snihost", &opt_openssl_snihost)
1460 #endif
1461 #ifdef SO_ACCEPTCONN /* AIX433 */
1462 IF_SOCKET ("so-acceptconn", &opt_so_acceptconn)
1463 #endif /* SO_ACCEPTCONN */
1464 #ifdef SO_ATTACH_FILTER
1465 IF_SOCKET ("so-attach-filter", &opt_so_attach_filter)
1466 #endif
1467 #ifdef SO_AUDIT /* AIX 4.3.3 */
1468 IF_SOCKET ("so-audit", &opt_so_audit)
1469 #endif /* SO_AUDIT */
1470 #ifdef SO_BINDTODEVICE
1471 IF_SOCKET ("so-bindtodevice", &opt_so_bindtodevice)
1472 #endif
1473 IF_SOCKET ("so-broadcast", &opt_so_broadcast)
1474 #ifdef SO_BSDCOMPAT
1475 IF_SOCKET ("so-bsdcompat", &opt_so_bsdcompat)
1476 #endif
1477 #ifdef SO_CKSUMRECV
1478 IF_SOCKET ("so-cksumrecv", &opt_so_cksumrecv)
1479 #endif /* SO_CKSUMRECV */
1480 IF_SOCKET ("so-debug", &opt_so_debug)
1481 #ifdef SO_DETACH_FILTER
1482 IF_SOCKET ("so-detach-filter", &opt_so_detach_filter)
1483 #endif
1484 #ifdef SO_DGRAM_ERRIND
1485 IF_SOCKET ("so-dgram-errind", &opt_so_dgram_errind)
1486 #endif
1487 #ifdef SO_DONTLINGER
1488 IF_SOCKET ("so-dontlinger", &opt_so_dontlinger)
1489 #endif
1490 IF_SOCKET ("so-dontroute", &opt_so_dontroute)
1491 IF_SOCKET ("so-error", &opt_so_error)
1492 IF_SOCKET ("so-keepalive", &opt_so_keepalive)
1493 #ifdef SO_KERNACCEPT /* AIX 4.3.3 */
1494 IF_SOCKET ("so-kernaccept", &opt_so_kernaccept)
1495 #endif /* SO_KERNACCEPT */
1496 IF_SOCKET ("so-linger", &opt_so_linger)
1497 #ifdef SO_NO_CHECK
1498 IF_SOCKET ("so-no-check", &opt_so_no_check)
1499 #endif
1500 #ifdef SO_NOREUSEADDR /* AIX 4.3.3 */
1501 IF_SOCKET ("so-noreuseaddr", &opt_so_noreuseaddr)
1502 #endif /* SO_NOREUSEADDR */
1503 IF_SOCKET ("so-oobinline", &opt_so_oobinline)
1504 #ifdef SO_PASSCRED
1505 IF_SOCKET ("so-passcred", &opt_so_passcred)
1506 #endif
1507 #ifdef SO_PEERCRED
1508 IF_SOCKET ("so-peercred", &opt_so_peercred)
1509 #endif
1510 #ifdef SO_PRIORITY
1511 IF_SOCKET ("so-priority", &opt_so_priority)
1512 #endif
1513 #ifdef SO_PROTOTYPE
1514 IF_SOCKET ("so-prototype", &opt_so_prototype)
1515 #endif
1516 IF_SOCKET ("so-rcvbuf", &opt_so_rcvbuf)
1517 IF_SOCKET ("so-rcvbuf-late", &opt_so_rcvbuf_late)
1518 #ifdef SO_RCVLOWAT
1519 IF_SOCKET ("so-rcvlowat", &opt_so_rcvlowat)
1520 #endif
1521 IF_SOCKET ("so-reuseaddr", &opt_so_reuseaddr)
1522 #ifdef SO_REUSEPORT /* AIX 4.3.3 */
1523 IF_SOCKET ("so-reuseport", &opt_so_reuseport)
1524 #endif /* defined(SO_REUSEPORT) */
1525 #ifdef SO_SECURITY_AUTHENTICATION
1526 IF_SOCKET ("so-security-authentication", &opt_so_security_authentication)
1527 #endif
1528 #ifdef SO_SECURITY_ENCRYPTION_NETWORK
1529 IF_SOCKET ("so-security-encryption-network", &opt_so_security_encryption_network)
1530 #endif
1531 #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
1532 IF_SOCKET ("so-security-encryption-transport", &opt_so_security_encryption_transport)
1533 #endif
1534 IF_SOCKET ("so-sndbuf", &opt_so_sndbuf)
1535 IF_SOCKET ("so-sndbuf-late", &opt_so_sndbuf_late)
1536 #ifdef SO_SNDLOWAT
1537 IF_SOCKET ("so-sndlowat", &opt_so_sndlowat)
1538 #endif
1539 #ifdef SO_TIMESTAMP
1540 IF_SOCKET ("so-timestamp", &opt_so_timestamp)
1541 #endif
1542 IF_SOCKET ("so-type", &opt_so_type)
1543 #ifdef SO_USE_IFBUFS
1544 IF_SOCKET ("so-use-ifbufs", &opt_so_use_ifbufs)
1545 #endif /* SO_USE_IFBUFS */
1546 #ifdef SO_USELOOPBACK /* AIX433, Solaris */
1547 IF_SOCKET ("so-useloopback", &opt_so_useloopback)
1548 #endif /* SO_USELOOPBACK */
1549 IF_SOCKET ("sockopt", &opt_setsockopt)
1550 IF_SOCKET ("sockopt-bin", &opt_setsockopt_bin)
1551 IF_SOCKET ("sockopt-int", &opt_setsockopt_int)
1552 IF_SOCKET ("sockopt-listen", &opt_setsockopt_listen)
1553 IF_SOCKET ("sockopt-string", &opt_setsockopt_string)
1554 IF_SOCKS4 ("socksport", &opt_socksport)
1555 IF_SOCKS4 ("socksuser", &opt_socksuser)
1556 IF_SOCKET ("socktype", &opt_so_type)
1557 #ifdef IP_ADD_SOURCE_MEMBERSHIP
1558 IF_IP ("source-membership", &opt_ip_add_source_membership)
1559 #endif
1560 IF_IPAPP ("sourceport", &opt_sourceport)
1561 IF_IPAPP ("sp", &opt_sourceport)
1562 IF_TERMIOS("start", &opt_vstart)
1563 #if HAVE_RESOLV_H
1564 IF_IP ("stayopen", &opt_res_stayopen)
1565 #endif /* HAVE_RESOLV_H */
1566 IF_EXEC ("stderr", &opt_stderr)
1567 #ifdef TCP_STDURG
1568 IF_TCP ("stdurg", &opt_tcp_stdurg)
1569 #endif
1570 IF_TERMIOS("stop", &opt_vstop)
1571 #ifdef I_POP
1572 IF_ANY ("streams-i-pop-all", &opt_streams_i_pop_all)
1573 #endif
1574 #ifdef I_PUSH
1575 IF_ANY ("streams-i-push", &opt_streams_i_push)
1576 #endif
1577 IF_ANY ("su", &opt_substuser)
1578 #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
1579 IF_ANY ("su-d", &opt_substuser_delayed)
1580 #endif
1581 IF_ANY ("su-e", &opt_substuser_early)
1582 IF_ANY ("substuser", &opt_substuser)
1583 #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
1584 IF_ANY ("substuser-delayed", &opt_substuser_delayed)
1585 #endif
1586 IF_ANY ("substuser-early", &opt_substuser_early)
1587 IF_TERMIOS("susp", &opt_vsusp)
1588 #ifdef VSWTC
1589 IF_TERMIOS("swtc", &opt_vswtc)
1590 IF_TERMIOS("swtch", &opt_vswtc)
1591 #endif
1592 IF_PTY ("symbolic-link", &opt_symbolic_link)
1593 #ifdef O_SYNC
1594 IF_OPEN ("sync", &opt_o_sync)
1595 #elif FS_SYNC_FL
1596 IF_ANY ("sync", &opt_fs_sync)
1597 #endif
1598 #ifdef TCP_SYNCNT
1599 IF_TCP ("syncnt", &opt_tcp_syncnt)
1600 #endif
1601 #ifdef TABDLY
1602 # ifdef TAB0
1603 IF_TERMIOS("tab0", &opt_tab0)
1604 # endif
1605 # ifdef TAB1
1606 IF_TERMIOS("tab1", &opt_tab1)
1607 # endif
1608 # ifdef TAB2
1609 IF_TERMIOS("tab2", &opt_tab2)
1610 # endif
1611 # ifdef TAB3
1612 IF_TERMIOS("tab3", &opt_tab3)
1613 # endif
1614 # if TABDLY_SHIFT >= 0
1615 IF_TERMIOS("tabdly", &opt_tabdly)
1616 # endif
1617 #endif
1618 IF_TERMIOS("tandem", &opt_ixoff)
1619 #ifdef TCP_ABORT_THRESHOLD /* HP_UX */
1620 IF_TCP ("tcp-abort-threshold", &opt_tcp_abort_threshold)
1621 #endif
1622 #ifdef TCP_CONN_ABORT_THRESHOLD /* HP_UX */
1623 IF_TCP ("tcp-conn-abort-threshold", &opt_tcp_conn_abort_threshold)
1624 #endif
1625 #ifdef TCP_CORK
1626 IF_TCP ("tcp-cork", &opt_tcp_cork)
1627 #endif
1628 #ifdef TCP_DEFER_ACCEPT /* Linux 2.4.0 */
1629 IF_TCP ("tcp-defer-accept", &opt_tcp_defer_accept)
1630 #endif
1631 #ifdef TCP_INFO /* Linux 2.4.0 */
1632 IF_TCP ("tcp-info", &opt_tcp_info)
1633 #endif
1634 #ifdef TCP_KEEPCNT /* Linux 2.4.0 */
1635 IF_TCP ("tcp-keepcnt", &opt_tcp_keepcnt)
1636 #endif
1637 #ifdef TCP_KEEPIDLE /* Linux 2.4.0 */
1638 IF_TCP ("tcp-keepidle", &opt_tcp_keepidle)
1639 #endif
1640 #ifdef TCP_KEEPINIT /* OSF1 */
1641 IF_TCP ("tcp-keepinit", &opt_tcp_keepinit)
1642 #endif
1643 #ifdef TCP_KEEPINTVL /* Linux 2.4.0 */
1644 IF_TCP ("tcp-keepintvl", &opt_tcp_keepintvl)
1645 #endif
1646 #ifdef TCP_LINGER2 /* Linux 2.4.0 */
1647 IF_TCP ("tcp-linger2", &opt_tcp_linger2)
1648 #endif
1649 #ifdef TCP_MAXSEG
1650 IF_TCP ("tcp-maxseg", &opt_tcp_maxseg)
1651 IF_TCP ("tcp-maxseg-late", &opt_tcp_maxseg_late)
1652 #endif
1653 #ifdef TCP_MD5SIG
1654 IF_TCP ("tcp-md5sig", &opt_tcp_md5sig)
1655 #endif
1656 #ifdef TCP_NODELAY
1657 IF_TCP ("tcp-nodelay", &opt_tcp_nodelay)
1658 #endif
1659 #ifdef TCP_NOOPT
1660 IF_TCP ("tcp-noopt", &opt_tcp_noopt)
1661 #endif
1662 #ifdef TCP_NOPUSH
1663 IF_TCP ("tcp-nopush", &opt_tcp_nopush)
1664 #endif
1665 #ifdef TCP_PAWS /* OSF1 */
1666 IF_TCP ("tcp-paws", &opt_tcp_paws)
1667 #endif
1668 #ifdef TCP_QUICKACK
1669 IF_TCP ("tcp-quickack", &opt_tcp_quickack)
1670 #endif
1671 #ifdef TCP_RFC1323
1672 IF_TCP ("tcp-rfc1323", &opt_tcp_rfc1323)
1673 #endif
1674 #ifdef TCP_SACK_DISABLE
1675 IF_TCP ("tcp-sack-disable", &opt_tcp_sack_disable)
1676 #endif
1677 #ifdef TCP_SACKENA /* OSF1 */
1678 IF_TCP ("tcp-sackena", &opt_tcp_sackena)
1679 #endif
1680 #ifdef TCP_SIGNATURE_ENABLE
1681 IF_TCP ("tcp-signature-enable", &opt_tcp_signature_enable)
1682 #endif
1683 #ifdef TCP_STDURG
1684 IF_TCP ("tcp-stdurg", &opt_tcp_stdurg)
1685 #endif
1686 #ifdef TCP_SYNCNT /* Linux 2.4.0 */
1687 IF_TCP ("tcp-syncnt", &opt_tcp_syncnt)
1688 #endif
1689 #ifdef TCP_TSOPTENA /* OSF1 */
1690 IF_TCP ("tcp-tsoptena", &opt_tcp_tsoptena)
1691 #endif
1692 #ifdef TCP_WINDOW_CLAMP /* Linux 2.4.0 */
1693 IF_TCP ("tcp-window-clamp", &opt_tcp_window_clamp)
1694 #endif
1695 #if WITH_LIBWRAP
1696 IF_IPAPP ("tcpwrap", &opt_tcpwrappers)
1697 IF_IPAPP ("tcpwrap-dir", &opt_tcpwrap_etc)
1698 IF_IPAPP ("tcpwrap-etc", &opt_tcpwrap_etc)
1699 #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE)
1700 IF_IPAPP ("tcpwrap-hosts-allow-table", &opt_tcpwrap_hosts_allow_table)
1701 #endif
1702 #if WITH_LIBWRAP && defined(HAVE_HOSTS_DENY_TABLE)
1703 IF_IPAPP ("tcpwrap-hosts-deny-table", &opt_tcpwrap_hosts_deny_table)
1704 #endif
1705 IF_IPAPP ("tcpwrapper", &opt_tcpwrappers)
1706 IF_IPAPP ("tcpwrappers", &opt_tcpwrappers)
1707 #endif
1708 IF_TERMIOS("termios-cfmakeraw", &opt_termios_cfmakeraw)
1709 IF_TERMIOS("termios-rawer", &opt_termios_rawer)
1710 #ifdef O_TEXT
1711 IF_ANY ("text", &opt_o_text)
1712 #endif
1713 IF_UNIX ("tightsocklen", &xioopt_unix_tightsocklen)
1714 IF_TERMIOS("time", &opt_vtime)
1715 #ifdef SO_TIMESTAMP
1716 IF_SOCKET ("timestamp", &opt_so_timestamp)
1717 #endif
1718 IF_TERMIOS("tiocsctty", &opt_tiocsctty)
1719 #if WITH_FS && defined(FS_TOPDIR_FL)
1720 IF_ANY ("topdir", &opt_fs_topdir)
1721 #endif
1722 IF_IP ("tos", &opt_ip_tos)
1723 IF_TERMIOS("tostop", &opt_tostop)
1724 #ifdef IP_TRANSPARENT
1725 IF_IP ("transparent", &opt_ip_transparent)
1726 #endif
1727 IF_OPEN ("trunc", &opt_o_trunc)
1728 #if HAVE_FTRUNCATE64
1729 IF_ANY ("truncate", &opt_ftruncate64)
1730 #else
1731 IF_ANY ("truncate", &opt_ftruncate32)
1732 #endif
1733 #ifdef TCP_TSOPTENA /* OSF1 */
1734 IF_TCP ("tsoptena", &opt_tcp_tsoptena)
1735 #endif
1736 IF_IP ("ttl", &opt_ip_ttl)
1737 IF_TUN ("tun-device", &opt_tun_device)
1738 IF_TUN ("tun-name", &opt_tun_name)
1739 IF_TUN ("tun-no-pi", &opt_iff_no_pi)
1740 IF_TUN ("tun-type", &opt_tun_type)
1741 IF_SOCKET ("type", &opt_so_type)
1742 IF_ANY ("uid", &opt_user)
1743 IF_NAMED ("uid-e", &opt_user_early)
1744 IF_ANY ("uid-l", &opt_user_late)
1745 IF_NAMED ("umask", &opt_umask)
1746 IF_IP6 ("unicast-hops", &opt_ipv6_unicast_hops)
1747 IF_UNIX ("unix-tightsocklen", &xioopt_unix_tightsocklen)
1748 IF_NAMED ("unlink", &opt_unlink)
1749 IF_NAMED ("unlink-close", &opt_unlink_close)
1750 IF_NAMED ("unlink-early", &opt_unlink_early)
1751 IF_NAMED ("unlink-late", &opt_unlink_late)
1752 #if WITH_FS && defined(FS_UNRM_FL)
1753 IF_ANY ("unrm", &opt_fs_unrm)
1754 #endif
1755 IF_TUN ("up", &opt_iff_up)
1756 #ifdef SO_USE_IFBUFS
1757 IF_SOCKET ("use-ifbufs", &opt_so_use_ifbufs)
1758 IF_SOCKET ("useifbufs", &opt_so_use_ifbufs)
1759 #endif /* SO_USE_IFBUFS */
1760 #ifdef SO_USELOOPBACK /* AIX433, Solaris */
1761 IF_SOCKET ("useloopback", &opt_so_useloopback)
1762 #endif /* SO_USELOOPBACK */
1763 IF_ANY ("user", &opt_user)
1764 IF_NAMED ("user-early", &opt_user_early)
1765 IF_ANY ("user-late", &opt_user_late)
1766 #if HAVE_RESOLV_H
1767 IF_IP ("usevc", &opt_res_usevc)
1768 #endif /* HAVE_RESOLV_H */
1769 #ifdef IPV6_V6ONLY
1770 IF_IP6 ("v6only", &opt_ipv6_v6only)
1771 #endif
1772 #ifdef VDISCARD
1773 IF_TERMIOS("vdiscard", &opt_vdiscard)
1774 #endif
1775 #ifdef VDSUSP /* HP-UX */
1776 IF_TERMIOS("vdsusp", &opt_vdsusp)
1777 #endif
1778 IF_TERMIOS("veof", &opt_veof)
1779 IF_TERMIOS("veol", &opt_veol)
1780 IF_TERMIOS("veol2", &opt_veol2)
1781 IF_TERMIOS("verase", &opt_verase)
1782 IF_OPENSSL("verify", &opt_openssl_verify)
1783 IF_TERMIOS("vintr", &opt_vintr)
1784 IF_TERMIOS("vkill", &opt_vkill)
1785 IF_TERMIOS("vlnext", &opt_vlnext)
1786 IF_TERMIOS("vmin", &opt_vmin)
1787 IF_TERMIOS("vquit", &opt_vquit)
1788 #ifdef VREPRINT
1789 IF_TERMIOS("vreprint", &opt_vreprint)
1790 #endif
1791 IF_TERMIOS("vstart", &opt_vstart)
1792 IF_TERMIOS("vstop", &opt_vstop)
1793 IF_TERMIOS("vsusp", &opt_vsusp)
1794 #ifdef VSWTC
1795 IF_TERMIOS("vswtc", &opt_vswtc)
1796 #endif
1797 #ifdef VTDLY
1798 # ifdef VT0
1799 IF_TERMIOS("vt0", &opt_vt0)
1800 # endif
1801 # ifdef VT1
1802 IF_TERMIOS("vt1", &opt_vt1)
1803 # endif
1804 IF_TERMIOS("vtdly", &opt_vtdly)
1805 #endif
1806 IF_TERMIOS("vtime", &opt_vtime)
1807 #ifdef VWERASE
1808 IF_TERMIOS("vwerase", &opt_vwerase)
1809 #endif
1810 #if HAVE_PTY && HAVE_POLL
1811 IF_PTY ("wait-slave", &opt_pty_wait_slave)
1812 #endif /* HAVE_PTY && HAVE_POLL */
1813 IF_ANY ("waitlock", &opt_waitlock)
1814 #if HAVE_PTY && HAVE_POLL
1815 IF_PTY ("waitslave", &opt_pty_wait_slave)
1816 #endif /* HAVE_PTY && HAVE_POLL */
1817 #ifdef VWERASE
1818 IF_TERMIOS("werase", &opt_vwerase)
1819 #endif
1820 #ifdef TCP_WINDOW_CLAMP /* Linux 2.4.0 */
1821 IF_TCP ("window-clamp", &opt_tcp_window_clamp)
1822 #endif
1823 #if WITH_LIBWRAP
1824 IF_IPAPP ("wrap", &opt_tcpwrappers)
1825 #endif
1826 IF_OPEN ("wronly", &opt_o_wronly)
1827 #ifdef XCASE
1828 IF_TERMIOS("xcase", &opt_xcase)
1829 #endif
1830 #if defined(TABDLY) && defined(XTABS)
1831 IF_TERMIOS("xtabs", &opt_xtabs)
1832 #endif
1833 { NULL }
1837 /* walks the text argument a and writes its options that conform to groups
1838 to the array opts. Uses the option table 'optionnames'.
1839 returns 0 on success, -1 on error, 1 on unknown/wrong option
1841 int parseopts(const char **a, unsigned int groups, struct opt **opts) {
1843 return parseopts_table(a, groups, opts, optionnames,
1844 sizeof(optionnames)/sizeof(struct optname)-1);
1848 /* walks the text argument a and writes its options that conform to groups
1849 to the array opts. Uses the specified option table.
1850 returns 0 on success, -1 on error, 1 on unknown/wrong option
1852 int parseopts_table(const char **a, unsigned int groups, struct opt **opts,
1853 const struct optname optionnames[], size_t optionnum) {
1854 int i=0;
1855 struct opt *opt;
1856 bool assign;
1857 const char *a0 = *a;
1858 unsigned long ulongval;
1859 long slongval;
1860 long long slonglongval;
1861 char token[2048], *tokp; size_t len;
1862 int parsres;
1863 int result;
1864 uint8_t optbuf[256]; size_t optlen;
1865 const char *endkey[6+1];
1866 const char *endval[5+1];
1867 const char *assign_str = "=";
1868 const char *hquotes[] = {
1869 "'",
1870 NULL
1872 const char *squotes[] = {
1873 "\"",
1874 NULL
1876 const char *nests[] = {
1877 "(", ")",
1878 "[", "]",
1879 "{", "}",
1880 NULL
1883 i = 0;
1884 /*endkey[i++] = xioopts.chainsep;*/ /* default: "|" */
1885 endkey[i++] = xioopts.pipesep; /* default: "!!" */
1886 endkey[i++] = ","/*xioopts.comma*/; /* default: "," */
1887 endkey[i++] = "=";
1888 endkey[i++] = NULL;
1890 i = 0;
1891 /*endval[i++] = xioopts.chainsep;*/ /* default: "|" */
1892 endval[i++] = xioopts.pipesep; /* default: "!!" */
1893 endval[i++] = ","/*xioopts.comma*/; /* default: "," */
1894 endval[i++] = NULL;
1896 i = 0;
1897 *opts = Malloc((i+8)*sizeof(struct opt));
1898 if (*opts == NULL) {
1899 return -1;
1901 if (*a == NULL) {
1902 (*opts)[i].desc = ODESC_END;
1903 return 0;
1906 while (true) {
1907 const struct optname *ent;
1909 if (a == NULL || *a == NULL || **a == '\0')
1910 break;
1912 while (!strncmp(*a, ",", strlen(","))) { (*a) += strlen(","); }
1913 a0 = *a;
1915 len = sizeof(token); tokp = token;
1916 parsres =
1917 nestlex(a, &tokp, &len, endkey, hquotes, squotes, nests,
1918 true, true, false);
1919 if (parsres < 0) {
1920 Error1("option too long: \"%s\"", *a);
1921 return -1;
1922 } else if (parsres > 0) {
1923 Error1("syntax error in \"%s\"", *a);
1924 return -1;
1926 if (tokp == token) {
1927 /* no option found */
1928 break;
1930 *tokp = '\0';
1932 ent = (struct optname *)
1933 keyw((struct wordent *)optionnames, token, optionnum);
1934 if (ent == NULL) {
1935 Error1("parseopts_table(): unknown option \"%s\"", token);
1936 continue;
1939 if (!(ent->desc->group & groups) && !(ent->desc->group & GROUP_ANY) &&
1940 !xioopts_ignoregroups) {
1941 Error1("parseopts_table(): option \"%s\" not supported with this address type",
1942 token /*a0*/);
1943 Info2("parseopts_table() groups=%08x, ent->group=%08x",
1944 groups, ent->desc->group);
1945 #if 0
1946 continue;
1947 #endif
1949 (*opts)[i].desc = ent->desc;
1951 if (!strncmp(*a, assign_str, strlen(assign_str))) {
1952 /* there is an assignment (mostly "=") */
1953 (*a) += strlen(assign_str);
1954 len = sizeof(token); tokp = token;
1955 parsres =
1956 nestlex(a, &tokp, &len, endval, hquotes, squotes, nests,
1957 true, true, false);
1958 if (parsres < 0) {
1959 Error1("option too long: \"%s\"", *a);
1960 return -1;
1961 } else if (parsres > 0) {
1962 Error1("syntax error in \"%s\"", *a);
1963 return -1;
1965 *tokp = '\0';
1966 assign = true;
1968 } else {
1969 assign = false;
1971 opt = &(*opts)[i];
1973 switch (ent->desc->type) {
1974 case TYPE_CONST:
1975 if (assign) {
1976 Error1("no value permitted for option \"%s\"",
1977 ent->desc->defname);
1978 continue;
1980 Info1("setting option \"%s\"", ent->desc->defname);
1981 break;
1982 case TYPE_BIN:
1983 if (!assign) { Error1("option \"%s\": value required", a0);
1984 continue; }
1985 optlen = 0;
1986 if ((result = dalan(token, optbuf, &optlen, sizeof(optbuf), 'i')) != 0) {
1987 Error1("parseopts_table(): problem with \"%s\" data", token);
1988 continue;
1990 if (((*opts)[i].value.u_bin.b_data = memdup(optbuf, optlen)) == NULL) {
1991 Error1("memdup(, "F_Zu"): out of memory", optlen);
1992 return -1;
1994 (*opts)[i].value.u_bin.b_len = optlen;
1995 break;
1996 case TYPE_BYTE:
1997 if (assign) {
1998 unsigned long ul;
1999 char *rest;
2000 ul = strtoul(token, &rest/*!*/, 0);
2001 if (ul > UCHAR_MAX) {
2002 Error3("parseopts_table(%s): byte value exceeds limit (%lu vs. %u), using max",
2003 a0, ul, UCHAR_MAX);
2004 (*opts)[i].value.u_byte = UCHAR_MAX;
2005 } else {
2006 (*opts)[i].value.u_byte = ul;
2008 } else {
2009 (*opts)[i].value.u_byte = 1;
2011 Info2("setting option \"%s\" to %d", ent->desc->defname,
2012 (*opts)[i].value.u_byte);
2013 break;
2014 #if HAVE_BASIC_OFF_T==3
2015 case TYPE_OFF32:
2016 #endif
2017 case TYPE_INT:
2018 if (assign) {
2019 char *rest;
2020 (*opts)[i].value.u_int = strtoul(token, &rest/*!*/, 0);
2021 } else {
2022 (*opts)[i].value.u_int = 1;
2024 Info2("setting option \"%s\" to %d", ent->desc->defname,
2025 (*opts)[i].value.u_int);
2026 break;
2027 case TYPE_BOOL:
2028 if (!assign) {
2029 (*opts)[i].value.u_bool = 1;
2030 } else {
2031 char *rest;
2032 (*opts)[i].value.u_bool = strtoul(token, &rest, 0);
2033 if (rest && *rest) {
2034 Error1("error in option \"%s\": \"0\" or \"1\" required", a0);
2037 Info2("setting option \"%s\" to %d", ent->desc->defname,
2038 (*opts)[i].value.u_bool);
2039 break;
2041 #if HAVE_BASIC_SIZE_T==4
2042 case TYPE_SIZE_T:
2043 #endif
2044 case TYPE_UINT:
2045 if (!assign) {
2046 (*opts)[i].value.u_uint = 1;
2047 } else {
2048 char *rest;
2049 ulongval = strtoul(token, &rest/*!*/, 0);
2050 if (ulongval > UINT_MAX) {
2051 Error3("parseopts_table(%s): unsigned int value exceeds limit (%lu vs. %u), using max",
2052 a0, ulongval, UINT_MAX);
2054 (*opts)[i].value.u_uint = ulongval;
2056 Info2("setting option \"%s\" to %u", ent->desc->defname,
2057 (*opts)[i].value.u_uint);
2058 break;
2060 #if HAVE_BASIC_SIZE_T==2
2061 case TYPE_SIZE_T:
2062 #endif
2063 case TYPE_USHORT:
2064 if (!assign) {
2065 (*opts)[i].value.u_ushort = 1;
2066 } else {
2067 char *rest;
2068 ulongval = strtoul(token, &rest/*!*/, 0);
2069 if (ulongval > USHRT_MAX) {
2070 Error3("parseopts_table(%s): unsigned short value exceeds limit (%lu vs. %u), using max",
2071 a0, ulongval, USHRT_MAX);
2073 (*opts)[i].value.u_ushort = ulongval;
2075 Info2("setting option \"%s\" to %u", ent->desc->defname,
2076 (*opts)[i].value.u_ushort);
2077 break;
2079 #if HAVE_BASIC_OFF_T==5
2080 case TYPE_OFF32:
2081 #endif
2082 #if HAVE_STAT64 && defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T==5
2083 case TYPE_OFF64:
2084 #endif
2085 case TYPE_LONG:
2086 if (!assign) {
2087 (*opts)[i].value.u_long = 1;
2088 } else {
2089 char *rest;
2090 slongval = strtol(token, &rest, 0);
2091 (*opts)[i].value.u_long = slongval;
2093 Info2("setting option \"%s\" to %lu", ent->desc->defname,
2094 (*opts)[i].value.u_long);
2095 break;
2097 #if HAVE_BASIC_SIZE_T==6
2098 case TYPE_SIZE_T:
2099 #endif
2100 case TYPE_ULONG:
2101 if (!assign) {
2102 (*opts)[i].value.u_ulong = 1;
2103 } else {
2104 char *rest;
2105 ulongval = strtoul(token, &rest, 0);
2106 (*opts)[i].value.u_ulong = ulongval;
2108 Info2("setting option \"%s\" to %lu", ent->desc->defname,
2109 (*opts)[i].value.u_ulong);
2110 break;
2112 #if HAVE_BASIC_OFF_T==7
2113 case TYPE_OFF32:
2114 #endif
2115 #if HAVE_TYPE_LONGLONG
2116 case TYPE_LONGLONG:
2117 # if HAVE_STAT64 && defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T==7
2118 case TYPE_OFF64:
2119 # endif
2120 if (!assign) {
2121 (*opts)[i].value.u_longlong = 1;
2122 } else {
2123 char *rest;
2124 # if HAVE_STRTOLL
2125 slonglongval = strtoll(token, &rest, 0);
2126 # else
2127 /* in this case, input value range is limited */
2128 slonglongval = strtol(token, &rest, 0);
2129 # endif /* HAVE_STRTOLL */
2130 (*opts)[i].value.u_longlong = slonglongval;
2132 Info2("setting option \"%s\" to %Lu", ent->desc->defname,
2133 (*opts)[i].value.u_longlong);
2134 break;
2135 #endif /* HAVE_TYPE_LONGLONG */
2137 case TYPE_UIDT:
2138 if (!assign) {
2139 Error1("option \"%s\": value required", a0);
2140 continue;
2142 if (isdigit((*token)&0xff)) {
2143 char *rest;
2144 (*opts)[i].value.u_uidt = strtoul(token, &rest/*!*/, 0);
2145 } else {
2146 struct passwd *pwd;
2147 if ((pwd = getpwnam(token)) == NULL) {
2148 Error1("getpwnam(\"%s\"): no such user", token);
2149 continue;
2151 (*opts)[i].value.u_uidt = getpwnam(token)->pw_uid;
2153 Info2("setting option \"%s\" to %u", ent->desc->defname,
2154 (*opts)[i].value.u_uidt);
2155 break;
2157 case TYPE_GIDT:
2158 if (!assign) { Error1("option \"%s\": value required", a0);
2159 continue; }
2160 if (isdigit((token[0])&0xff)) {
2161 char *rest;
2162 (*opts)[i].value.u_gidt = strtoul(token, &rest/*!*/, 0);
2163 } else {
2164 struct group *grp;
2165 grp = getgrnam(token);
2166 if (grp == NULL) {
2167 Error1("getgrnam(\"%s\"): no such group", token);
2168 continue;
2170 (*opts)[i].value.u_gidt = grp->gr_gid;
2172 Info2("setting option \"%s\" to %u", ent->desc->defname,
2173 (*opts)[i].value.u_gidt);
2174 break;
2176 case TYPE_MODET:
2177 if (!assign) { Error1("option \"%s\": value required", a0);
2178 continue;
2181 char *rest;
2182 (*opts)[i].value.u_modet = strtoul(token, &rest/*!*/, 8);
2184 Info2("setting option \"%s\" to %u", ent->desc->defname,
2185 (*opts)[i].value.u_modet);
2186 break;
2188 case TYPE_STRING:
2189 if (!assign) {
2190 Error1("option \"%s\": value required", a0);
2191 continue;
2193 if (((*opts)[i].value.u_string = strdup(token)) == NULL) {
2194 Error("out of memory"); return -1;
2196 Info2("setting option \"%s\" to \"%s\"", ent->desc->defname,
2197 (*opts)[i].value.u_string);
2198 break;
2200 case TYPE_STRING_NULL:
2201 if (!assign) {
2202 (*opts)[i].value.u_string = NULL;
2203 Info1("setting option \"%s\" to NULL", ent->desc->defname);
2204 } else {
2205 (*opts)[i].value.u_string = strdup(token);
2206 Info2("setting option \"%s\" to \"%s\"", ent->desc->defname,
2207 (*opts)[i].value.u_string);
2209 break;
2211 #if LATER
2212 case TYPE_INT3:
2214 break;
2215 #endif
2217 case TYPE_TIMEVAL:
2218 if (!assign) {
2219 Error1("option \"%s\": value required", a0);
2220 continue;
2221 } else {
2222 double val;
2223 val = strtod(token, NULL);
2224 if (val == HUGE_VAL || val == -HUGE_VAL ||
2225 val == 0.0 && errno == ERANGE) {
2226 Error2("strtod(\"%s\", NULL): %s", token, strerror(errno));
2227 val = 0.0;
2229 (*opts)[i].value.u_timeval.tv_sec = val;
2230 (*opts)[i].value.u_timeval.tv_usec =
2231 (val-(*opts)[i].value.u_timeval.tv_sec+0.0000005) * 1000000;
2233 break;
2235 #if HAVE_STRUCT_TIMESPEC
2236 case TYPE_TIMESPEC:
2237 if (!assign) {
2238 Error1("option \"%s\": value required", a0);
2239 continue;
2240 } else {
2241 double val;
2242 val = strtod(token, NULL);
2243 if (val == HUGE_VAL || val == -HUGE_VAL ||
2244 val == 0.0 && errno == ERANGE) {
2245 Error2("strtod(\"%s\", NULL): %s", token, strerror(errno));
2246 val = 0.0;
2248 (*opts)[i].value.u_timespec.tv_sec = val;
2249 (*opts)[i].value.u_timespec.tv_nsec =
2250 (val-(*opts)[i].value.u_timespec.tv_sec) * 1000000000.;
2252 break;
2253 #endif /* HAVE_STRUCT_TIMESPEC */
2255 #if HAVE_STRUCT_LINGER
2256 case TYPE_LINGER:
2257 if (!assign) {
2258 Error1("option \"%s\": value required", a0);
2259 continue;
2261 (*opts)[i].value.u_linger.l_onoff = 1;
2263 char *rest;
2264 (*opts)[i].value.u_linger.l_linger = strtoul(token, &rest/*!*/, 0);
2266 Info3("setting option \"%s\" to {%d,%d}", ent->desc->defname,
2267 (*opts)[i].value.u_linger.l_onoff,
2268 (*opts)[i].value.u_linger.l_linger);
2269 break;
2270 #endif /* HAVE_STRUCT_LINGER */
2272 case TYPE_INT_INT:
2273 case TYPE_INT_INTP:
2274 if (!assign) {
2275 Error1("option \"%s\": values required", a0);
2276 continue;
2279 char *rest;
2280 (*opts)[i].value.u_int = strtoul(token, &rest, 0);
2281 if (*rest != ':') {
2282 Error1("option \"%s\": 2 arguments required",
2283 ent->desc->defname);
2285 ++rest;
2286 (*opts)[i].value2.u_int = strtoul(rest, &rest, 0);
2288 Info3("setting option \"%s\" to %d:%d", ent->desc->defname,
2289 (*opts)[i].value.u_int, (*opts)[i].value2.u_int);
2290 break;
2292 case TYPE_INT_BIN:
2293 if (!assign) {
2294 Error1("option \"%s\": values required", a0);
2295 continue;
2298 char *rest;
2299 (*opts)[i].value.u_int = strtoul(token, &rest, 0);
2300 if (*rest != ':') {
2301 Error1("option \"%s\": 2 arguments required",
2302 ent->desc->defname);
2304 ++rest;
2305 optlen = 0;
2306 if ((result = dalan(rest, optbuf, &optlen, sizeof(optbuf), 'i')) != 0) {
2307 Error1("parseopts_table(): problem with \"%s\" data", rest);
2308 continue;
2310 if (((*opts)[i].value2.u_bin.b_data = memdup(optbuf, optlen)) == NULL) {
2311 Error1("memdup(, "F_Zu"): out of memory", optlen);
2312 return -1;
2314 (*opts)[i].value2.u_bin.b_len = optlen;
2316 Info2("setting option \"%s\" to %d:..."/*!!!*/, ent->desc->defname,
2317 (*opts)[i].value.u_int);
2318 break;
2320 case TYPE_INT_STRING:
2321 if (!assign) {
2322 Error1("option \"%s\": values required", a0);
2323 continue;
2326 char *rest;
2327 (*opts)[i].value.u_int = strtoul(token, &rest, 0);
2328 if (*rest != ':') {
2329 Error1("option \"%s\": 2 arguments required",
2330 ent->desc->defname);
2332 ++rest;
2333 if (((*opts)[i].value2.u_string = strdup(rest)) == NULL) {
2334 Error("out of memory"); return -1;
2337 Info3("setting option \"%s\" to %d:\"%s\"", ent->desc->defname,
2338 (*opts)[i].value.u_int, (*opts)[i].value2.u_string);
2339 break;
2341 case TYPE_INT_INT_INT:
2342 if (!assign) {
2343 Error1("option \"%s\": values required", a0);
2344 continue;
2347 char *rest;
2348 (*opts)[i].value.u_int = strtoul(token, &rest, 0);
2349 if (*rest != ':') {
2350 Error1("option \"%s\": 3 arguments required",
2351 ent->desc->defname);
2353 ++rest;
2354 (*opts)[i].value2.u_int = strtoul(rest, &rest, 0);
2355 if (*rest != ':') {
2356 Error1("option \"%s\": 3 arguments required",
2357 ent->desc->defname);
2359 ++rest;
2360 (*opts)[i].value3.u_int = strtoul(rest, &rest, 0);
2362 Info4("setting option \"%s\" to %d:%d:%d", ent->desc->defname,
2363 (*opts)[i].value.u_int, (*opts)[i].value2.u_int, (*opts)[i].value3.u_int);
2364 break;
2366 case TYPE_INT_INT_BIN:
2367 case TYPE_INT_INT_GENERIC:
2368 if (!assign) {
2369 Error1("option \"%s\": values required", a0);
2370 continue;
2373 char *rest;
2374 (*opts)[i].value.u_int = strtoul(token, &rest, 0);
2375 if (*rest != ':') {
2376 Error1("option \"%s\": 3 arguments required",
2377 ent->desc->defname);
2379 ++rest;
2380 (*opts)[i].value2.u_int = strtoul(rest, &rest, 0);
2381 if (*rest != ':') {
2382 Error1("option \"%s\": 3 arguments required",
2383 ent->desc->defname);
2385 ++rest;
2386 optlen = 0;
2387 if ((result = dalan(rest, optbuf, &optlen, sizeof(optbuf), 'i')) != 0) {
2388 Error1("parseopts_table(): problem with \"%s\" data", rest);
2389 continue;
2391 if (((*opts)[i].value3.u_bin.b_data = memdup(optbuf, optlen)) == NULL) {
2392 Error1("memdup(, "F_Zu"): out of memory", optlen);
2393 return -1;
2395 (*opts)[i].value3.u_bin.b_len = optlen;
2397 Info3("setting option \"%s\" to %d:%d:..."/*!!!*/, ent->desc->defname,
2398 (*opts)[i].value.u_int, (*opts)[i].value2.u_int);
2399 break;
2401 case TYPE_INT_INT_STRING:
2402 if (!assign) {
2403 Error1("option \"%s\": values required", a0);
2404 continue;
2407 char *rest;
2408 (*opts)[i].value.u_int = strtoul(token, &rest, 0);
2409 if (*rest != ':') {
2410 Error1("option \"%s\": 3 arguments required",
2411 ent->desc->defname);
2413 ++rest;
2414 (*opts)[i].value2.u_int = strtoul(rest, &rest, 0);
2415 if (*rest != ':') {
2416 Error1("option \"%s\": 3 arguments required",
2417 ent->desc->defname);
2419 ++rest;
2420 if (((*opts)[i].value3.u_string = strdup(rest)) == NULL) {
2421 Error("out of memory"); return -1;
2424 Info4("setting option \"%s\" to %d:%d:\"%s\"", ent->desc->defname,
2425 (*opts)[i].value.u_int, (*opts)[i].value2.u_int,
2426 (*opts)[i].value3.u_string);
2427 break;
2428 #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)
2430 case TYPE_IP_MREQN:
2432 /* we do not resolve the addresses here because we do not yet know
2433 if we are coping with a IPv4 or IPv6 socat address */
2434 const char *ends[] = { ":", NULL };
2435 const char *nests[] = { "[","]", NULL };
2436 char buff[512], *buffp=buff; size_t bufspc = sizeof(buff)-1;
2438 /* parse first IP address, expect ':' */
2439 tokp = token;
2440 /*! result= */
2441 parsres =
2442 nestlex((const char **)&tokp, &buffp, &bufspc,
2443 ends, NULL, NULL, nests,
2444 true, false, false);
2445 if (parsres < 0) {
2446 Error1("option too long: \"%s\"", *a);
2447 return -1;
2448 } else if (parsres > 0) {
2449 Error1("syntax error in \"%s\"", *a);
2450 return -1;
2452 if (*tokp != ':') {
2453 Error1("syntax in option %s: missing ':'", token);
2455 *buffp++ = '\0';
2456 (*opts)[i].value.u_ip_mreq.multiaddr = strdup(buff); /*!!! NULL */
2458 ++tokp;
2459 /* parse second IP address, expect ':' or '\0'' */
2460 buffp = buff;
2461 /*! result= */
2462 parsres =
2463 nestlex((const char **)&tokp, &buffp, &bufspc,
2464 ends, NULL, NULL, nests,
2465 true, false, false);
2466 if (parsres < 0) {
2467 Error1("option too long: \"%s\"", *a);
2468 return -1;
2469 } else if (parsres > 0) {
2470 Error1("syntax error in \"%s\"", *a);
2471 return -1;
2473 *buffp++ = '\0';
2474 (*opts)[i].value.u_ip_mreq.param2 = strdup(buff); /*!!! NULL */
2476 #if HAVE_STRUCT_IP_MREQN
2477 if (*tokp++ == ':') {
2478 strncpy((*opts)[i].value.u_ip_mreq.ifindex, tokp, IF_NAMESIZE); /* ok */
2479 Info4("setting option \"%s\" to {\"%s\",\"%s\",\"%s\"}",
2480 ent->desc->defname,
2481 (*opts)[i].value.u_ip_mreq.multiaddr,
2482 (*opts)[i].value.u_ip_mreq.param2,
2483 (*opts)[i].value.u_ip_mreq.ifindex);
2484 } else {
2485 (*opts)[i].value.u_ip_mreq.ifindex[0] = '\0';
2486 Info3("setting option \"%s\" to {\"%s\",\"%s\"}",
2487 ent->desc->defname,
2488 (*opts)[i].value.u_ip_mreq.multiaddr,
2489 (*opts)[i].value.u_ip_mreq.param2);
2491 #else /* !HAVE_STRUCT_IP_MREQN */
2492 Info3("setting option \"%s\" to {0x%08x,0x%08x}",
2493 ent->desc->defname,
2494 (*opts)[i].value.u_ip_mreq.multiaddr,
2495 (*opts)[i].value.u_ip_mreq.param2);
2496 #endif /* !HAVE_STRUCT_IP_MREQN */
2498 break;
2499 #endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */
2501 case TYPE_IP_MREQ_SOURCE:
2502 xiotype_ip_add_source_membership(token, ent, opt);
2503 break;
2505 #if WITH_IP4
2506 case TYPE_IP4NAME:
2508 struct sockaddr_in sa; socklen_t salen = sizeof(sa);
2509 const char *ends[] = { NULL };
2510 const char *nests[] = { "[","]", NULL };
2511 char buff[512], *buffp=buff; size_t bufspc = sizeof(buff)-1;
2513 tokp = token;
2514 parsres =
2515 nestlex((const char **)&tokp, &buffp, &bufspc,
2516 ends, NULL, NULL, nests,
2517 true, false, false);
2518 if (parsres < 0) {
2519 Error1("option too long: \"%s\"", *a);
2520 return -1;
2521 } else if (parsres > 0) {
2522 Error1("syntax error in \"%s\"", *a);
2523 return -1;
2525 if (*tokp != '\0') {
2526 Error1("trailing data in option \"%s\"", token);
2528 *buffp = '\0';
2529 if (xiogetaddrinfo(buff, NULL, AF_INET, SOCK_DGRAM, IPPROTO_IP,
2530 (union sockaddr_union *)&sa, &salen,
2531 0, 0/*!!!*/) != STAT_OK) {
2532 opt->desc = ODESC_ERROR; continue;
2534 opt->value.u_ip4addr = sa.sin_addr;
2536 break;
2537 #endif /* defined(WITH_IP4) */
2539 case TYPE_GENERIC:
2540 if (!assign) {
2541 (*opts)[i].value.u_int = 1;
2542 } else {
2543 int rc;
2544 size_t binlen = 64; /*!!!*/
2545 if (((*opts[i]).value.u_bin.b_data = Malloc(binlen)) == NULL) Error("!!!");
2546 (*opts)[i].value.u_bin.b_len = 0;
2547 rc = dalan(token, (*opts)[i].value.u_bin.b_data,
2548 &(*opts)[i].value.u_bin.b_len, binlen, 'i');
2549 if (rc != 0) {
2550 Error("!!!");
2552 //(*opts)[i].value.u_bin.b_len
2554 break;
2556 default:
2557 Error2("parseopts_table(): internal error on option \"%s\": unimplemented type %d",
2558 ent->desc->defname, ent->desc->type);
2559 continue;
2562 ++i;
2563 if ((i % 8) == 0) {
2564 *opts = Realloc(*opts, (i+8) * sizeof(struct opt));
2565 if (*opts == NULL) {
2566 return -1;
2571 /*(*opts)[i+1].desc = ODESC_END;*/
2572 (*opts)[i].desc = ODESC_END;
2573 return 0;
2577 /* look for an option with the given properties
2578 return a pointer to the first matching valid option in the list
2579 Returns NULL when no matching option found */
2580 const struct opt *searchopt(const struct opt *opts, unsigned int groups, enum e_phase from, enum e_phase to,
2581 enum e_func func) {
2582 int i;
2584 if (!opts) return NULL;
2586 /* remember: struct opt are in an array */
2587 i = 0;
2588 while (opts[i].desc != ODESC_END) {
2589 if (opts[i].desc != ODESC_DONE &&
2590 (groups == 0 || (groups && (opts[i].desc->group&groups))) &&
2591 (from == 0 || (from <= opts[i].desc->phase)) &&
2592 (to == 0 || (opts[i].desc->phase <= to)) &&
2593 (func == 0 || (opts[i].desc->func == func))) {
2594 return &opts[i];
2596 ++i;
2598 return NULL;
2601 /* copy the already parsed options for repeated application, but only those
2602 matching groups ANY and <groups> */
2603 struct opt *copyopts(const struct opt *opts, unsigned int groups) {
2604 struct opt *new;
2605 int i, j, n;
2607 if (!opts) return NULL;
2609 /* just count the options in the array */
2610 i = 0; while (opts[i].desc != ODESC_END) {
2611 ++i;
2613 n = i+1;
2615 new = Malloc(n * sizeof(struct opt));
2616 if (new == NULL) {
2617 return NULL;
2620 i = 0, j = 0;
2621 while (i < n-1) {
2622 if (opts[i].desc == ODESC_DONE) {
2623 new[j].desc = ODESC_DONE;
2624 } else if ((opts[i].desc->group & (GROUP_ANY&~GROUP_PROCESS)) ||
2625 (opts[i].desc->group & groups)) {
2626 new[j++] = opts[i];
2628 ++i;
2630 new[j].desc = ODESC_END;
2631 return new;
2634 /* move options to a new options list
2635 move only those matching <groups> */
2636 struct opt *moveopts(struct opt *opts, unsigned int groups) {
2637 struct opt *new;
2638 int i, j, n;
2640 if (!opts) return NULL;
2642 /* just count the options in the array */
2643 i = 0; j = 0; while (opts[i].desc != ODESC_END) {
2644 if (opts[i].desc != ODESC_DONE &&
2645 opts[i].desc != ODESC_ERROR)
2646 ++j;
2647 ++i;
2649 n = i;
2651 new = Malloc((j+1) * sizeof(struct opt));
2652 if (new == NULL) {
2653 return NULL;
2656 i = 0, j = 0;
2657 while (i < n) {
2658 if (opts[i].desc == ODESC_DONE ||
2659 opts[i].desc == ODESC_ERROR) {
2660 ++i; continue;
2661 } else if (opts[i].desc->group & groups) {
2662 new[j++] = opts[i];
2663 opts[i].desc = ODESC_DONE;
2665 ++i;
2667 new[j].desc = ODESC_END;
2668 return new;
2671 /* return the number of yet unconsumed options; -1 on error */
2672 int leftopts(const struct opt *opts) {
2673 const struct opt *opt = opts;
2674 int num = 0;
2676 if (!opts) return 0;
2678 while (opt->desc != ODESC_END) {
2679 if (opt->desc != ODESC_DONE) {
2680 ++num;
2682 ++opt;
2684 return num;
2687 /* show as warning which options are still unused */
2688 int showleft(const struct opt *opts) {
2689 const struct opt *opt = opts;
2691 while (opt->desc != ODESC_END) {
2692 if (opt->desc != ODESC_DONE) {
2693 Warn1("showleft(): option \"%s\" not inquired", opt->desc->defname);
2695 ++opt;
2697 return 0;
2701 /* determines the address group from mode_t */
2702 /* does not set GROUP_FD; cannot determine GROUP_TERMIOS ! */
2703 int _groupbits(mode_t mode) {
2704 unsigned int result = 0;
2706 switch ((mode&S_IFMT)>>12) {
2707 case (S_IFIFO>>12): /* 1, FIFO */
2708 result = GROUP_FIFO; break;
2709 case (S_IFCHR>>12): /* 2, character device */
2710 result = GROUP_CHR|GROUP_TERMIOS; break;
2711 case (S_IFDIR>>12): /* 4, directory !!! not supported */
2712 result = GROUP_NONE; break;
2713 case (S_IFBLK>>12): /* 6, block device */
2714 result = GROUP_BLK; break;
2715 case (S_IFREG>>12): /* 8, regular file */
2716 result = GROUP_REG; break;
2717 case (S_IFLNK>>12): /* 10, symbolic link !!! not supported */
2718 result = GROUP_NONE; break;
2719 #ifdef S_IFSOCK
2720 case (S_IFSOCK>>12): /* 12, socket */
2721 result = GROUP_SOCKET|GROUP_SOCK_UNIX; break;
2722 #else
2723 default: /* some systems (pure POSIX.1) do not know S_IFSOCK */
2724 result = GROUP_SOCKET|GROUP_SOCK_UNIX; break;
2725 #endif
2727 Debug2("_groupbits(%d) -> %d", mode, result);
2728 return result;
2731 /* does not set GROUP_FD */
2732 int groupbits(int fd) {
2733 #if HAVE_STAT64
2734 struct stat64 buf;
2735 #else
2736 struct stat buf;
2737 #endif /* !HAVE_STAT64 */
2738 int result;
2740 if (
2741 #if HAVE_STAT64
2742 Fstat64(fd, &buf) < 0
2743 #else
2744 Fstat(fd, &buf) < 0
2745 #endif /* !HAVE_STAT64 */
2747 Error4("groupbits(%d): fstat(%d, %p): %s",
2748 fd, fd, &buf, strerror(errno));
2749 return -1;
2751 result = _groupbits(buf.st_mode&S_IFMT);
2752 if (result == GROUP_CHR) {
2753 if (Isatty(fd) > 0) {
2754 result |= GROUP_TERMIOS;
2757 return result;
2760 #if 0 /* currently not used */
2761 int retropt(struct opt *opts, int optcode, union integral *result) {
2762 struct opt *opt = opts;
2764 while (opt->desc != ODESC_END) {
2765 if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
2766 *result = opt->value;
2767 opt->desc = ODESC_DONE;
2768 return 0;
2770 ++opt;
2772 return -1;
2774 #endif
2776 static struct opt *xio_findopt(struct opt *opts, int optcode) {
2777 struct opt *opt = opts;
2779 while (opt->desc != ODESC_END) {
2780 if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
2781 return opt;
2783 ++opt;
2785 return NULL;
2788 int retropt_timespec(struct opt *opts, int optcode, struct timespec *result) {
2789 struct opt *opt;
2791 if (!(opt = xio_findopt(opts, optcode))) {
2792 return -1;
2794 *result = opt->value.u_timespec;
2795 opt->desc = ODESC_DONE;
2796 return 0;
2800 /* Looks for the first option of type <optcode>. If the option is found,
2801 this function stores its bool value in *result, "consumes" the
2802 option, and returns 0.
2803 If the option is not found, *result is not modified, and -1 is returned. */
2804 int retropt_bool(struct opt *opts, int optcode, bool *result) {
2805 struct opt *opt = opts;
2807 while (opt->desc != ODESC_END) {
2808 if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
2809 *result = opt->value.u_bool;
2810 opt->desc = ODESC_DONE;
2811 return 0;
2813 ++opt;
2815 return -1;
2818 #if 0 /* currently not used */
2819 /* Looks for the first option of type <optcode>. If the option is found,
2820 this function stores its short value in *result, "consumes" the
2821 option, and returns 0.
2822 If the option is not found, *result is not modified, and -1 is returned. */
2823 int retropt_short(struct opt *opts, int optcode, short *result) {
2824 struct opt *opt = opts;
2826 while (opt->desc != ODESC_END) {
2827 if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
2828 *result = opt->value.u_short;
2829 opt->desc = ODESC_DONE;
2830 return 0;
2832 ++opt;
2834 return -1;
2836 #endif
2838 /* Looks for the first option of type <optcode>. If the option is found,
2839 this function stores its unsigned short value in *result, "consumes" the
2840 option, and returns 0.
2841 If the option is not found, *result is not modified, and -1 is returned. */
2842 int retropt_ushort(struct opt *opts, int optcode, unsigned short *result) {
2843 struct opt *opt = opts;
2845 while (opt->desc != ODESC_END) {
2846 if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
2847 *result = opt->value.u_ushort;
2848 opt->desc = ODESC_DONE;
2849 return 0;
2851 ++opt;
2853 return -1;
2856 /* Looks for the first option of type <optcode>. If the option is found,
2857 this function stores its int value in *result, "consumes" the
2858 option, and returns 0.
2859 If the option is not found, *result is not modified, and -1 is returned. */
2860 int retropt_int(struct opt *opts, int optcode, int *result) {
2861 struct opt *opt = opts;
2863 while (opt->desc != ODESC_END) {
2864 if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
2865 switch (opt->desc->type) {
2866 case TYPE_INT: *result = opt->value.u_int; break;
2867 case TYPE_STRING: *result = strtol(opt->value.u_string, NULL, 0);
2868 break;
2869 default: Error2("cannot convert type %d of option %s to int",
2870 opt->desc->type, opt->desc->defname);
2871 opt->desc = ODESC_ERROR;
2872 return -1;
2874 opt->desc = ODESC_DONE;
2875 return 0;
2877 ++opt;
2879 return -1;
2882 /* Looks for the first option of type <optcode>. If the option is found,
2883 this function stores its unsigned int value in *result, "consumes" the
2884 option, and returns 0.
2885 If the option is not found, *result is not modified, and -1 is returned. */
2886 int retropt_uint(struct opt *opts, int optcode, unsigned int *result) {
2887 struct opt *opt = opts;
2889 while (opt->desc != ODESC_END) {
2890 if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
2891 *result = opt->value.u_uint;
2892 opt->desc = ODESC_DONE;
2893 return 0;
2895 ++opt;
2897 return -1;
2900 /* Looks for the first option of type <optcode>. If the option is found,
2901 this function stores its long value in *result, "consumes" the option,
2902 and returns 0.
2903 If the option is not found, *result is not modified, and -1 is returned. */
2904 int retropt_long(struct opt *opts, int optcode, long *result) {
2905 struct opt *opt = opts;
2907 while (opt->desc != ODESC_END) {
2908 if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
2909 *result = opt->value.u_long;
2910 opt->desc = ODESC_DONE;
2911 return 0;
2913 ++opt;
2915 return -1;
2918 /* Looks for the first option of type <optcode>. If the option is found,
2919 this function stores its unsigned long value in *result, "consumes" the
2920 option, and returns 0.
2921 If the option is not found, *result is not modified, and -1 is returned. */
2922 int retropt_ulong(struct opt *opts, int optcode, unsigned long *result) {
2923 struct opt *opt = opts;
2925 while (opt->desc != ODESC_END) {
2926 if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
2927 *result = opt->value.u_ulong;
2928 opt->desc = ODESC_DONE;
2929 return 0;
2931 ++opt;
2933 return -1;
2936 #if 0 /* currently not used */
2937 /* get the value of a FLAG typed option, and apply it to the appropriate
2938 bit position. Mark the option as consumed (done). return 0 if options was found and successfully applied,
2939 or -1 if option was not in opts */
2940 int retropt_flag(struct opt *opts, int optcode, flags_t *result) {
2941 struct opt *opt = opts;
2943 while (opt->desc != ODESC_END) {
2944 if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
2945 if (opt->value.u_bool) {
2946 *result |= opt->desc->major;
2947 } else {
2948 *result &= ~opt->desc->major;
2950 opt->desc = ODESC_DONE;
2951 return 0;
2953 ++opt;
2955 return -1;
2957 #endif
2959 /* Looks for the first option of type <optcode>. If the option is found,
2960 this function stores its character pointer value in *result, "consumes" the
2961 option, and returns 0. Note that, for options of type STRING_NULL, the
2962 character pointer might degenerate to NULL.
2963 The resulting string is malloc'ed and should be freed after use.
2964 If the option is not found, *result is not modified, and -1 is returned.
2966 int retropt_string(struct opt *opts, int optcode, char **result) {
2967 struct opt *opt = opts;
2969 while (opt->desc != ODESC_END) {
2970 if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
2971 if (opt->value.u_string == NULL) {
2972 *result = NULL;
2973 } else if ((*result = strdup(opt->value.u_string)) == NULL) {
2974 Error1("strdup("F_Zu"): out of memory",
2975 strlen(opt->value.u_string));
2976 return -1;
2978 opt->desc = ODESC_DONE;
2979 return 0;
2981 ++opt;
2983 return -1;
2987 #if _WITH_SOCKET
2988 /* looks for a bind option and, if found, overwrites the complete contents of
2989 sa with the appropriate value(s).
2990 returns STAT_OK if option exists and could be resolved,
2991 STAT_NORETRY if option exists but had error,
2992 or STAT_NOACTION if it does not exist */
2993 /* currently only for IP (v4, v6) and raw (PF_UNSPEC) */
2994 int retropt_bind(struct opt *opts,
2995 int af,
2996 int socktype,
2997 int ipproto,
2998 struct sockaddr *sa,
2999 socklen_t *salen,
3000 int feats, /* TCP etc: 1..address allowed,
3001 3..address and port allowed
3002 UNIX (or'd): 1..tight
3003 2..abstract
3005 unsigned long res_opts0, unsigned long res_opts1) {
3006 const char portsep[] = ":";
3007 const char *ends[] = { portsep, NULL };
3008 const char *nests[] = { "[", "]", NULL };
3009 bool portallowed;
3010 char *bindname, *bindp;
3011 char hostname[512], *hostp = hostname, *portp = NULL;
3012 size_t hostlen = sizeof(hostname)-1;
3013 int parsres;
3014 int result;
3016 if (retropt_string(opts, OPT_BIND, &bindname) < 0) {
3017 return STAT_NOACTION;
3019 bindp = bindname;
3021 switch (af) {
3023 case AF_UNSPEC:
3025 size_t p = 0;
3026 dalan(bindname, (uint8_t *)sa->sa_data, &p, *salen-sizeof(sa->sa_family), 'i');
3027 *salen = p + sizeof(sa->sa_family);
3028 *salen = p +
3029 #if HAVE_STRUCT_SOCKADDR_SALEN
3030 sizeof(sa->sa_len) +
3031 #endif
3032 sizeof(sa->sa_family);
3033 #if HAVE_STRUCT_SOCKADDR_SALEN
3034 sa->sa_len = *salen;
3035 #endif
3037 break;
3039 #if WITH_IP4 || WITH_IP6
3040 #if WITH_IP4
3041 case AF_INET:
3042 #endif
3043 #if WITH_IP6
3044 case AF_INET6:
3045 #endif /*WITH_IP6 */
3046 portallowed = (feats>=2);
3047 parsres =
3048 nestlex((const char **)&bindp, &hostp, &hostlen, ends, NULL, NULL, nests,
3049 true, false, false);
3050 if (parsres < 0) {
3051 Error1("option too long: \"%s\"", bindp);
3052 return STAT_NORETRY;
3053 } else if (parsres > 0) {
3054 Error1("syntax error in \"%s\"", bindp);
3055 return STAT_NORETRY;
3057 *hostp++ = '\0';
3058 if (!strncmp(bindp, portsep, strlen(portsep))) {
3059 if (!portallowed) {
3060 Error("port specification not allowed in this bind option");
3061 return STAT_NORETRY;
3062 } else {
3063 portp = bindp + strlen(portsep);
3066 if ((result =
3067 xiogetaddrinfo(hostname[0]!='\0'?hostname:NULL, portp,
3068 af, socktype, ipproto,
3069 (union sockaddr_union *)sa, salen,
3070 res_opts0, res_opts1))
3071 != STAT_OK) {
3072 Error("error resolving bind option");
3073 return STAT_NORETRY;
3075 break;
3076 #endif /* WITH_IP4 || WITH_IP6 */
3078 #if WITH_UNIX
3079 case AF_UNIX:
3081 bool abstract = (feats&2);
3082 bool tight = (feats&1);
3083 struct sockaddr_un *s_un = (struct sockaddr_un *)sa;
3084 *salen = xiosetunix(af, s_un, bindname, abstract, tight);
3086 break;
3087 #endif /* WITH_UNIX */
3089 default:
3090 Error1("bind: unknown address family %d", af);
3091 return STAT_NORETRY;
3093 return STAT_OK;
3095 #endif /* _WITH_SOCKET */
3098 /* applies to fd all options belonging to phase */
3099 /* note: not all options can be applied this way (e.g. OFUNC_SPEC with PH_OPEN)
3100 implemented are: OFUNC_FCNTL, OFUNC_SOCKOPT (probably not all types),
3101 OFUNC_TERMIOS_FLAG, OFUNC_TERMIOS_PATTERN, and some OFUNC_SPEC */
3102 int applyopts(int fd, struct opt *opts, enum e_phase phase) {
3103 struct opt *opt;
3105 opt = opts; while (opt && opt->desc != ODESC_END) {
3106 if (opt->desc == ODESC_DONE ||
3107 (phase != PH_ALL && opt->desc->phase != phase)) {
3108 ++opt; continue; }
3110 if (opt->desc->func == OFUNC_SEEK32) {
3111 if (Lseek(fd, opt->value.u_off, opt->desc->major) < 0) {
3112 Error4("lseek(%d, "F_off", %d): %s",
3113 fd, opt->value.u_off, opt->desc->major, strerror(errno));
3115 #if HAVE_LSEEK64
3116 } else if (opt->desc->func == OFUNC_SEEK64) {
3118 /*! this depends on off64_t atomic type */
3119 if (Lseek64(fd, opt->value.u_off64, opt->desc->major) < 0) {
3120 Error4("lseek64(%d, "F_off64", %d): %s",
3121 fd, opt->value.u_off64, opt->desc->major, strerror(errno));
3123 #endif /* HAVE_LSEEK64 */
3125 } else if (opt->desc->func == OFUNC_FCNTL) {
3126 int flag;
3128 /* retrieve existing flag setttings */
3129 if ((flag = Fcntl(fd, opt->desc->major-1)) < 0) {
3130 Error3("fcntl(%d, %d): %s",
3131 fd, opt->desc->major, strerror(errno));
3132 opt->desc = ODESC_ERROR; ++opt; continue;
3133 } else {
3134 if (opt->value.u_bool) {
3135 flag |= opt->desc->minor;
3136 } else {
3137 flag &= ~opt->desc->minor;
3139 if (Fcntl_l(fd, opt->desc->major, flag) < 0) {
3140 Error4("fcntl(%d, %d, %d): %s",
3141 fd, opt->desc->major, flag, strerror(errno));
3142 opt->desc = ODESC_ERROR; ++opt; continue;
3146 } else if (opt->desc->func == OFUNC_IOCTL) {
3147 if (Ioctl(fd, opt->desc->major, (void *)&opt->value) < 0) {
3148 Error4("ioctl(%d, 0x%x, %p): %s",
3149 fd, opt->desc->major, (void *)&opt->value, strerror(errno));
3150 opt->desc = ODESC_ERROR; ++opt; continue;
3153 } else if (opt->desc->func == OFUNC_IOCTL_MASK_LONG) {
3154 long val;
3155 int getreq = opt->desc->major;
3156 int setreq = opt->desc->minor;
3157 long mask = opt->desc->arg3;
3159 if (Ioctl(fd, getreq, (void *)&val) < 0) {
3160 Error4("ioctl(%d, 0x%x, %p): %s",
3161 fd, opt->desc->major, (void *)&val, strerror(errno));
3162 opt->desc = ODESC_ERROR; ++opt; continue;
3164 val &= ~mask;
3165 if (opt->value.u_bool) val |= mask;
3166 if (Ioctl(fd, setreq, (void *)&val) < 0) {
3167 Error4("ioctl(%d, 0x%x, %p): %s",
3168 fd, opt->desc->major, (void *)&val, strerror(errno));
3169 opt->desc = ODESC_ERROR; ++opt; continue;
3172 } else if (opt->desc->func == OFUNC_IOCTL_GENERIC) {
3173 switch (opt->desc->type) {
3174 case TYPE_INT:
3175 if (Ioctl(fd, opt->value.u_int, NULL) < 0) {
3176 Error3("ioctl(%d, 0x%x, NULL): %s",
3177 fd, opt->value.u_int, strerror(errno));
3178 opt->desc = ODESC_ERROR; ++opt; continue;
3180 break;
3181 case TYPE_INT_INT:
3182 if (Ioctl_int(fd, opt->value.u_int, opt->value2.u_int) < 0) {
3183 Error4("ioctl(%d, 0x%x, 0x%x): %s",
3184 fd, opt->value.u_int, opt->value2.u_int, strerror(errno));
3185 opt->desc = ODESC_ERROR; ++opt; continue;
3187 break;
3188 case TYPE_INT_INTP:
3189 if (Ioctl(fd, opt->value.u_int, (void *)&opt->value2.u_int) < 0) {
3190 Error4("ioctl(%d, 0x%x, %p): %s",
3191 fd, opt->value.u_int, (void *)&opt->value2.u_int, strerror(errno));
3192 opt->desc = ODESC_ERROR; ++opt; continue;
3194 break;
3195 case TYPE_INT_BIN:
3196 if (Ioctl(fd, opt->value.u_int, (void *)opt->value2.u_bin.b_data) < 0) {
3197 Error4("ioctl(%d, 0x%x, %p): %s",
3198 fd, opt->value.u_int, (void *)opt->value2.u_bin.b_data, strerror(errno));
3199 opt->desc = ODESC_ERROR; ++opt; continue;
3201 break;
3202 case TYPE_INT_STRING:
3203 if (Ioctl(fd, opt->value.u_int, (void *)opt->value2.u_string) < 0) {
3204 Error4("ioctl(%d, 0x%x, %p): %s",
3205 fd, opt->value.u_int, (void *)opt->value2.u_string, strerror(errno));
3206 opt->desc = ODESC_ERROR; ++opt; continue;
3208 break;
3209 default:
3210 Error1("ioctl() data type %d not implemented",
3211 opt->desc->type);
3214 #if _WITH_SOCKET
3215 } else if (opt->desc->func == OFUNC_SOCKOPT) {
3216 if (0) {
3218 #if 0 && HAVE_STRUCT_LINGER
3219 } else if (opt->desc->optcode == OPT_SO_LINGER) {
3220 struct linger lingstru;
3221 lingstru.l_onoff = (opt->value.u_int>=0 ? 1 : 0);
3222 lingstru.l_linger = opt->value.u_int;
3223 if (Setsockopt(fd, opt->desc->major, opt->desc->minor, &lingstru,
3224 sizeof(lingstru)) < 0) {
3225 Error6("setsockopt(%d, %d, %d, {%d,%d}, "F_Zu,
3226 fd, opt->desc->major, opt->desc->minor, lingstru.l_onoff,
3227 lingstru.l_linger, sizeof(lingstru));
3228 opt->desc = ODESC_ERROR; ++opt; continue;
3230 #endif /* HAVE_STRUCT_LINGER */
3231 } else {
3232 switch (opt->desc->type) {
3233 case TYPE_BIN:
3234 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3235 opt->value.u_bin.b_data, opt->value.u_bin.b_len)
3236 < 0) {
3237 Error6("setsockopt(%d, %d, %d, %p, "F_Zu"): %s",
3238 fd, opt->desc->major, opt->desc->minor,
3239 opt->value.u_bin.b_data, opt->value.u_bin.b_len,
3240 strerror(errno));
3241 opt->desc = ODESC_ERROR; ++opt; continue;
3243 break;
3244 case TYPE_BOOL:
3245 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3246 &opt->value.u_bool, sizeof(opt->value.u_bool))
3247 < 0) {
3248 Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu"): %s", fd,
3249 opt->desc->major, opt->desc->minor,
3250 opt->value.u_bool, sizeof(opt->value.u_bool),
3251 strerror(errno));
3252 opt->desc = ODESC_ERROR; ++opt; continue;
3254 break;
3255 case TYPE_BYTE:
3256 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3257 &opt->value.u_byte, sizeof(uint8_t)) < 0) {
3258 Error6("setsockopt(%d, %d, %d, {%u}, "F_Zu"): %s",
3259 fd, opt->desc->major, opt->desc->minor,
3260 opt->value.u_byte, sizeof(uint8_t), strerror(errno));
3261 opt->desc = ODESC_ERROR; ++opt; continue;
3263 break;
3264 case TYPE_INT:
3265 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3266 &opt->value.u_int, sizeof(int)) < 0) {
3267 Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu"): %s",
3268 fd, opt->desc->major, opt->desc->minor,
3269 opt->value.u_int, sizeof(int), strerror(errno));
3270 opt->desc = ODESC_ERROR; ++opt; continue;
3272 break;
3273 case TYPE_LONG:
3274 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3275 &opt->value.u_long, sizeof(long)) < 0) {
3276 Error6("setsockopt(%d, %d, %d, {%ld}, "F_Zu"): %s",
3277 fd, opt->desc->major, opt->desc->minor,
3278 opt->value.u_long, sizeof(long), strerror(errno));
3279 opt->desc = ODESC_ERROR; ++opt; continue;
3281 break;
3282 case TYPE_STRING:
3283 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3284 opt->value.u_string,
3285 strlen(opt->value.u_string)+1) < 0) {
3286 Error6("setsockopt(%d, %d, %d, \"%s\", "F_Zu"): %s",
3287 fd, opt->desc->major, opt->desc->minor,
3288 opt->value.u_string, strlen(opt->value.u_string)+1,
3289 strerror(errno));
3290 opt->desc = ODESC_ERROR; ++opt; continue;
3292 break;
3293 case TYPE_UINT:
3294 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3295 &opt->value.u_uint, sizeof(unsigned int)) < 0) {
3296 Error6("setsockopt(%d, %d, %d, {%u}, "F_Zu"): %s",
3297 fd, opt->desc->major, opt->desc->minor,
3298 opt->value.u_uint, sizeof(unsigned int),
3299 strerror(errno));
3300 opt->desc = ODESC_ERROR; ++opt; continue;
3302 break;
3303 case TYPE_TIMEVAL:
3304 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3305 &opt->value.u_timeval, sizeof(struct timeval)) < 0) {
3306 Error7("setsockopt(%d, %d, %d, {%ld,%ld}, "F_Zu"): %s",
3307 fd, opt->desc->major, opt->desc->minor,
3308 opt->value.u_timeval.tv_sec, opt->value.u_timeval.tv_usec,
3309 sizeof(struct timeval), strerror(errno));
3310 opt->desc = ODESC_ERROR; ++opt; continue;
3312 break;
3313 #if HAVE_STRUCT_LINGER
3314 case TYPE_LINGER:
3316 struct linger lingstru;
3317 lingstru.l_onoff = (opt->value.u_linger.l_onoff>=0 ? 1 : 0);
3318 lingstru.l_linger = opt->value.u_linger.l_linger;
3319 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3320 &lingstru, sizeof(lingstru)) < 0) {
3321 Error6("setsockopt(%d, %d, %d, {%d,%d}): %s",
3322 fd, opt->desc->major, opt->desc->minor,
3323 lingstru.l_onoff, lingstru.l_linger,
3324 strerror(errno));
3325 opt->desc = ODESC_ERROR; ++opt; continue;
3328 break;
3329 #endif /* HAVE_STRUCT_LINGER */
3330 #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)
3331 case TYPE_IP_MREQN:
3332 /* handled in applyopts_single */
3333 ++opt; continue;
3334 #endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */
3336 /*! still many types missing; implement on demand */
3337 #if WITH_IP4
3338 case TYPE_IP4NAME:
3339 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3340 &opt->value.u_ip4addr, sizeof(opt->value.u_ip4addr)) < 0) {
3341 Error6("setsockopt(%d, %d, %d, {0x%x}, "F_Zu"): %s",
3342 fd, opt->desc->major, opt->desc->minor,
3343 *(uint32_t *)&opt->value.u_ip4addr, sizeof(opt->value.u_ip4addr),
3344 strerror(errno));
3346 break;
3347 #endif /* defined(WITH_IP4) */
3348 default:
3349 #if !NDEBUG
3350 Error1("applyopts(): type %d not implemented",
3351 opt->desc->type);
3352 #else
3353 Warn1("applyopts(): type %d not implemented",
3354 opt->desc->type);
3355 #endif
3356 opt->desc = ODESC_ERROR; ++opt; continue;
3360 } else if (opt->desc->func == OFUNC_SOCKOPT_APPEND) {
3361 switch (opt->desc->type) {
3362 uint8_t data[256];
3363 socklen_t oldlen, newlen;
3364 case TYPE_BIN:
3365 oldlen = sizeof(data);
3366 if (Getsockopt(fd, opt->desc->major, opt->desc->minor,
3367 data, &oldlen)
3368 < 0) {
3369 Error6("getsockopt(%d, %d, %d, %p, {"F_socklen"}): %s",
3370 fd, opt->desc->major, opt->desc->minor, data, oldlen,
3371 strerror(errno));
3372 opt->desc = ODESC_ERROR; ++opt; continue;
3374 memcpy(&data[oldlen], opt->value.u_bin.b_data,
3375 MIN(opt->value.u_bin.b_len, sizeof(data)-oldlen));
3376 newlen = oldlen + MIN(opt->value.u_bin.b_len, sizeof(data)-oldlen);
3377 if (Setsockopt(fd, opt->desc->major, opt->desc->minor,
3378 data, newlen)
3379 < 0) {
3380 Error6("setsockopt(%d, %d, %d, %p, %d): %s",
3381 fd, opt->desc->major, opt->desc->minor, data, newlen,
3382 strerror(errno));
3383 opt->desc = ODESC_ERROR; ++opt; continue;
3385 break;
3386 default:
3387 Error2("internal: option \"%s\": unimplemented type %d",
3388 opt->desc->defname, opt->desc->type);
3389 break;
3391 } else if (opt->desc->func == OFUNC_SOCKOPT_GENERIC) {
3392 switch (opt->desc->type) {
3393 case TYPE_INT_INT_INT:
3394 if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int,
3395 &opt->value3.u_int, sizeof(int)) < 0) {
3396 Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu"): %s",
3397 fd, opt->value.u_int, opt->value2.u_int,
3398 opt->value3.u_int, sizeof(int), strerror(errno));
3400 break;
3401 case TYPE_INT_INT_BIN:
3402 if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int,
3403 opt->value3.u_bin.b_data, opt->value3.u_bin.b_len) < 0) {
3404 Error5("setsockopt(%d, %d, %d, {...}, "F_Zu"): %s",
3405 fd, opt->value.u_int, opt->value2.u_int,
3406 opt->value3.u_bin.b_len, strerror(errno));
3408 break;
3409 case TYPE_INT_INT_STRING:
3410 if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int,
3411 opt->value3.u_string,
3412 strlen(opt->value3.u_string)+1) < 0) {
3413 Error6("setsockopt(%d, %d, %d, \"%s\", "F_Zu"): %s",
3414 fd, opt->value.u_int, opt->value2.u_int,
3415 opt->value3.u_string, strlen(opt->value3.u_string)+1,
3416 strerror(errno));
3418 break;
3419 default:
3420 Error1("setsockopt() data type %d not implemented",
3421 opt->desc->type);
3423 #endif /* _WITH_SOCKET */
3425 #if HAVE_FLOCK
3426 } else if (opt->desc->func == OFUNC_FLOCK) {
3427 if (Flock(fd, opt->desc->major) < 0) {
3428 Error3("flock(%d, %d): %s",
3429 fd, opt->desc->major, strerror(errno));
3430 opt->desc = ODESC_ERROR; ++opt; continue;
3432 #endif /* defined(HAVE_FLOCK) */
3434 } else if (opt->desc->func == OFUNC_SPEC ||
3435 opt->desc->func == OFUNC_FLAG) {
3436 switch (opt->desc->optcode) {
3437 case OPT_USER:
3438 case OPT_USER_LATE:
3439 if (Fchown(fd, opt->value.u_uidt, -1) < 0) {
3440 Error3("fchown(%d, "F_uid", -1): %s",
3441 fd, opt->value.u_uidt, strerror(errno));
3442 opt->desc = ODESC_ERROR; ++opt; continue;
3444 break;
3445 case OPT_GROUP:
3446 case OPT_GROUP_LATE:
3447 if (Fchown(fd, -1, opt->value.u_gidt) < 0) {
3448 Error3("fchown(%d, -1, "F_gid"): %s",
3449 fd, opt->value.u_gidt, strerror(errno));
3450 opt->desc = ODESC_ERROR; ++opt; continue;
3452 break;
3453 case OPT_PERM:
3454 case OPT_PERM_LATE:
3455 if (Fchmod(fd, opt->value.u_modet) < 0) {
3456 Error3("fchmod(%d, %u): %s",
3457 fd, opt->value.u_modet, strerror(errno));
3458 opt->desc = ODESC_ERROR; ++opt; continue;
3460 break;
3461 case OPT_FTRUNCATE32:
3462 if (Ftruncate(fd, opt->value.u_off) < 0) {
3463 Error3("ftruncate(%d, "F_off"): %s",
3464 fd, opt->value.u_off, strerror(errno));
3465 opt->desc = ODESC_ERROR; ++opt; continue;
3467 break;
3468 #if HAVE_FTRUNCATE64
3469 case OPT_FTRUNCATE64:
3470 if (Ftruncate64(fd, opt->value.u_off64) < 0) {
3471 Error3("ftruncate64(%d, "F_off64"): %s",
3472 fd, opt->value.u_off64, strerror(errno));
3473 opt->desc = ODESC_ERROR; ++opt; continue;
3475 #endif /* HAVE_FTRUNCATE64 */
3476 break;
3477 case OPT_F_SETLK_RD:
3478 case OPT_F_SETLK_WR:
3479 case OPT_F_SETLKW_RD:
3480 case OPT_F_SETLKW_WR:
3482 struct flock l; /* Linux: <asm/fcntl.h> */
3483 l.l_type = opt->desc->minor;
3484 l.l_whence = SEEK_SET;
3485 l.l_start = 0;
3486 l.l_len = LONG_MAX;
3487 l.l_pid = 0; /* hope this uses our current process */
3488 if (Fcntl_lock(fd, opt->desc->major, &l) < 0) {
3489 Error3("fcntl(%d, %d, {type=F_WRLCK,whence=SEEK_SET,start=0,len=LONG_MAX,pid=0}): %s", fd, opt->desc->major, strerror(errno));
3490 opt->desc = ODESC_ERROR; ++opt; continue;
3493 break;
3494 case OPT_SETUID_EARLY:
3495 case OPT_SETUID:
3496 if (Setuid(opt->value.u_uidt) < 0) {
3497 Error2("setuid("F_uid"): %s", opt->value.u_uidt,
3498 strerror(errno));
3499 opt->desc = ODESC_ERROR; ++opt; continue;
3501 break;
3502 case OPT_SETGID_EARLY:
3503 case OPT_SETGID:
3504 if (Setgid(opt->value.u_gidt) < 0) {
3505 Error2("setgid("F_gid"): %s", opt->value.u_gidt,
3506 strerror(errno));
3507 opt->desc = ODESC_ERROR; ++opt; continue;
3509 break;
3510 case OPT_SUBSTUSER_EARLY:
3511 case OPT_SUBSTUSER:
3513 struct passwd *pwd;
3514 if ((pwd = getpwuid(opt->value.u_uidt)) == NULL) {
3515 Error1("getpwuid("F_uid"): no such user",
3516 opt->value.u_uidt);
3517 opt->desc = ODESC_ERROR; ++opt; continue;
3519 if (Initgroups(pwd->pw_name, pwd->pw_gid) < 0) {
3520 Error3("initgroups(%s, "F_gid"): %s",
3521 pwd->pw_name, pwd->pw_gid, strerror(errno));
3522 opt->desc = ODESC_ERROR; ++opt; continue;
3524 if (Setgid(pwd->pw_gid) < 0) {
3525 Error2("setgid("F_gid"): %s", pwd->pw_gid,
3526 strerror(errno));
3527 opt->desc = ODESC_ERROR; ++opt; continue;
3529 if (Setuid(opt->value.u_uidt) < 0) {
3530 Error2("setuid("F_uid"): %s", opt->value.u_uidt,
3531 strerror(errno));
3532 opt->desc = ODESC_ERROR; ++opt; continue;
3534 #if 1
3535 if (setenv("USER", pwd->pw_name, 1) < 0)
3536 Error1("setenv(\"USER\", \"%s\", 1): insufficient space",
3537 pwd->pw_name);
3538 if (setenv("LOGNAME", pwd->pw_name, 1) < 0)
3539 Error1("setenv(\"LOGNAME\", \"%s\", 1): insufficient space",
3540 pwd->pw_name);
3541 if (setenv("HOME", pwd->pw_dir, 1) < 0)
3542 Error1("setenv(\"HOME\", \"%s\", 1): insufficient space",
3543 pwd->pw_dir);
3544 if (setenv("SHELL", pwd->pw_shell, 1) < 0)
3545 Error1("setenv(\"SHELL\", \"%s\", 1): insufficient space",
3546 pwd->pw_shell);
3547 #endif
3549 break;
3550 #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
3551 case OPT_SUBSTUSER_DELAYED:
3553 struct passwd *pwd;
3555 if ((pwd = getpwuid(opt->value.u_uidt)) == NULL) {
3556 Error1("getpwuid("F_uid"): no such user",
3557 opt->value.u_uidt);
3558 opt->desc = ODESC_ERROR; ++opt; continue;
3560 delayeduser_uid = opt->value.u_uidt;
3561 delayeduser_gid = pwd->pw_gid;
3562 if ((delayeduser_name = strdup(pwd->pw_name)) == NULL) {
3563 Error1("strdup("F_Zu"): out of memory",
3564 strlen(pwd->pw_name)+1);
3565 opt->desc = ODESC_ERROR; ++opt; continue;
3567 if ((delayeduser_dir = strdup(pwd->pw_dir)) == NULL) {
3568 Error1("strdup("F_Zu"): out of memory",
3569 strlen(pwd->pw_dir)+1);
3570 opt->desc = ODESC_ERROR; ++opt; continue;
3572 if ((delayeduser_shell = strdup(pwd->pw_shell)) == NULL) {
3573 Error1("strdup("F_Zu"): out of memory",
3574 strlen(pwd->pw_shell)+1);
3575 opt->desc = ODESC_ERROR; ++opt; continue;
3577 /* function to get all supplementary groups of user */
3578 delayeduser_ngids = sizeof(delayeduser_gids)/sizeof(gid_t);
3579 getusergroups(delayeduser_name, delayeduser_gids,
3580 &delayeduser_ngids);
3581 delayeduser = true;
3583 break;
3584 #endif
3585 case OPT_CHROOT_EARLY:
3586 case OPT_CHROOT:
3587 if (Chroot(opt->value.u_string) < 0) {
3588 Error2("chroot(\"%s\"): %s", opt->value.u_string,
3589 strerror(errno));
3590 opt->desc = ODESC_ERROR; ++opt; continue;
3592 if (Chdir("/") < 0) {
3593 Error1("chdir(\"/\"): %s", strerror(errno));
3595 break;
3596 case OPT_SETSID:
3597 if (Setsid() < 0) {
3598 Warn1("setsid(): %s", strerror(errno));
3599 if (Setpgid(getpid(), getppid()) < 0) {
3600 Warn3("setpgid(%d, %d): %s",
3601 getpid(), getppid(), strerror(errno));
3602 } else {
3603 if (Setsid() < 0) {
3604 Error1("setsid(): %s", strerror(errno));
3608 break;
3609 case OPT_SETPGID:
3610 if (Setpgid(0, opt->value.u_int) < 0) {
3611 Warn2("setpgid(0, "F_pid"): %s",
3612 opt->value.u_int, strerror(errno));
3614 break;
3615 case OPT_TIOCSCTTY:
3617 int mytty;
3618 /* this code idea taken from ssh/pty.c: make pty controlling term. */
3619 if ((mytty = Open("/dev/tty", O_NOCTTY, 0640)) < 0) {
3620 Warn1("open(\"/dev/tty\", O_NOCTTY, 0640): %s", strerror(errno));
3621 } else {
3622 /*0 Info1("open(\"/dev/tty\", O_NOCTTY, 0640) -> %d", mytty);*/
3623 #ifdef TIOCNOTTY
3624 if (Ioctl(mytty, TIOCNOTTY, NULL) < 0) {
3625 Warn2("ioctl(%d, TIOCNOTTY, NULL): %s",
3626 mytty, strerror(errno));
3628 #endif
3629 if (Close(mytty) < 0) {
3630 Info2("close(%d): %s",
3631 mytty, strerror(errno));
3634 #ifdef TIOCSCTTY
3635 if (Ioctl(fd, TIOCSCTTY, NULL) < 0) {
3636 Warn2("ioctl(%d, TIOCSCTTY, NULL): %s", fd, strerror(errno));
3638 #endif
3639 if (Tcsetpgrp(0, getpid()) < 0) {
3640 Warn2("tcsetpgrp("F_pid"): %s", getpid(), strerror(errno));
3643 break;
3645 default: Error1("applyopts(): option \"%s\" not implemented",
3646 opt->desc->defname);
3647 opt->desc = ODESC_ERROR; ++opt; continue;
3650 #if WITH_TERMIOS
3651 } else if (opt->desc->func == OFUNC_TERMIOS_FLAG) {
3652 if (xiotermiosflag_applyopt(fd, opt) < 0) {
3653 opt->desc = ODESC_ERROR; ++opt; continue;
3656 } else if (opt->desc->func == OFUNC_TERMIOS_VALUE) {
3657 if (((opt->value.u_uint << opt->desc->arg3) & opt->desc->minor) !=
3658 (opt->value.u_uint << opt->desc->arg3)) {
3659 Error2("option %s: invalid value %u",
3660 opt->desc->defname, opt->value.u_uint);
3661 opt->desc = ODESC_ERROR; ++opt; continue;
3663 if (xiotermios_value(fd, opt->desc->major, opt->desc->minor,
3664 (opt->value.u_uint << opt->desc->arg3) & opt->desc->minor) < 0) {
3665 opt->desc = ODESC_ERROR; ++opt; continue;
3668 } else if (opt->desc->func == OFUNC_TERMIOS_PATTERN) {
3669 if (xiotermios_value(fd, opt->desc->major, opt->desc->arg3, opt->desc->minor) < 0) {
3670 opt->desc = ODESC_ERROR; ++opt; continue;
3673 } else if (opt->desc->func == OFUNC_TERMIOS_CHAR) {
3674 if (xiotermios_char(fd, opt->desc->major, opt->value.u_byte) < 0) {
3675 opt->desc = ODESC_ERROR; ++opt; continue;
3678 #ifdef HAVE_TERMIOS_ISPEED
3679 } else if (opt->desc->func == OFUNC_TERMIOS_SPEED) {
3680 if (xiotermios_speed(fd, opt->desc->major, opt->value.u_uint) < 0) {
3681 opt->desc = ODESC_ERROR; ++opt; continue;
3683 #endif /* HAVE_TERMIOS_ISPEED */
3685 } else if (opt->desc->func == OFUNC_TERMIOS_SPEC) {
3686 if (xiotermios_spec(fd, opt->desc->optcode) < 0) {
3687 opt->desc = ODESC_ERROR; ++opt; continue;
3690 #endif /* WITH_TERMIOS */
3692 #if WITH_STREAMS
3693 #define ENABLE_APPLYOPT
3694 #include "xio-streams.c"
3695 #undef ENABLE_APPLYOPT
3696 #endif /* WITH_STREAMS */
3698 } else {
3699 /*Error1("applyopts(): function %d not implemented",
3700 opt->desc->func);*/
3701 if (opt->desc->func != OFUNC_EXT && opt->desc->func != OFUNC_SIGNAL) {
3702 Error1("applyopts(): option \"%s\" does not apply",
3703 opt->desc->defname);
3704 opt->desc = ODESC_ERROR;
3705 ++opt;
3706 continue;
3708 ++opt;
3709 continue;
3711 opt->desc = ODESC_DONE;
3712 ++opt;
3715 #if WITH_TERMIOS
3716 if (phase == PH_FD || phase == PH_ALL) {
3717 xiotermios_flush(fd);
3719 #endif /* WITH_TERMIOS */
3720 return 0;
3723 /* applies to fd all options belonging to phases */
3724 /* note: not all options can be applied this way (e.g. OFUNC_SPEC with PH_OPEN)
3725 implemented are: OFUNC_FCNTL, OFUNC_SOCKOPT (probably not all types),
3726 OFUNC_TERMIOS_FLAG, OFUNC_TERMIOS_PATTERN, and some OFUNC_SPEC */
3727 int applyopts2(int fd, struct opt *opts, unsigned int from, unsigned int to) {
3728 unsigned int i;
3729 int stat;
3731 for (i = from; i <= to; ++i) {
3732 if ((stat = applyopts(fd, opts, i)) < 0)
3733 return stat;
3735 return 0;
3738 /* apply and consume all options of type FLAG and group.
3739 Return 0 if everything went right, or -1 if an error occurred. */
3740 int applyopts_flags(struct opt *opts, int group, flags_t *result) {
3741 struct opt *opt = opts;
3743 if (!opts) return 0;
3745 while (opt->desc != ODESC_END) {
3746 if (opt->desc != ODESC_DONE &&
3747 (opt->desc->group & group)) {
3748 if (opt->desc->func == OFUNC_FLAG) {
3749 if (opt->value.u_bool) {
3750 *result |= opt->desc->major;
3751 } else {
3752 *result &= ~opt->desc->major;
3754 opt->desc = ODESC_DONE;
3755 } else if (opt->desc->func == OFUNC_FLAG_PATTERN) {
3756 *result &= ~opt->desc->minor;
3757 *result |= opt->desc->major;
3758 opt->desc = ODESC_DONE;
3761 ++opt;
3763 return 0;
3768 /* set the FD_CLOEXEC fcntl if the options do not set it to 0 */
3769 int applyopts_cloexec(int fd, struct opt *opts) {
3770 bool docloexec = 1;
3772 if (!opts) return 0;
3774 retropt_bool(opts, OPT_CLOEXEC, &docloexec);
3775 if (docloexec) {
3776 if (Fcntl_l(fd, F_SETFD, FD_CLOEXEC) < 0) {
3777 Warn2("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", fd, strerror(errno));
3780 return 0;
3783 int applyopts_fchown(int fd, struct opt *opts) {
3784 uid_t user = -1;
3785 gid_t group = -1;
3787 retropt_uidt(opts, OPT_USER, &user);
3788 retropt_gidt(opts, OPT_GROUP, &group);
3790 if (user != (uid_t)-1 || group != (gid_t)-1) {
3791 if (Fchown(fd, user, group) < 0) {
3792 Error4("fchown(%d, "F_uid", "F_gid"): %s", fd, user, group,
3793 strerror(errno));
3794 return STAT_RETRYLATER;
3797 return 0;
3800 /* caller must make sure that option is not yet consumed */
3801 static int applyopt_offset(struct single *xfd, struct opt *opt) {
3802 unsigned char *ptr;
3804 ptr = (unsigned char *)xfd + opt->desc->major;
3805 switch (opt->desc->type) {
3806 case TYPE_BOOL:
3807 *(bool *)ptr = opt->value.u_bool; break;
3808 case TYPE_INT:
3809 *(int *)ptr = opt->value.u_int; break;
3810 case TYPE_DOUBLE:
3811 *(double *)ptr = opt->value.u_double; break;
3812 case TYPE_TIMEVAL:
3813 *(struct timeval *)ptr = opt->value.u_timeval; break;
3814 case TYPE_STRING_NULL:
3815 if (opt->value.u_string == NULL) {
3816 *(char **)ptr = NULL;
3817 break;
3819 /* PASSTHROUGH */
3820 case TYPE_STRING:
3821 if ((*(char **)ptr = strdup(opt->value.u_string)) == NULL) {
3822 Error1("strdup("F_Zu"): out of memory",
3823 strlen(opt->value.u_string)+1);
3825 break;
3826 case TYPE_CONST:
3827 *(int *)ptr = opt->desc->minor;
3828 break;
3829 default:
3830 Error1("applyopt_offset(): type %d not implemented",
3831 opt->desc->type);
3832 return -1;
3834 opt->desc = ODESC_DONE;
3835 return 0;
3838 int applyopts_offset(struct single *xfd, struct opt *opts) {
3839 struct opt *opt;
3841 opt = opts; while (opt->desc != ODESC_END) {
3842 if ((opt->desc == ODESC_DONE) ||
3843 opt->desc->func != OFUNC_OFFSET) {
3844 ++opt; continue; }
3846 applyopt_offset(xfd, opt);
3847 opt->desc = ODESC_DONE;
3848 ++opt;
3850 return 0;
3853 /* applies to xfd all OFUNC_EXT options belonging to phase
3854 returns -1 if an error occurred */
3855 int applyopts_single(struct single *xfd, struct opt *opts, enum e_phase phase) {
3856 struct opt *opt;
3857 int lockrc;
3859 if (!opts) return 0;
3861 opt = opts; while (opt->desc != ODESC_END) {
3862 if ((opt->desc == ODESC_DONE) ||
3863 (opt->desc->phase != phase && phase != PH_ALL)) {
3864 /* option not handled in this function */
3865 ++opt; continue;
3866 } else {
3867 switch (opt->desc->func) {
3869 case OFUNC_OFFSET:
3870 applyopt_offset(xfd, opt);
3871 break;
3873 case OFUNC_EXT:
3874 switch (opt->desc->optcode) {
3875 #if 0
3876 case OPT_IGNOREEOF:
3877 xfd->ignoreeof = true;
3878 break;
3879 case OPT_CR:
3880 xfd->lineterm = LINETERM_CR;
3881 break;
3882 case OPT_CRNL:
3883 xfd->lineterm = LINETERM_CRNL;
3884 break;
3885 #endif /* 0 */
3886 case OPT_READBYTES:
3887 xfd->readbytes = opt->value.u_sizet;
3888 xfd->actbytes = xfd->readbytes;
3889 break;
3890 case OPT_LOCKFILE:
3891 if (xfd->lock.lockfile) {
3892 Error("only one use of options lockfile and waitlock allowed");
3894 xfd->lock.lockfile = strdup(opt->value.u_string);
3895 xfd->lock.intervall.tv_sec = 1;
3896 xfd->lock.intervall.tv_nsec = 0;
3898 if ((lockrc = xiolock(&xfd->lock)) < 0) {
3899 /* error message already printed */
3900 return -1;
3902 if (lockrc) {
3903 Error1("could not obtain lock \"%s\"", xfd->lock.lockfile);
3904 } else {
3905 xfd->havelock = true;
3907 break;
3908 case OPT_WAITLOCK:
3909 if (xfd->lock.lockfile) {
3910 Error("only one use of options lockfile and waitlock allowed");
3912 xfd->lock.lockfile = strdup(opt->value.u_string);
3913 xfd->lock.waitlock = true;
3914 xfd->lock.intervall.tv_sec = 1;
3915 xfd->lock.intervall.tv_nsec = 0;
3917 /*! this should be integrated into central select()/poll() loop */
3918 if (xiolock(&xfd->lock) < 0) {
3919 return -1;
3921 xfd->havelock = true;
3922 break;
3924 default:
3925 /* just store the value in the correct component of struct single */
3926 if (opt->desc->type == TYPE_CONST) {
3927 /* only for integral types compatible to int */
3928 *(int *)(&((char *)xfd)[opt->desc->major]) = opt->desc->arg3;
3929 } else {
3930 memcpy(&((char *)xfd)[opt->desc->major], &opt->value, opt->desc->minor);
3933 break;
3935 case OFUNC_OFFSET_MASKS:
3937 void *masks = (char *)xfd + opt->desc->major;
3938 size_t masksize = opt->desc->minor;
3939 unsigned long bit = opt->desc->arg3;
3940 switch (masksize>>1) {
3941 case sizeof(uint16_t):
3942 if (opt->value.u_bool) {
3943 ((uint16_t *)masks)[0] |= bit;
3944 } else {
3945 ((uint16_t *)masks)[1] |= bit;
3947 break;
3948 case sizeof(uint32_t):
3949 if (opt->value.u_bool) {
3950 ((uint32_t *)masks)[0] |= bit;
3951 } else {
3952 ((uint32_t *)masks)[1] |= bit;
3954 break;
3955 default:
3956 Info1("sizeof(uint32_t)="F_Zu, sizeof(uint32_t));
3957 Error1("applyopts_single: masksize "F_Zu" not implemented",
3958 masksize);
3961 break;
3963 #if _WITH_SOCKET
3964 case OFUNC_SOCKOPT:
3965 switch (opt->desc->optcode) {
3966 #if WITH_IP4 && (defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN))
3967 case OPT_IP_ADD_MEMBERSHIP:
3969 union {
3970 #if HAVE_STRUCT_IP_MREQN
3971 struct ip_mreqn mreqn;
3972 #endif
3973 struct ip_mreq mreq;
3974 } ip4_mreqn = {{{0}}};
3975 /* IPv6 not supported - seems to have different handling */
3977 mc:addr:ifname|ifind
3978 mc:ifname|ifind
3979 mc:addr
3981 union sockaddr_union sockaddr1;
3982 socklen_t socklen1 = sizeof(sockaddr1.ip4);
3983 union sockaddr_union sockaddr2;
3984 socklen_t socklen2 = sizeof(sockaddr2.ip4);
3986 /* first parameter is alway multicast address */
3987 /*! result */
3988 xiogetaddrinfo(opt->value.u_ip_mreq.multiaddr, NULL,
3989 xfd->para.socket.la.soa.sa_family,
3990 SOCK_DGRAM, IPPROTO_IP,
3991 &sockaddr1, &socklen1, 0, 0);
3992 ip4_mreqn.mreq.imr_multiaddr = sockaddr1.ip4.sin_addr;
3993 if (0) {
3994 ; /* for canonical reasons */
3995 #if HAVE_STRUCT_IP_MREQN
3996 } else if (opt->value.u_ip_mreq.ifindex[0] != '\0') {
3997 /* three parameters */
3998 /* second parameter is interface address */
3999 xiogetaddrinfo(opt->value.u_ip_mreq.param2, NULL,
4000 xfd->para.socket.la.soa.sa_family,
4001 SOCK_DGRAM, IPPROTO_IP,
4002 &sockaddr2, &socklen2, 0, 0);
4003 ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_addr;
4004 /* third parameter is interface */
4005 if (ifindex(opt->value.u_ip_mreq.ifindex,
4006 (unsigned int *)&ip4_mreqn.mreqn.imr_ifindex, -1)
4007 < 0) {
4008 Error1("cannot resolve interface \"%s\"",
4009 opt->value.u_ip_mreq.ifindex);
4011 #endif /* HAVE_STRUCT_IP_MREQN */
4012 } else {
4013 /* two parameters */
4014 if (0) {
4015 ; /* for canonical reasons */
4016 #if HAVE_STRUCT_IP_MREQN
4017 /* there is a form with two parameters that uses mreqn */
4018 } else if (ifindex(opt->value.u_ip_mreq.param2,
4019 (unsigned int *)&ip4_mreqn.mreqn.imr_ifindex,
4021 >= 0) {
4022 /* yes, second param converts to interface */
4023 ip4_mreqn.mreq.imr_interface.s_addr = htonl(0);
4024 #endif /* HAVE_STRUCT_IP_MREQN */
4025 } else {
4026 /*! result */
4027 xiogetaddrinfo(opt->value.u_ip_mreq.param2, NULL,
4028 xfd->para.socket.la.soa.sa_family,
4029 SOCK_DGRAM, IPPROTO_IP,
4030 &sockaddr2, &socklen2, 0, 0);
4031 ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_addr;
4035 #if LATER
4036 if (0) {
4037 ; /* for canonical reasons */
4038 } else if (xfd->para.socket.la.soa.sa_family == PF_INET) {
4039 } else if (xfd->para.socket.la.soa.sa_family == PF_INET6) {
4040 ip6_mreqn.mreq.imr_multiaddr = sockaddr1.ip6.sin6_addr;
4041 ip6_mreqn.mreq.imr_interface = sockaddr2.ip6.sin6_addr;
4043 #endif
4045 #if HAVE_STRUCT_IP_MREQN
4046 if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor,
4047 &ip4_mreqn.mreqn, sizeof(ip4_mreqn.mreqn)) < 0) {
4048 Error8("setsockopt(%d, %d, %d, {0x%08x,0x%08x,%d}, "F_Zu"): %s",
4049 xfd->fd, opt->desc->major, opt->desc->minor,
4050 ip4_mreqn.mreqn.imr_multiaddr.s_addr,
4051 ip4_mreqn.mreqn.imr_address.s_addr,
4052 ip4_mreqn.mreqn.imr_ifindex,
4053 sizeof(ip4_mreqn.mreqn),
4054 strerror(errno));
4055 opt->desc = ODESC_ERROR; continue;
4057 #else
4058 if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor,
4059 &ip4_mreqn.mreq, sizeof(ip4_mreqn.mreq)) < 0) {
4060 Error7("setsockopt(%d, %d, %d, {0x%08x,0x%08x}, "F_Zu"): %s",
4061 xfd->fd, opt->desc->major, opt->desc->minor,
4062 ip4_mreqn.mreq.imr_multiaddr,
4063 ip4_mreqn.mreq.imr_interface,
4064 sizeof(ip4_mreqn.mreq),
4065 strerror(errno));
4066 opt->desc = ODESC_ERROR; continue;
4068 #endif
4069 break;
4071 break;
4072 #endif /* WITH_IP4 && (defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)) */
4074 #if WITH_IP4 && defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP)
4075 case OPT_IP_ADD_SOURCE_MEMBERSHIP:
4076 if (xioapply_ip_add_source_membership(xfd, opt) < 0) {
4077 continue;
4079 break;
4080 #endif /* WITH_IP4 && defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP) */
4082 #if WITH_IP6 && defined(HAVE_STRUCT_IPV6_MREQ)
4083 case OPT_IPV6_JOIN_GROUP:
4085 struct ipv6_mreq ip6_mreq = {{{{0}}}};
4086 union sockaddr_union sockaddr1;
4087 socklen_t socklen1 = sizeof(sockaddr1.ip6);
4089 /* always two parameters */
4090 /* first parameter is multicast address */
4091 /*! result */
4092 xiogetaddrinfo(opt->value.u_ip_mreq.multiaddr, NULL,
4093 xfd->para.socket.la.soa.sa_family,
4094 SOCK_DGRAM, IPPROTO_IP,
4095 &sockaddr1, &socklen1, 0, 0);
4096 ip6_mreq.ipv6mr_multiaddr = sockaddr1.ip6.sin6_addr;
4097 if (ifindex(opt->value.u_ip_mreq.param2,
4098 &ip6_mreq.ipv6mr_interface, -1)
4099 < 0) {
4100 Error1("interface \"%s\" not found",
4101 opt->value.u_ip_mreq.param2);
4102 ip6_mreq.ipv6mr_interface = htonl(0);
4105 if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor,
4106 &ip6_mreq, sizeof(ip6_mreq)) < 0) {
4107 Error6("setsockopt(%d, %d, %d, {...,0x%08x}, "F_Zu"): %s",
4108 xfd->fd, opt->desc->major, opt->desc->minor,
4109 ip6_mreq.ipv6mr_interface,
4110 sizeof(ip6_mreq),
4111 strerror(errno));
4112 opt->desc = ODESC_ERROR; continue;
4115 break;
4116 #endif /* WITH_IP6 && defined(HAVE_STRUCT_IPV6_MREQ) */
4117 default:
4118 /* ignore here */
4119 ++opt; continue;
4121 break;
4122 #endif /* _WITH_SOCKET */
4124 default:
4125 ++opt;
4126 continue;
4128 opt->desc = ODESC_DONE;
4129 ++opt;
4132 return 0;
4136 /* xfd->para.exec.pid must be set */
4137 int applyopts_signal(struct single *xfd, struct opt *opts) {
4138 struct opt *opt;
4140 if (!opts) return 0;
4142 opt = opts; while (opt->desc != ODESC_END) {
4143 if (opt->desc == ODESC_DONE || opt->desc->func != OFUNC_SIGNAL) {
4144 ++opt; continue;
4147 if (xio_opt_signal(xfd->para.exec.pid, opt->desc->major) < 0) {
4148 opt->desc = ODESC_ERROR; continue;
4150 opt->desc = ODESC_DONE;
4151 ++opt;
4153 return 0;
4156 /* apply remaining options to file descriptor, and tell us if something is
4157 still unused */
4158 int _xio_openlate(struct single *fd, struct opt *opts) {
4159 int numleft;
4160 int result;
4162 _xioopen_setdelayeduser();
4164 if ((result = applyopts(fd->fd, opts, PH_LATE)) < 0) {
4165 return result;
4167 if ((result = applyopts_single(fd, opts, PH_LATE)) < 0) {
4168 return result;
4170 if ((result = applyopts(fd->fd, opts, PH_LATE2)) < 0) {
4171 return result;
4174 if ((numleft = leftopts(opts)) > 0) {
4175 showleft(opts);
4176 Error1("%d option(s) could not be used", numleft);
4177 return -1;
4179 return 0;
4182 int dropopts(struct opt *opts, unsigned int phase) {
4183 struct opt *opt;
4185 if (phase == PH_ALL) {
4186 opts[0].desc = ODESC_END;
4187 return 0;
4189 opt = opts; while (opt && opt->desc != ODESC_END) {
4190 if (opt->desc != ODESC_DONE && opt->desc->phase == phase) {
4191 Debug1("ignoring option \"%s\"", opt->desc->defname);
4192 opt->desc = ODESC_DONE;
4194 ++opt;
4196 return 0;
4199 int dropopts2(struct opt *opts, unsigned int from, unsigned int to) {
4200 unsigned int i;
4202 for (i = from; i <= to; ++i) {
4203 dropopts(opts, i);
4205 return 0;