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