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