diff --git a/CHANGES b/CHANGES index 3251e53..550cb53 100644 --- a/CHANGES +++ b/CHANGES @@ -188,6 +188,8 @@ Coding: Moved multicast related code from xioopts.c to xio-ip.c and xio-ip6.c + Pointers of type struct single are now always called sfd. + Porting: Removed Config/ because its contents have not been maintained for many years. @@ -207,6 +209,8 @@ Documentation: Renamed xiogetpacketsrc() to xiogetancillary() + On bad parameter number now print syntax. + ####################### V 1.7.4.5 (not released): Corrections: diff --git a/test.sh b/test.sh index 052721c..214524a 100755 --- a/test.sh +++ b/test.sh @@ -17097,7 +17097,6 @@ CMD0="$TRACE $SOCAT $opts -T 2 PIPE EXEC:\"$CAT\",pty,setsid,sigint" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & pid0=$! -#echo "pid0=$pid0" >&2 #!!! sleep 1 kill -INT $pid0 wait diff --git a/xio-creat.c b/xio-creat.c index 2d7fbdc..c2f09d7 100644 --- a/xio-creat.c +++ b/xio-creat.c @@ -13,7 +13,7 @@ #include "xio-creat.h" -static int xioopen_creat(int arg, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3); +static int xioopen_creat(int arg, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, const struct addrdesc *addrdesc); /*! within stream model, this is a write-only address - use 2 instead of 3 */ @@ -37,7 +37,14 @@ static int _xioopen_creat(const char *path, int rw, struct opt *opts) { } -static int xioopen_creat(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int dummy1, int dummy2, int dummy3) { +static int xioopen_creat( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ struct single *sfd = &xxfd->stream; const char *filename = argv[1]; int rw = (xioflags&XIO_ACCMODE); @@ -46,7 +53,10 @@ static int xioopen_creat(int argc, const char *argv[], struct opt *opts, int xio int result; /* remove old file, or set user/permissions on old file; parse options */ - if ((result = _xioopen_named_early(argc, argv, xxfd, groups, &exists, opts)) < 0) { + if ((result = + _xioopen_named_early(argc, argv, xxfd, addrdesc->groups, &exists, opts, + addrdesc->syntax)) + < 0) { return result; } diff --git a/xio-exec.c b/xio-exec.c index 5ca274e..bed513c 100644 --- a/xio-exec.c +++ b/xio-exec.c @@ -13,23 +13,20 @@ #if WITH_EXEC -static int xioopen_exec(int argc, const char *argv[], struct opt *opts, - int xioflags, /* XIO_RDONLY etc. */ - xiofile_t *fd, - groups_t groups, - int dummy1, int dummy2, int dummy3 - ); +static int xioopen_exec(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); const struct addrdesc xioaddr_exec = { "EXEC", 3, xioopen_exec, GROUP_FD|GROUP_FORK|GROUP_EXEC|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_TERMIOS|GROUP_FIFO|GROUP_PTY|GROUP_PARENT, 0, 0, 0 HELP(":") }; const struct optdesc opt_dash = { "dash", "login", OPT_DASH, GROUP_EXEC, PH_PREEXEC, TYPE_BOOL, OFUNC_SPEC }; -static int xioopen_exec(int argc, const char *argv[], struct opt *opts, - int xioflags, /* XIO_RDONLY, XIO_MAYCHILD etc. */ - xiofile_t *xfd, - groups_t groups, - int dummy1, int dummy2, int dummy3 - ) { +static int xioopen_exec( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, /* XIO_RDONLY, XIO_MAYCHILD etc. */ + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ struct single *sfd = &xfd->stream; int status; bool dash = false; @@ -37,12 +34,14 @@ static int xioopen_exec(int argc, const char *argv[], struct opt *opts, int numleft; if (argc != 2) { - Error2("\"%s\": wrong number of parameters (%d instead of 1)", argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); + return STAT_NORETRY; } retropt_bool(opts, OPT_DASH, &dash); - status = _xioopen_foxec(xioflags, sfd, groups, &opts, &duptostderr); + status = + _xioopen_foxec(xioflags, sfd, addrdesc->groups, &opts, &duptostderr); if (status < 0) return status; if (status == 0) { /* child */ diff --git a/xio-fdnum.c b/xio-fdnum.c index 26bc48a..fdff75f 100644 --- a/xio-fdnum.c +++ b/xio-fdnum.c @@ -14,8 +14,8 @@ #if WITH_FDNUM -static int xioopen_fdnum(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3); -static int xioopen_accept_fd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3); +static int xioopen_fdnum(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); +static int xioopen_accept_fd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); const struct addrdesc xioaddr_fd = { "FD", 1+XIO_RDWR, xioopen_fdnum, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_FILE|GROUP_SOCKET|GROUP_TERMIOS|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP, 0, 0, 0 HELP(":") }; @@ -25,9 +25,14 @@ const struct addrdesc xioaddr_accept_fd = { "ACCEPT-FD", 1+XIO_RDWR, xioopen_acc /* use some file descriptor and apply the options. Set the FD_CLOEXEC flag. */ -static int xioopen_fdnum(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int dummy1, int dummy2, int dummy3) { +static int xioopen_fdnum( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ char *a1; int rw = (xioflags&XIO_ACCMODE); int numfd; @@ -46,7 +51,7 @@ static int xioopen_fdnum(int argc, const char *argv[], struct opt *opts, Warn2("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", numfd, strerror(errno)); } Notice2("using file descriptor %d for %s", numfd, ddirection[rw]); - if ((result = xioopen_fd(opts, rw, &xfd->stream, numfd, dummy2, dummy3)) < 0) { + if ((result = xioopen_fd(opts, rw, &xfd->stream, numfd)) < 0) { return result; } return 0; @@ -61,10 +66,7 @@ static int xioopen_accept_fd( struct opt *opts, int xioflags, xiofile_t *xfd, - groups_t groups, - int dummy1, - int dummy2, - int dummy3) + const struct addrdesc *addrdesc) { char *a1; int rw = (xioflags&XIO_ACCMODE); @@ -74,7 +76,8 @@ static int xioopen_accept_fd( int result; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); + return STAT_NORETRY; } numfd = strtoul(argv[1], &a1, 0); @@ -103,29 +106,29 @@ static int xioopen_accept_fd( #if WITH_FD -/* retrieve and apply options to a standard file descriptor. - Do not set FD_CLOEXEC flag. */ -int xioopen_fd(struct opt *opts, int rw, xiosingle_t *xfd, int numfd, int dummy2, int dummy3) { +/* Retrieves and apply options to a standard file descriptor. + Does not set FD_CLOEXEC flag. */ +int xioopen_fd(struct opt *opts, int rw, struct single *sfd, int numfd) { - xfd->fd = numfd; - xfd->howtoend = END_NONE; + sfd->fd = numfd; + sfd->howtoend = END_NONE; #if WITH_TERMIOS - if (Isatty(xfd->fd)) { - if (Tcgetattr(xfd->fd, &xfd->savetty) < 0) { + if (Isatty(sfd->fd)) { + if (Tcgetattr(sfd->fd, &sfd->savetty) < 0) { Warn2("cannot query current terminal settings on fd %d: %s", - xfd->fd, strerror(errno)); + sfd->fd, strerror(errno)); } else { - xfd->ttyvalid = true; + sfd->ttyvalid = true; } } #endif /* WITH_TERMIOS */ - if (applyopts_single(xfd, opts, PH_INIT) < 0) + if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; - applyopts2(xfd, -1, opts, PH_INIT, PH_FD); + applyopts2(sfd, -1, opts, PH_INIT, PH_FD); - return _xio_openlate(xfd, opts); + return _xio_openlate(sfd, opts); } #endif /* WITH_FD */ diff --git a/xio-fdnum.h b/xio-fdnum.h index 9e3acdb..4589602 100644 --- a/xio-fdnum.h +++ b/xio-fdnum.h @@ -8,6 +8,6 @@ extern const struct addrdesc xioaddr_fd; extern const struct addrdesc xioaddr_accept_fd; -extern int xioopen_fd(struct opt *opts, int rw, xiosingle_t *xfd, int numfd, int dummy2, int dummy3); +extern int xioopen_fd(struct opt *opts, int rw, xiosingle_t *xfd, int numfd); #endif /* !defined(__xio_fdnum_h_included) */ diff --git a/xio-file.c b/xio-file.c index f41226e..c19be4b 100644 --- a/xio-file.c +++ b/xio-file.c @@ -11,7 +11,7 @@ #include "xio-file.h" -static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3); +static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); #if WITH_OPEN @@ -72,7 +72,14 @@ const struct addrdesc xioaddr_open = { "OPEN", 3, xioopen_open, GROUP_FD|GRO if the filesystem entry already exists, the data is appended if it does not exist, a file is created and the data is appended */ -static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) { +static int xioopen_open( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ const char *filename = argv[1]; int rw = (xioflags & XIO_ACCMODE); struct single *sfd = &xfd->stream; @@ -81,7 +88,10 @@ static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xiof int result; /* remove old file, or set user/permissions on old file; parse options */ - if ((result = _xioopen_named_early(argc, argv, xfd, groups, &exists, opts)) < 0) { + if ((result = + _xioopen_named_early(argc, argv, xfd, addrdesc->groups, &exists, opts, + addrdesc->syntax)) + < 0) { return result; } diff --git a/xio-gopen.c b/xio-gopen.c index 27488a2..7d251c7 100644 --- a/xio-gopen.c +++ b/xio-gopen.c @@ -14,12 +14,19 @@ #if WITH_GOPEN -static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3); +static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); const struct addrdesc xioaddr_gopen = { "GOPEN", 3, xioopen_gopen, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_REG|GROUP_NAMED|GROUP_OPEN|GROUP_FILE|GROUP_TERMIOS|GROUP_SOCKET|GROUP_SOCK_UNIX, 0, 0, 0 HELP(":") }; -static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int dummy1, int dummy2, int dummy3) { +static int xioopen_gopen( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ struct single *sfd = &xxfd->stream; const char *filename = argv[1]; flags_t openflags = (xioflags & XIO_ACCMODE); @@ -29,7 +36,9 @@ static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xio int result; if ((result = - _xioopen_named_early(argc, argv, xxfd, GROUP_NAMED|groups, &exists, opts)) < 0) { + _xioopen_named_early(argc, argv, xxfd, GROUP_NAMED|addrdesc->groups, &exists, + opts, addrdesc->syntax)) + < 0) { return result; } st_mode = result; @@ -53,7 +62,7 @@ static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xio Info1("\"%s\" is a socket, connecting to it", filename); result = - _xioopen_unix_client(sfd, xioflags, groups, 0, opts, filename); + _xioopen_unix_client(sfd, xioflags, addrdesc->groups, 0, opts, filename); if (result < 0) { return result; } diff --git a/xio-interface.c b/xio-interface.c index 6fe1231..5d13b63 100644 --- a/xio-interface.c +++ b/xio-interface.c @@ -15,10 +15,7 @@ #include "xio-interface.h" -static -int xioopen_interface(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, int pf, - int dummy2, int dummy3); +static int xioopen_interface(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); /*0 const struct optdesc opt_interface_addr = { "interface-addr", "address", OPT_INTERFACE_ADDR, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };*/ /*0 const struct optdesc opt_interface_netmask = { "interface-netmask", "netmask", OPT_INTERFACE_NETMASK, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };*/ @@ -62,7 +59,7 @@ static int _xioopen_interface(const char *ifname, struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int pf) { - xiosingle_t *xfd = &xxfd->stream; + xiosingle_t *sfd = &xxfd->stream; union sockaddr_union us = {{0}}; socklen_t uslen; int socktype = SOCK_RAW; @@ -77,21 +74,21 @@ int _xioopen_interface(const char *ifname, ifidx = 0; /* desparate attempt to continue */ } - xfd->howtoend = END_INTERFACE; + sfd->howtoend = END_INTERFACE; retropt_int(opts, OPT_SO_TYPE, &socktype); retropt_socket_pf(opts, &pf); /* ...res_opts[] */ - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; - applyopts(xfd, -1, opts, PH_INIT); + if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; + applyopts(sfd, -1, opts, PH_INIT); - xfd->salen = sizeof(xfd->peersa); + sfd->salen = sizeof(sfd->peersa); if (pf == PF_UNSPEC) { - pf = xfd->peersa.soa.sa_family; + pf = sfd->peersa.soa.sa_family; } - xfd->dtype = XIODATA_RECVFROM_SKIPIP; + sfd->dtype = XIODATA_RECVFROM_SKIPIP; if (retropt_string(opts, OPT_BIND, &bindstring)) { needbind = true; @@ -102,24 +99,24 @@ int _xioopen_interface(const char *ifname, us.ll.sll_ifindex = ifidx; uslen = sizeof(sall); needbind = true; - xfd->peersa = (union sockaddr_union)us; + sfd->peersa = (union sockaddr_union)us; rc = _xioopen_dgram_sendto(needbind?&us:NULL, uslen, - opts, xioflags, xfd, groups, pf, socktype, 0, 0); + opts, xioflags, sfd, groups, pf, socktype, 0, 0); if (rc < 0) return rc; - strncpy(xfd->para.interface.name, ifname, IFNAMSIZ); - _xiointerface_get_iff(xfd->fd, ifname, &xfd->para.interface.save_iff); - _xiointerface_apply_iff(xfd->fd, ifname, xfd->para.interface.iff_opts); + strncpy(sfd->para.interface.name, ifname, IFNAMSIZ); + _xiointerface_get_iff(sfd->fd, ifname, &sfd->para.interface.save_iff); + _xiointerface_apply_iff(sfd->fd, ifname, sfd->para.interface.iff_opts); #ifdef PACKET_IGNORE_OUTGOING /* Raw socket might also provide packets that are outbound - we are not interested in these and disable this "feature" in kernel if possible */ - if (Setsockopt(xfd->fd, SOL_PACKET, PACKET_IGNORE_OUTGOING, &one, sizeof(one)) < 0) { + if (Setsockopt(sfd->fd, SOL_PACKET, PACKET_IGNORE_OUTGOING, &one, sizeof(one)) < 0) { Warn2("setsockopt(%d, SOL_PACKET, PACKET_IGNORE_OUTGOING, {1}): %s", - xfd->fd, strerror(errno)); + sfd->fd, strerror(errno)); } #endif /*defined(PACKET_IGNORE_OUTGOING) */ @@ -144,32 +141,37 @@ int _interface_setsockopt_auxdata(int fd, int auxdata) { } static -int xioopen_interface(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int pf, int dummy2, int dummy3) { - xiosingle_t *xfd = &xxfd->stream; +int xioopen_interface( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ + xiosingle_t *sfd = &xxfd->stream; int result; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } if ((result = - _xioopen_interface(argv[1], opts, xioflags, xxfd, groups, pf)) + _xioopen_interface(argv[1], opts, xioflags, xxfd, addrdesc->groups, + addrdesc->arg1)) != STAT_OK) { return result; } - xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; - if (pf == PF_INET) { - xfd->dtype |= XIOREAD_RECV_SKIPIP; + sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; + if (addrdesc->arg1 == PF_INET) { + sfd->dtype |= XIOREAD_RECV_SKIPIP; } - xfd->para.socket.la.soa.sa_family = xfd->peersa.soa.sa_family; + sfd->para.socket.la.soa.sa_family = sfd->peersa.soa.sa_family; - _xio_openlate(xfd, opts); + _xio_openlate(sfd, opts); return STAT_OK; } diff --git a/xio-ip.c b/xio-ip.c index a89183d..53ae1af 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -731,7 +731,7 @@ int xiotype_ip_add_membership( #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) int xioapply_ip_add_membership( - xiosingle_t *xfd, + struct single *sfd, struct opt *opt) { union { @@ -754,9 +754,9 @@ mc:addr /* First parameter is always multicast address */ /*! result */ xioresolve(opt->value.u_string/*multiaddr*/, NULL, - xfd->para.socket.la.soa.sa_family, + sfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr1, &socklen1, - xfd->para.socket.ip.ai_flags); + sfd->para.socket.ip.ai_flags); ip4_mreqn.mreq.imr_multiaddr = sockaddr1.ip4.sin_addr; if (0) { ; /* for canonical reasons */ @@ -765,9 +765,9 @@ mc:addr /* three parameters */ /* second parameter is interface address */ xioresolve(opt->value2.u_string/*param2*/, NULL, - xfd->para.socket.la.soa.sa_family, + sfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr2, &socklen2, - xfd->para.socket.ip.ai_flags); + sfd->para.socket.ip.ai_flags); ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_addr; /* third parameter is interface */ if (ifindex(opt->value3.u_string/*ifindex*/, @@ -793,10 +793,10 @@ mc:addr } else { /*! result */ xioresolve(opt->value2.u_string/*param2*/, NULL, - xfd->para.socket.la.soa.sa_family, + sfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr2, &socklen2, - xfd->para.socket.ip.ai_flags); + sfd->para.socket.ip.ai_flags); ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_addr; } } @@ -804,18 +804,18 @@ mc:addr #if LATER if (0) { ; /* for canonical reasons */ - } else if (xfd->para.socket.la.soa.sa_family == PF_INET) { - } else if (xfd->para.socket.la.soa.sa_family == PF_INET6) { + } else if (sfd->para.socket.la.soa.sa_family == PF_INET) { + } else if (sfd->para.socket.la.soa.sa_family == PF_INET6) { ip6_mreqn.mreq.imr_multiaddr = sockaddr1.ip6.sin6_addr; ip6_mreqn.mreq.imr_interface = sockaddr2.ip6.sin6_addr; } #endif #if HAVE_STRUCT_IP_MREQN - if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor, + if (Setsockopt(sfd->fd, opt->desc->major, opt->desc->minor, &ip4_mreqn.mreqn, sizeof(ip4_mreqn.mreqn)) < 0) { Error8("setsockopt(%d, %d, %d, {0x%08x,0x%08x,%d}, "F_Zu"): %s", - xfd->fd, opt->desc->major, opt->desc->minor, + sfd->fd, opt->desc->major, opt->desc->minor, ip4_mreqn.mreqn.imr_multiaddr.s_addr, ip4_mreqn.mreqn.imr_address.s_addr, ip4_mreqn.mreqn.imr_ifindex, @@ -825,10 +825,10 @@ mc:addr return -1; } #else - if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor, + if (Setsockopt(sfd->fd, opt->desc->major, opt->desc->minor, &ip4_mreqn.mreq, sizeof(ip4_mreqn.mreq)) < 0) { Error7("setsockopt(%d, %d, %d, {0x%08x,0x%08x}, "F_Zu"): %s", - xfd->fd, opt->desc->major, opt->desc->minor, + sfd->fd, opt->desc->major, opt->desc->minor, ip4_mreqn.mreq.imr_multiaddr, ip4_mreqn.mreq.imr_interface, sizeof(ip4_mreqn.mreq), @@ -932,7 +932,7 @@ int xiotype_ip_add_source_membership(char *token, const struct optname *ent, str return 0; } -int xioapply_ip_add_source_membership(struct single *xfd, struct opt *opt) { +int xioapply_ip_add_source_membership(struct single *sfd, struct opt *opt) { struct ip_mreq_source ip4_mreq_src = {{0}}; /* IPv6 not supported - seems to have different handling */ union sockaddr_union sockaddr1; @@ -945,35 +945,35 @@ int xioapply_ip_add_source_membership(struct single *xfd, struct opt *opt) { /* first parameter is always multicast address */ rc = xioresolve(opt->value.u_string/*mcaddr*/, NULL, - xfd->para.socket.la.soa.sa_family, + sfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, - &sockaddr1, &socklen1, xfd->para.socket.ip.ai_flags); + &sockaddr1, &socklen1, sfd->para.socket.ip.ai_flags); if (rc < 0) { return -1; } ip4_mreq_src.imr_multiaddr = sockaddr1.ip4.sin_addr; /* second parameter is interface address */ rc = xioresolve(opt->value.u_string/*ifaddr*/, NULL, - xfd->para.socket.la.soa.sa_family, + sfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, - &sockaddr2, &socklen2, xfd->para.socket.ip.ai_flags); + &sockaddr2, &socklen2, sfd->para.socket.ip.ai_flags); if (rc < 0) { return -1; } ip4_mreq_src.imr_interface = sockaddr2.ip4.sin_addr; /* third parameter is source address */ rc = xioresolve(opt->value.u_string/*srcaddr*/, NULL, - xfd->para.socket.la.soa.sa_family, + sfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, - &sockaddr3, &socklen3, xfd->para.socket.ip.ai_flags); + &sockaddr3, &socklen3, sfd->para.socket.ip.ai_flags); if (rc < 0) { return -1; } ip4_mreq_src.imr_sourceaddr = sockaddr3.ip4.sin_addr; - if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor, + if (Setsockopt(sfd->fd, opt->desc->major, opt->desc->minor, &ip4_mreq_src, sizeof(ip4_mreq_src)) < 0) { Error8("setsockopt(%d, %d, %d, {0x%08x,0x%08x,0x%08x}, "F_Zu"): %s", - xfd->fd, opt->desc->major, opt->desc->minor, + sfd->fd, opt->desc->major, opt->desc->minor, htonl((uint32_t)ip4_mreq_src.imr_multiaddr.s_addr), ip4_mreq_src.imr_interface.s_addr, ip4_mreq_src.imr_sourceaddr.s_addr, diff --git a/xio-ip6.c b/xio-ip6.c index 49a18d1..51f7af3 100644 --- a/xio-ip6.c +++ b/xio-ip6.c @@ -259,7 +259,7 @@ int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange *range) { returns STAT_OK on success */ int xiolog_ancillary_ip6( - struct single *xfd, + struct single *sfd, struct cmsghdr *cmsg, int *num, char *typbuff, int typlen, @@ -476,7 +476,7 @@ xiosetsockaddrenv_ip6(int idx, char *namebuff, size_t namelen, #if defined(HAVE_STRUCT_IPV6_MREQ) int xioapply_ipv6_join_group( - xiosingle_t *xfd, + struct single *sfd, struct opt *opt) { struct ipv6_mreq ip6_mreq = {{{{0}}}}; @@ -488,10 +488,10 @@ int xioapply_ipv6_join_group( /* First parameter is multicast address */ if ((res = xioresolve(opt->value.u_string/*multiaddr*/, NULL, - xfd->para.socket.la.soa.sa_family, + sfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr1, &socklen1, - xfd->para.socket.ip.ai_flags)) + sfd->para.socket.ip.ai_flags)) != STAT_OK) { return res; } @@ -504,10 +504,10 @@ int xioapply_ipv6_join_group( ip6_mreq.ipv6mr_interface = htonl(0); } - if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor, + if (Setsockopt(sfd->fd, opt->desc->major, opt->desc->minor, &ip6_mreq, sizeof(ip6_mreq)) < 0) { Error6("setsockopt(%d, %d, %d, {...,0x%08x}, "F_Zu"): %s", - xfd->fd, opt->desc->major, opt->desc->minor, + sfd->fd, opt->desc->major, opt->desc->minor, ip6_mreq.ipv6mr_interface, sizeof(ip6_mreq), strerror(errno)); @@ -618,7 +618,7 @@ int xiotype_ip6_join_source_group( return 0; } -int xioapply_ip6_join_source_group(struct single *xfd, struct opt *opt) { +int xioapply_ip6_join_source_group(struct single *sfd, struct opt *opt) { struct group_source_req ip6_gsr = {0}; union sockaddr_union sockaddr1; socklen_t socklen1 = sizeof(sockaddr1.ip6); @@ -629,9 +629,9 @@ int xioapply_ip6_join_source_group(struct single *xfd, struct opt *opt) { /* First parameter is always multicast address */ if ((res = xioresolve(opt->value.u_string/*mcaddr*/, NULL, - xfd->para.socket.la.soa.sa_family, + sfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr1, &socklen1, - xfd->para.socket.ip.ai_flags)) + sfd->para.socket.ip.ai_flags)) != STAT_OK) { return res; } @@ -647,17 +647,17 @@ int xioapply_ip6_join_source_group(struct single *xfd, struct opt *opt) { /* Third parameter is source address */ if ((res = xioresolve(opt->value3.u_string/*srcaddr*/, NULL, - xfd->para.socket.la.soa.sa_family, + sfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr2, &socklen2, - xfd->para.socket.ip.ai_flags)) + sfd->para.socket.ip.ai_flags)) != STAT_OK) { return res; } memcpy(&ip6_gsr.gsr_source, &sockaddr2.ip6, socklen2); - if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor, + if (Setsockopt(sfd->fd, opt->desc->major, opt->desc->minor, &ip6_gsr, sizeof(ip6_gsr)) < 0) { Error6("setsockopt(%d, %d, %d, {%d,...}, "F_Zu"): %s", - xfd->fd, opt->desc->major, opt->desc->minor, + sfd->fd, opt->desc->major, opt->desc->minor, ip6_gsr.gsr_interface, sizeof(ip6_gsr), strerror(errno)); diff --git a/xio-ipapp.c b/xio-ipapp.c index 7fbeb70..1487168 100644 --- a/xio-ipapp.c +++ b/xio-ipapp.c @@ -21,12 +21,19 @@ const struct optdesc opt_lowport = { "lowport", NULL, OPT_LOWPORT, GROUP_IPAPP, #if WITH_IP4 /* we expect the form "host:port" */ -int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, - groups_t groups, int socktype, int ipproto, - int pf) { - struct single *xfd = &xxfd->stream; +int xioopen_ipapp_connect( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ + struct single *sfd = &xxfd->stream; struct opt *opts0 = NULL; + int socktype = addrdesc->arg1; + int ipproto = addrdesc->arg2; + int pf = addrdesc->arg3; const char *hostname = argv[1], *portname = argv[2]; bool dofork = false; union sockaddr_union us_sa, *us = &us_sa; @@ -41,19 +48,21 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, int result; if (argc != 3) { - Error2("%s: wrong number of parameters (%d instead of 2)", argv[0], argc-1); + xio_syntax(argv[0], 2, argc-1, addrdesc->syntax); + return STAT_NORETRY; } - xfd->howtoend = END_SHUTDOWN; + xioinit_ip(&pf, xioparms.default_ip); + sfd->howtoend = END_SHUTDOWN; - if (applyopts_single(xfd, opts, PH_INIT) < 0) + if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; - applyopts(xfd, -1, opts, PH_INIT); + applyopts(sfd, -1, opts, PH_INIT); retropt_bool(opts, OPT_FORK, &dofork); if (_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto, - xfd->para.socket.ip.ai_flags, + sfd->para.socket.ip.ai_flags, &themlist, us, &uslen, &needbind, &lowport, socktype) != STAT_OK) { return STAT_NORETRY; @@ -95,14 +104,14 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, infobuff, sizeof(infobuff))); #if WITH_RETRY - if (xfd->forever || xfd->retry || ai_sorted[i] != NULL) { + if (sfd->forever || sfd->retry || ai_sorted[i] != NULL) { level = E_INFO; } else #endif /* WITH_RETRY */ level = E_ERROR; result = - _xioopen_connect(xfd, + _xioopen_connect(sfd, needbind?us:NULL, uslen, themp->ai_addr, themp->ai_addrlen, opts, pf?pf:themp->ai_family, socktype, ipproto, @@ -119,10 +128,10 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (xfd->forever || xfd->retry) { - --xfd->retry; + if (sfd->forever || sfd->retry) { + --sfd->retry; if (result == STAT_RETRYLATER) { - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); } dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL); continue; @@ -138,13 +147,13 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, if (dofork) { pid_t pid; int level = E_ERROR; - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { level = E_WARN; /* most users won't expect a problem here, so Notice is too weak */ } - while ((pid = xio_fork(false, level, xfd->shutup)) < 0) { - if (xfd->forever || --xfd->retry) { - Nanosleep(&xfd->intervall, NULL); continue; + while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { + if (sfd->forever || --sfd->retry) { + Nanosleep(&sfd->intervall, NULL); continue; } free(ai_sorted); free(opts0); @@ -152,14 +161,14 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, } if (pid == 0) { /* child process */ - xfd->forever = false; xfd->retry = 0; + sfd->forever = false; sfd->retry = 0; break; } /* parent process */ - Close(xfd->fd); + Close(sfd->fd); /* with and without retry */ - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL); continue; /* with next socket() bind() connect() */ } else @@ -172,7 +181,7 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, free(ai_sorted); xiofreeaddrinfo(themlist); - if ((result = _xio_openlate(xfd, opts)) < 0) { + if ((result = _xio_openlate(sfd, opts)) < 0) { free(opts0);free(opts); return result; } @@ -302,18 +311,26 @@ int _xioopen_ipapp_listen_prepare( /* we expect the form: port */ /* currently only used for TCP4 */ -int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, - groups_t groups, int socktype, - int ipproto, int pf) { +int xioopen_ipapp_listen( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ struct single *sfd = &xfd->stream; struct opt *opts0 = NULL; + int socktype = addrdesc->arg1; + int ipproto = addrdesc->arg2; + int pf = addrdesc->arg3; union sockaddr_union us_sa, *us = &us_sa; socklen_t uslen = sizeof(us_sa); int result; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); + xio_syntax(argv[0], 2, argc-1, addrdesc->syntax); + return STAT_NORETRY; } xioinit_ip(&pf, xioparms.default_ip); @@ -331,23 +348,23 @@ int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts, #endif } - xfd->stream.howtoend = END_SHUTDOWN; + sfd->howtoend = END_SHUTDOWN; - if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1; + if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; applyopts(sfd, -1, opts, PH_INIT); applyopts(sfd, -1, opts, PH_EARLY); if (_xioopen_ipapp_listen_prepare(opts, &opts0, argv[1], &pf, ipproto, - xfd->stream.para.socket.ip.ai_flags, + sfd->para.socket.ip.ai_flags, us, &uslen, socktype) != STAT_OK) { return STAT_NORETRY; } if ((result = - xioopen_listen(&xfd->stream, xioflags, + xioopen_listen(sfd, xioflags, (struct sockaddr *)us, uslen, - opts, opts0, pf, socktype, ipproto)) + opts, opts0, pf, socktype, ipproto)) != 0) return result; return 0; diff --git a/xio-ipapp.h b/xio-ipapp.h index dbd89eb..20679f7 100644 --- a/xio-ipapp.h +++ b/xio-ipapp.h @@ -14,19 +14,13 @@ extern const struct optdesc opt_sourceport; /*extern const struct optdesc opt_port;*/ extern const struct optdesc opt_lowport; -extern int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, - groups_t groups, int socktype, - int ipproto, int protname); -extern int _xioopen_ipapp_prepare(struct opt *opts, struct opt **opts0, const char *hostname, const char *portname, int *pf, int protocol, const int ai_flags[2], struct addrinfo **res, union sockaddr_union *us, socklen_t *uslen, bool *needbind, bool *lowport, - int socktype); +extern int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); +extern int _xioopen_ipapp_prepare(struct opt *opts, struct opt **opts0, const char *hostname, const char *portname, int *pf, int protocol, const int ai_flags[2], struct addrinfo **res, union sockaddr_union *us, socklen_t *uslen, bool *needbind, bool *lowport, int socktype); extern int _xioopen_ip4app_connect(const char *hostname, const char *portname, struct single *xfd, int socktype, int ipproto, void *protname, struct opt *opts); -extern int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *fd, - groups_t groups, int socktype, - int ipproto, int protname); +extern int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); extern int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0, const char *portname, int *pf, int ipproto, const int ai_flags[2], union sockaddr_union *us, socklen_t *uslen, int socktype); extern int _xio_sort_ip_addresses(struct addrinfo *themlist, struct addrinfo **ai_sorted); diff --git a/xio-listen.c b/xio-listen.c index 078001b..64ac0e9 100644 --- a/xio-listen.c +++ b/xio-listen.c @@ -35,7 +35,7 @@ const struct optdesc opt_accept_timeout = { "accept-timeout", "listen-timeout", OPT_SOURCEPORT, OPT_LOWPORT, cloexec */ int - xioopen_listen(struct single *xfd, int xioflags, + xioopen_listen(struct single *sfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, struct opt *opts0, int pf, int socktype, int proto) { @@ -43,7 +43,7 @@ int int result; #if WITH_RETRY - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { level = E_INFO; } else #endif /* WITH_RETRY */ @@ -53,7 +53,7 @@ int /* tcp listen; this can fork() for us; it only returns on error or on successful establishment of tcp connection */ - result = _xioopen_listen(xfd, xioflags, + result = _xioopen_listen(sfd, xioflags, (struct sockaddr *)us, uslen, opts, pf, socktype, proto, level); /*! not sure if we should try again on retry/forever */ @@ -62,13 +62,13 @@ int #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); if (result == STAT_RETRYLATER) { - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); } dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); - --xfd->retry; + --sfd->retry; continue; } return STAT_NORETRY; @@ -103,31 +103,31 @@ int OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_BACKLOG, OPT_RANGE, tcpwrap, OPT_SOURCEPORT, OPT_LOWPORT, cloexec */ -int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen, +int _xioopen_listen(struct single *sfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, int pf, int socktype, int proto, int level) { int backlog = 5; /* why? 1 seems to cause problems under some load */ char infobuff[256]; - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; + if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; - if ((xfd->fd = xiosocket(opts, pf?pf:us->sa_family, socktype, proto, level)) < 0) { + if ((sfd->fd = xiosocket(opts, pf?pf:us->sa_family, socktype, proto, level)) < 0) { return STAT_RETRYLATER; } - applyopts(xfd, -1, opts, PH_PASTSOCKET); + applyopts(sfd, -1, opts, PH_PASTSOCKET); - applyopts_offset(xfd, opts); - applyopts_cloexec(xfd->fd, opts); + applyopts_offset(sfd, opts); + applyopts_cloexec(sfd->fd, opts); /* Phase prebind */ - xiosock_reuseaddr(xfd->fd, proto, opts); - applyopts(xfd, -1, opts, PH_PREBIND); + xiosock_reuseaddr(sfd->fd, proto, opts); + applyopts(sfd, -1, opts, PH_PREBIND); - applyopts(xfd, -1, opts, PH_BIND); - if (Bind(xfd->fd, (struct sockaddr *)us, uslen) < 0) { - Msg4(level, "bind(%d, {%s}, "F_socklen"): %s", xfd->fd, + applyopts(sfd, -1, opts, PH_BIND); + if (Bind(sfd->fd, (struct sockaddr *)us, uslen) < 0) { + Msg4(level, "bind(%d, {%s}, "F_socklen"): %s", sfd->fd, sockaddr_info(us, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); - Close(xfd->fd); + Close(sfd->fd); return STAT_RETRYLATER; } @@ -136,36 +136,36 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl if (((union sockaddr_union *)us)->un.sun_path[0] != '\0') { applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD); } else { - applyopts(xfd, -1, opts, PH_FD); + applyopts(sfd, -1, opts, PH_FD); } } #endif - applyopts(xfd, -1, opts, PH_PASTBIND); + applyopts(sfd, -1, opts, PH_PASTBIND); #if WITH_UNIX if (us->sa_family == AF_UNIX) { if (((union sockaddr_union *)us)->un.sun_path[0] != '\0') { applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_EARLY); applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN); } else { - applyopts(xfd, -1, opts, PH_EARLY); - applyopts(xfd, -1, opts, PH_PREOPEN); + applyopts(sfd, -1, opts, PH_EARLY); + applyopts(sfd, -1, opts, PH_PREOPEN); } } #endif /* WITH_UNIX */ - applyopts(xfd, -1, opts, PH_PRELISTEN); + applyopts(sfd, -1, opts, PH_PRELISTEN); retropt_int(opts, OPT_BACKLOG, &backlog); - applyopts(xfd, -1, opts, PH_LISTEN); - if (Listen(xfd->fd, backlog) < 0) { - Error3("listen(%d, %d): %s", xfd->fd, backlog, strerror(errno)); + applyopts(sfd, -1, opts, PH_LISTEN); + if (Listen(sfd->fd, backlog) < 0) { + Error3("listen(%d, %d): %s", sfd->fd, backlog, strerror(errno)); return STAT_RETRYLATER; } - return _xioopen_accept_fd(xfd, xioflags, us, uslen, opts, pf, proto,level); + return _xioopen_accept_fd(sfd, xioflags, us, uslen, opts, pf, proto,level); } int _xioopen_accept_fd( - struct single *xfd, + struct single *sfd, int xioflags, struct sockaddr *us, socklen_t uslen, @@ -196,7 +196,7 @@ int _xioopen_accept_fd( Error("option fork not allowed here"); return STAT_NORETRY; } - xfd->flags |= XIO_DOESFORK; + sfd->flags |= XIO_DOESFORK; } retropt_int(opts, OPT_MAX_CHILDREN, &maxchildren); @@ -213,33 +213,33 @@ int _xioopen_accept_fd( /* Under some circumstances (e.g., TCP listen on port 0) bind() fills empty fields that we want to know. */ salen = sizeof(sa); - if (Getsockname(xfd->fd, us, &uslen) < 0) { + if (Getsockname(sfd->fd, us, &uslen) < 0) { Warn4("getsockname(%d, %p, {%d}): %s", - xfd->fd, &us, uslen, strerror(errno)); + sfd->fd, &us, uslen, strerror(errno)); } #if WITH_IP4 /*|| WITH_IP6*/ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (xioparserange(rangename, pf, &xfd->para.socket.range, - xfd->para.socket.ip.ai_flags) + if (xioparserange(rangename, pf, &sfd->para.socket.range, + sfd->para.socket.ip.ai_flags) < 0) { free(rangename); return STAT_NORETRY; } free(rangename); - xfd->para.socket.dorange = true; + sfd->para.socket.dorange = true; } #endif #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP - xio_retropt_tcpwrap(xfd, opts); + xio_retropt_tcpwrap(sfd, opts); #endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */ #if WITH_TCP || WITH_UDP - if (retropt_ushort(opts, OPT_SOURCEPORT, &xfd->para.socket.ip.sourceport) >= 0) { - xfd->para.socket.ip.dosourceport = true; + if (retropt_ushort(opts, OPT_SOURCEPORT, &sfd->para.socket.ip.sourceport) >= 0) { + sfd->para.socket.ip.dosourceport = true; } - retropt_bool(opts, OPT_LOWPORT, &xfd->para.socket.ip.lowport); + retropt_bool(opts, OPT_LOWPORT, &sfd->para.socket.ip.lowport); #endif /* WITH_TCP || WITH_UDP */ if (xioparms.logopt == 'm') { @@ -259,30 +259,30 @@ int _xioopen_accept_fd( do { /*? int level = E_ERROR;*/ Notice1("listening on %s", sockaddr_info(us, uslen, lisname, sizeof(lisname))); - if (xfd->para.socket.accept_timeout.tv_sec > 0 || - xfd->para.socket.accept_timeout.tv_usec > 0) { + if (sfd->para.socket.accept_timeout.tv_sec > 0 || + sfd->para.socket.accept_timeout.tv_usec > 0) { fd_set rfd; struct timeval tmo; FD_ZERO(&rfd); - FD_SET(xfd->fd, &rfd); - tmo.tv_sec = xfd->para.socket.accept_timeout.tv_sec; - tmo.tv_usec = xfd->para.socket.accept_timeout.tv_usec; + FD_SET(sfd->fd, &rfd); + tmo.tv_sec = sfd->para.socket.accept_timeout.tv_sec; + tmo.tv_usec = sfd->para.socket.accept_timeout.tv_usec; while (1) { - if (Select(xfd->fd+1, &rfd, NULL, NULL, &tmo) < 0) { + if (Select(sfd->fd+1, &rfd, NULL, NULL, &tmo) < 0) { if (errno != EINTR) { - Error5("Select(%d, &0x%lx, NULL, NULL, {%ld.%06ld}): %s", xfd->fd+1, 1L<<(xfd->fd+1), - xfd->para.socket.accept_timeout.tv_sec, xfd->para.socket.accept_timeout.tv_usec, + Error5("Select(%d, &0x%lx, NULL, NULL, {%ld.%06ld}): %s", sfd->fd+1, 1L<<(sfd->fd+1), + sfd->para.socket.accept_timeout.tv_sec, sfd->para.socket.accept_timeout.tv_usec, strerror(errno)); } } else { break; } } - if (!FD_ISSET(xfd->fd, &rfd)) { + if (!FD_ISSET(sfd->fd, &rfd)) { struct sigaction act; Warn1("accept: %s", strerror(ETIMEDOUT)); - Close(xfd->fd); + Close(sfd->fd); Notice("Waiting for child processes to terminate"); memset(&act, 0, sizeof(struct sigaction)); act.sa_flags = SA_NOCLDSTOP/*|SA_RESTART*/ @@ -304,9 +304,9 @@ int _xioopen_accept_fd( Exit(0); } } - ps = Accept(xfd->fd, (struct sockaddr *)&sa, &salen); + ps = Accept(sfd->fd, (struct sockaddr *)&sa, &salen); if (ps >= 0) { - /*0 Info4("accept(%d, %p, {"F_Zu"}) -> %d", xfd->fd, &sa, salen, ps);*/ + /*0 Info4("accept(%d, %p, {"F_Zu"}) -> %d", sfd->fd, &sa, salen, ps);*/ break; /* success, break out of loop */ } if (errno == EINTR) { @@ -314,12 +314,12 @@ int _xioopen_accept_fd( } if (errno == ECONNABORTED) { Notice4("accept(%d, %p, {"F_socklen"}): %s", - xfd->fd, &sa, salen, strerror(errno)); + sfd->fd, &sa, salen, strerror(errno)); continue; } Msg4(level, "accept(%d, %p, {"F_socklen"}): %s", - xfd->fd, &sa, salen, strerror(errno)); - Close(xfd->fd); + sfd->fd, &sa, salen, strerror(errno)); + Close(sfd->fd); return STAT_RETRYLATER; } while (true); applyopts_cloexec(ps, opts); @@ -339,7 +339,7 @@ int _xioopen_accept_fd( la? sockaddr_info(&la->soa, las, sockname, sizeof(sockname)):"NULL"); - if (pa != NULL && la != NULL && xiocheckpeer(xfd, pa, la) < 0) { + if (pa != NULL && la != NULL && xiocheckpeer(sfd, pa, la) < 0) { if (Shutdown(ps, 2) < 0) { Info2("shutdown(%d, 2): %s", ps, strerror(errno)); } @@ -363,9 +363,9 @@ int _xioopen_accept_fd( if ((pid = xio_fork(false, level==E_ERROR?level:E_WARN, - xfd->shutup)) + sfd->shutup)) < 0) { - Close(xfd->fd); + Close(sfd->fd); Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL); return STAT_RETRYLATER; } @@ -376,14 +376,14 @@ int _xioopen_accept_fd( Info1("just born: child process "F_pid, cpid); xiosetenvulong("PID", cpid, 1); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } - xfd->fd = ps; + sfd->fd = ps; #if WITH_RETRY /* !? */ - xfd->forever = false; xfd->retry = 0; + sfd->forever = false; sfd->retry = 0; level = E_ERROR; #endif /* WITH_RETRY */ @@ -410,18 +410,18 @@ int _xioopen_accept_fd( } Info("still listening"); } else { - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } - xfd->fd = ps; + sfd->fd = ps; break; } } - applyopts(xfd, -1, opts, PH_FD); - applyopts(xfd, -1, opts, PH_PASTSOCKET); - applyopts(xfd, -1, opts, PH_CONNECTED); - if ((result = _xio_openlate(xfd, opts)) < 0) + applyopts(sfd, -1, opts, PH_FD); + applyopts(sfd, -1, opts, PH_PASTSOCKET); + applyopts(sfd, -1, opts, PH_CONNECTED); + if ((result = _xio_openlate(sfd, opts)) < 0) return result; /* set the env vars describing the local and remote sockets */ diff --git a/xio-named.c b/xio-named.c index 0d07356..abb9f51 100644 --- a/xio-named.c +++ b/xio-named.c @@ -95,8 +95,14 @@ int applyopts_named(const char *filename, struct opt *opts, unsigned int phase) If the path exists, its st_mode field is returned. After this sub you may proceed with open() or whatever... */ -int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd, - groups_t groups, bool *exists, struct opt *opts) +int _xioopen_named_early( + int argc, + const char *argv[], + xiofile_t *xfd, + groups_t groups, + bool *exists, + struct opt *opts, + const char *syntax) { const char *path = argv[1]; struct single *sfd = &xfd->stream; @@ -108,7 +114,8 @@ int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd, bool opt_unlink_early = false; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", argv[0]?argv[0]:"", argc); + xio_syntax(argv[0], 1, argc-1, syntax); + return STAT_NORETRY; } statbuf.st_mode = 0; /* find the appropriate groupbits */ diff --git a/xio-named.h b/xio-named.h index e727a9b..ac83dc3 100644 --- a/xio-named.h +++ b/xio-named.h @@ -18,9 +18,7 @@ extern const struct optdesc opt_umask; extern int applyopts_named(const char *filename, struct opt *opts, unsigned int phase); -extern int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd, - groups_t groups, - bool *exists, struct opt *opts); +extern int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd, groups_t groups, bool *exists, struct opt *opts, const char *syntax); extern int _xioopen_open(const char *path, int rw, struct opt *opts); extern int xio_unlink(const char *pathname, int level); diff --git a/xio-openssl.c b/xio-openssl.c index dfcead4..3ade1c3 100644 --- a/xio-openssl.c +++ b/xio-openssl.c @@ -43,21 +43,18 @@ */ /* static declaration of ssl's open function */ -static int xioopen_openssl_connect(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *fd, groups_t groups, - int dummy1, int dummy2, int dummy3); +static int xioopen_openssl_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); /* static declaration of ssl's open function */ -static int xioopen_openssl_listen(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *fd, groups_t groups, - int dummy1, int dummy2, int dummy3); +static int xioopen_openssl_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); + static int openssl_SSL_ERROR_SSL(int level, const char *funcname); -static int openssl_handle_peer_certificate(struct single *xfd, +static int openssl_handle_peer_certificate(struct single *sfd, const char *peername, bool opt_ver, int level); -static int xioSSL_set_fd(struct single *xfd, int level); -static int xioSSL_connect(struct single *xfd, const char *opt_commonname, bool opt_ver, int level); +static int xioSSL_set_fd(struct single *sfd, int level); +static int xioSSL_connect(struct single *sfd, const char *opt_commonname, bool opt_ver, int level); static int openssl_delete_cert_info(void); @@ -223,26 +220,20 @@ static void openssl_conn_loginfo(SSL *ssl) { } /* the open function for OpenSSL client */ -static int - xioopen_openssl_connect(int argc, - const char *argv[], /* the arguments in the address string */ - struct opt *opts, - int xioflags, /* is the open meant for reading (0), +static int xioopen_openssl_connect( + int argc, + const char *argv[], /* the arguments in the address string */ + struct opt *opts, + int xioflags, /* is the open meant for reading (0), writing (1), or both (2) ? */ - xiofile_t *xxfd, /* a xio file descriptor structure, + xiofile_t *xxfd, /* a xio file descriptor structure, already allocated */ - groups_t groups, /* the matching address groups... */ - int protogrp, /* first transparent integer value from - addr_openssl */ - int dummy2, /* second transparent integer value from - addr_openssl */ - int dummy3) /* transparent pointer value from - addr_openssl */ + const struct addrdesc *addrdesc) /* the above descriptor */ { - struct single *xfd = &xxfd->stream; - struct single *sfd = xfd; + struct single *sfd = &xxfd->stream; struct opt *opts0 = NULL; const char *hostname, *portname; + int protogrp = addrdesc->arg1; int pf = PF_UNSPEC; bool use_dtls = (protogrp != 0); int socktype = SOCK_STREAM; @@ -268,10 +259,10 @@ static int Error("address with data processing not allowed here"); return STAT_NORETRY; } - xfd->flags |= XIO_DOESCONVERT; + sfd->flags |= XIO_DOESCONVERT; if (argc != 3) { - Error1("%s: 2 parameters required", argv[0]); + xio_syntax(argv[0], 2, argc-1, addrdesc->syntax); return STAT_NORETRY; } hostname = argv[1]; @@ -283,8 +274,10 @@ static int return STAT_NORETRY; } - xfd->howtoend = END_SHUTDOWN; - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; + xioinit_ip(&pf, xioparms.default_ip); + sfd->howtoend = END_SHUTDOWN; + if (applyopts_single(sfd, opts, PH_INIT) < 0) + return -1; applyopts(sfd, -1, opts, PH_INIT); retropt_bool(opts, OPT_FORK, &dofork); @@ -317,7 +310,7 @@ static int #endif result = - _xioopen_openssl_prepare(opts, xfd, false, &opt_ver, opt_cert, &ctx, (bool *)&use_dtls); + _xioopen_openssl_prepare(opts, sfd, false, &opt_ver, opt_cert, &ctx, (bool *)&use_dtls); if (result != STAT_OK) return STAT_NORETRY; if (use_dtls) { @@ -329,7 +322,7 @@ static int result = _xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto, - xfd->para.socket.ip.ai_flags, + sfd->para.socket.ip.ai_flags, &themlist, us, &uslen, &needbind, &lowport, socktype); if (result != STAT_OK) return STAT_NORETRY; @@ -362,7 +355,7 @@ static int while (themp != NULL) { #if WITH_RETRY - if (xfd->forever || xfd->retry || ai_sorted[i] != NULL) { + if (sfd->forever || sfd->retry || ai_sorted[i] != NULL) { level = E_INFO; } else #endif /* WITH_RETRY */ @@ -370,7 +363,7 @@ static int /* This cannot fork because we retrieved fork option above */ result = - _xioopen_connect(xfd, + _xioopen_connect(sfd, needbind?us:NULL, uslen, themp->ai_addr, themp->ai_addrlen, opts, pf?pf:themp->ai_addr->sa_family, socktype, ipproto, lowport, level); @@ -386,12 +379,12 @@ static int #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); if (result == STAT_RETRYLATER) { - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); } - --xfd->retry; + --sfd->retry; continue; } free(ai_sorted); @@ -402,25 +395,25 @@ static int return result; } /*! isn't this too early? */ - if ((result = _xio_openlate(xfd, opts)) < 0) { + if ((result = _xio_openlate(sfd, opts)) < 0) { free(ai_sorted); return result; } - result = _xioopen_openssl_connect(xfd, opt_ver, opt_commonname, + result = _xioopen_openssl_connect(sfd, opt_ver, opt_commonname, opt_no_sni, opt_snihost, ctx, level); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (xfd->forever || xfd->retry) { - Close(xfd->fd); + if (sfd->forever || sfd->retry) { + Close(sfd->fd); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); if (result == STAT_RETRYLATER) { - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); } - --xfd->retry; + --sfd->retry; continue; } #endif /* WITH_RETRY */ @@ -437,28 +430,28 @@ static int if (dofork) { pid_t pid; int level = E_ERROR; - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { level = E_WARN; } - while ((pid = xio_fork(false, level, xfd->shutup)) < 0) { - if (xfd->forever || --xfd->retry) { - Nanosleep(&xfd->intervall, NULL); continue; + while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { + if (sfd->forever || --sfd->retry) { + Nanosleep(&sfd->intervall, NULL); continue; } xiofreeaddrinfo(themlist); return STAT_RETRYLATER; } if (pid == 0) { /* child process */ - xfd->forever = false; xfd->retry = 0; + sfd->forever = false; sfd->retry = 0; break; } /* parent process */ - Close(xfd->fd); - sycSSL_free(xfd->para.openssl.ssl); - xfd->para.openssl.ssl = NULL; + Close(sfd->fd); + sycSSL_free(sfd->para.openssl.ssl); + sfd->para.openssl.ssl = NULL; /* with and without retry */ - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); continue; /* with next socket() bind() connect() */ } @@ -468,7 +461,7 @@ static int free(ai_sorted); xiofreeaddrinfo(themlist); - openssl_conn_loginfo(xfd->para.openssl.ssl); + openssl_conn_loginfo(sfd->para.openssl.ssl); free((void *)opt_commonname); free((void *)opt_snihost); @@ -479,10 +472,10 @@ static int /* this function is typically called within the OpenSSL client fork/retry loop. - xfd must be of type DATA_OPENSSL, and its fd must be set with a valid file + sfd must be of type DATA_OPENSSL, and its fd must be set with a valid file descriptor. this function then performs all SSL related step to make a valid SSL connection from an FD and a CTX. */ -int _xioopen_openssl_connect(struct single *xfd, +int _xioopen_openssl_connect(struct single *sfd, bool opt_ver, const char *opt_commonname, bool no_sni, @@ -502,12 +495,12 @@ int _xioopen_openssl_connect(struct single *xfd, /*Error("SSL_new()");*/ return STAT_RETRYLATER; } - xfd->para.openssl.ssl = ssl; + sfd->para.openssl.ssl = ssl; - result = xioSSL_set_fd(xfd, level); + result = xioSSL_set_fd(sfd, level); if (result != STAT_OK) { - sycSSL_free(xfd->para.openssl.ssl); - xfd->para.openssl.ssl = NULL; + sycSSL_free(sfd->para.openssl.ssl); + sfd->para.openssl.ssl = NULL; return result; } @@ -517,25 +510,25 @@ int _xioopen_openssl_connect(struct single *xfd, Warn("refusing to set empty SNI host name"); } else if (!SSL_set_tlsext_host_name(ssl, snihost)) { Error1("Failed to set SNI host \"%s\"", snihost); - sycSSL_free(xfd->para.openssl.ssl); - xfd->para.openssl.ssl = NULL; + sycSSL_free(sfd->para.openssl.ssl); + sfd->para.openssl.ssl = NULL; return STAT_NORETRY; } } #endif - result = xioSSL_connect(xfd, opt_commonname, opt_ver, level); + result = xioSSL_connect(sfd, opt_commonname, opt_ver, level); if (result != STAT_OK) { - sycSSL_free(xfd->para.openssl.ssl); - xfd->para.openssl.ssl = NULL; + sycSSL_free(sfd->para.openssl.ssl); + sfd->para.openssl.ssl = NULL; return result; } - result = openssl_handle_peer_certificate(xfd, opt_commonname, + result = openssl_handle_peer_certificate(sfd, opt_commonname, opt_ver, level); if (result != STAT_OK) { - sycSSL_free(xfd->para.openssl.ssl); - xfd->para.openssl.ssl = NULL; + sycSSL_free(sfd->para.openssl.ssl); + sfd->para.openssl.ssl = NULL; return result; } @@ -545,25 +538,19 @@ int _xioopen_openssl_connect(struct single *xfd, #if WITH_LISTEN -static int - xioopen_openssl_listen(int argc, - const char *argv[], /* the arguments in the address string */ - struct opt *opts, - int xioflags, /* is the open meant for reading (0), +static int xioopen_openssl_listen( + int argc, + const char *argv[], /* the arguments in the address string */ + struct opt *opts, + int xioflags, /* is the open meant for reading (0), writing (1), or both (2) ? */ - xiofile_t *xxfd, /* a xio file descriptor structure, + xiofile_t *xxfd, /* a xio file descriptor structure, already allocated */ - groups_t groups, /* the matching address groups... */ - int protogrp, /* first transparent integer value from - addr_openssl */ - int dummy2, /* second transparent integer value from - addr_openssl */ - int dummy3) /* transparent pointer value from - addr_openssl */ + const struct addrdesc *addrdesc) /* the above descriptor */ { - struct single *xfd = &xxfd->stream; - struct single *sfd = xfd; + struct single *sfd = &xxfd->stream; const char *portname; + int protogrp = addrdesc->arg1; struct opt *opts0 = NULL; union sockaddr_union us_sa, *us = &us_sa; socklen_t uslen = sizeof(us_sa); @@ -583,13 +570,14 @@ static int Error("address with data processing not allowed here"); return STAT_NORETRY; } - xfd->flags |= XIO_DOESCONVERT; + sfd->flags |= XIO_DOESCONVERT; if (argc != 2) { - Error1("%s: 1 parameter required", argv[0]); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } + xioinit_ip(&pf, xioparms.default_ip); #if WITH_IP4 && WITH_IP6 switch (xioparms.default_ip) { case '4': pf = PF_INET; break; @@ -604,8 +592,8 @@ static int portname = argv[1]; - xfd->howtoend = END_SHUTDOWN; - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; + sfd->howtoend = END_SHUTDOWN; + if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; applyopts(sfd, -1, opts, PH_INIT); retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert); @@ -618,7 +606,7 @@ static int applyopts(sfd, -1, opts, PH_EARLY); result = - _xioopen_openssl_prepare(opts, xfd, true, &opt_ver, opt_cert, &ctx, &use_dtls); + _xioopen_openssl_prepare(opts, sfd, true, &opt_ver, opt_cert, &ctx, &use_dtls); if (result != STAT_OK) return STAT_NORETRY; if (use_dtls) { @@ -629,7 +617,7 @@ static int retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto); if (_xioopen_ipapp_listen_prepare(opts, &opts0, portname, &pf, ipproto, - xfd->para.socket.ip.ai_flags, + sfd->para.socket.ip.ai_flags, us, &uslen, socktype) != STAT_OK) { return STAT_NORETRY; @@ -637,12 +625,12 @@ static int if (pf == 0) pf = us->soa.sa_family; - xfd->dtype = XIODATA_OPENSSL; + sfd->dtype = XIODATA_OPENSSL; while (true) { /* loop over failed attempts */ #if WITH_RETRY - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { level = E_INFO; } else #endif /* WITH_RETRY */ @@ -651,18 +639,18 @@ static int /* this can fork() for us; it only returns on error or on successful establishment of connection */ if (ipproto == IPPROTO_TCP) { - result = _xioopen_listen(xfd, xioflags, + result = _xioopen_listen(sfd, xioflags, (struct sockaddr *)us, uslen, opts, pf, socktype, ipproto, #if WITH_RETRY - (xfd->retry||xfd->forever)?E_INFO:E_ERROR + (sfd->retry||sfd->forever)?E_INFO:E_ERROR #else E_ERROR #endif /* WITH_RETRY */ ); #if WITH_UDP } else { - result = _xioopen_ipdgram_listen(xfd, xioflags, + result = _xioopen_ipdgram_listen(sfd, xioflags, us, uslen, opts, pf, socktype, ipproto); #endif /* WITH_UDP */ } @@ -672,13 +660,13 @@ static int #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); if (result == STAT_RETRYLATER) { - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); } dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); - --xfd->retry; + --sfd->retry; continue; } return STAT_NORETRY; @@ -687,19 +675,19 @@ static int return result; } - result = _xioopen_openssl_listen(xfd, opt_ver, opt_commonname, ctx, level); + result = _xioopen_openssl_listen(sfd, opt_ver, opt_commonname, ctx, level); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); if (result == STAT_RETRYLATER) { - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); } dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); - --xfd->retry; + --sfd->retry; continue; } return STAT_NORETRY; @@ -708,7 +696,7 @@ static int return result; } - openssl_conn_loginfo(xfd->para.openssl.ssl); + openssl_conn_loginfo(sfd->para.openssl.ssl); break; } /* drop out on success */ @@ -719,7 +707,7 @@ static int } -int _xioopen_openssl_listen(struct single *xfd, +int _xioopen_openssl_listen(struct single *sfd, bool opt_ver, const char *opt_commonname, SSL_CTX *ctx, @@ -729,7 +717,7 @@ int _xioopen_openssl_listen(struct single *xfd, int errint, ret; /* create an SSL object */ - if ((xfd->para.openssl.ssl = sycSSL_new(ctx)) == NULL) { + if ((sfd->para.openssl.ssl = sycSSL_new(ctx)) == NULL) { if (ERR_peek_error() == 0) Msg(level, "SSL_new() failed"); while (err = ERR_get_error()) { Msg1(level, "SSL_new(): %s", ERR_error_string(err, NULL)); @@ -739,11 +727,11 @@ int _xioopen_openssl_listen(struct single *xfd, } /* assign the network connection to the SSL object */ - if (sycSSL_set_fd(xfd->para.openssl.ssl, xfd->fd) <= 0) { + if (sycSSL_set_fd(sfd->para.openssl.ssl, sfd->fd) <= 0) { if (ERR_peek_error() == 0) Msg(level, "SSL_set_fd() failed"); while (err = ERR_get_error()) { Msg2(level, "SSL_set_fd(, %d): %s", - xfd->fd, ERR_error_string(err, NULL)); + sfd->fd, ERR_error_string(err, NULL)); } } @@ -753,7 +741,7 @@ int _xioopen_openssl_listen(struct single *xfd, const char *ciphers = NULL; Debug("available ciphers:"); do { - ciphers = SSL_get_cipher_list(xfd->para.openssl.ssl, i); + ciphers = SSL_get_cipher_list(sfd->para.openssl.ssl, i); if (ciphers == NULL) break; Debug2("CIPHERS pri=%d: %s", i, ciphers); ++i; @@ -762,9 +750,9 @@ int _xioopen_openssl_listen(struct single *xfd, #endif /* WITH_DEBUG */ /* connect via SSL by performing handshake */ - if ((ret = sycSSL_accept(xfd->para.openssl.ssl)) <= 0) { + if ((ret = sycSSL_accept(sfd->para.openssl.ssl)) <= 0) { /*if (ERR_peek_error() == 0) Msg(level, "SSL_accept() failed");*/ - errint = SSL_get_error(xfd->para.openssl.ssl, ret); + errint = SSL_get_error(sfd->para.openssl.ssl, ret); switch (errint) { case SSL_ERROR_NONE: Msg(level, "ok"); break; @@ -803,7 +791,7 @@ int _xioopen_openssl_listen(struct single *xfd, return STAT_RETRYLATER; } - if (openssl_handle_peer_certificate(xfd, opt_commonname, opt_ver, E_ERROR/*!*/) < 0) { + if (openssl_handle_peer_certificate(sfd, opt_commonname, opt_ver, E_ERROR/*!*/) < 0) { return STAT_NORETRY; } @@ -978,7 +966,7 @@ static int _xio_openssl_parse_version(const char *verstring, int vergroups) { int _xioopen_openssl_prepare(struct opt *opts, - struct single *xfd,/* a xio file descriptor + struct single *sfd,/* a xio file descriptor structure, already allocated */ bool server, /* SSL client: false */ @@ -1004,7 +992,7 @@ int unsigned long err; int result; - xfd->dtype = XIODATA_OPENSSL; + sfd->dtype = XIODATA_OPENSSL; retropt_bool(opts, OPT_OPENSSL_FIPS, &opt_fips); retropt_string(opts, OPT_OPENSSL_METHOD, &me_str); @@ -1237,35 +1225,35 @@ int /*ERR_clear_error;*/ return STAT_RETRYLATER; } - xfd->para.openssl.ctx = ctx; + sfd->para.openssl.ctx = ctx; *ctxp = ctx; #if HAVE_SSL_CTX_set_min_proto_version || defined(SSL_CTX_set_min_proto_version) - if (xfd->para.openssl.min_proto_version != NULL) { + if (sfd->para.openssl.min_proto_version != NULL) { int sslver, rc; - sslver = _xio_openssl_parse_version(xfd->para.openssl.min_proto_version, + sslver = _xio_openssl_parse_version(sfd->para.openssl.min_proto_version, XIO_OPENSSL_VERSIONGROUP_TLS|XIO_OPENSSL_VERSIONGROUP_DTLS); if (sslver < 0) return STAT_NORETRY; if ((rc = SSL_CTX_set_min_proto_version(ctx, sslver)) <= 0) { Debug1("version: %ld", SSL_CTX_get_min_proto_version(ctx)); Error3("_xioopen_openssl_prepare(): SSL_CTX_set_min_proto_version(\"%s\"->%d): failed (%d)", - xfd->para.openssl.min_proto_version, sslver, rc); + sfd->para.openssl.min_proto_version, sslver, rc); return STAT_NORETRY; } Debug1("version: %ld", SSL_CTX_get_min_proto_version(ctx)); } #endif /* HAVE_SSL_set_min_proto_version || defined(SSL_set_min_proto_version) */ #if HAVE_SSL_CTX_set_max_proto_version || defined(SSL_CTX_set_max_proto_version) - if (xfd->para.openssl.max_proto_version != NULL) { + if (sfd->para.openssl.max_proto_version != NULL) { int sslver; - sslver = _xio_openssl_parse_version(xfd->para.openssl.max_proto_version, + sslver = _xio_openssl_parse_version(sfd->para.openssl.max_proto_version, XIO_OPENSSL_VERSIONGROUP_TLS|XIO_OPENSSL_VERSIONGROUP_DTLS); if (sslver < 0) return STAT_NORETRY; if (SSL_CTX_set_max_proto_version(ctx, sslver) <= 0) { Error2("_xioopen_openssl_prepare(): SSL_CTX_set_max_proto_version(\"%s\"->%d): failed", - xfd->para.openssl.max_proto_version, sslver); + sfd->para.openssl.max_proto_version, sslver); return STAT_NORETRY; } } @@ -1793,7 +1781,7 @@ static bool openssl_check_peername(X509_NAME *name, const char *peername) { /* peername is, with OpenSSL client, the server name, or the value of option commonname if provided; With OpenSSL server, it is the value of option commonname */ -static int openssl_handle_peer_certificate(struct single *xfd, +static int openssl_handle_peer_certificate(struct single *sfd, const char *peername, bool opt_ver, int level) { X509 *peer_cert; @@ -1802,7 +1790,7 @@ static int openssl_handle_peer_certificate(struct single *xfd, int extcount, i, ok = 0; int status; - if ((peer_cert = SSL_get_peer_certificate(xfd->para.openssl.ssl)) == NULL) { + if ((peer_cert = SSL_get_peer_certificate(sfd->para.openssl.ssl)) == NULL) { if (opt_ver) { Msg(level, "no peer certificate"); status = STAT_RETRYLATER; @@ -1816,7 +1804,7 @@ static int openssl_handle_peer_certificate(struct single *xfd, /* verify peer certificate (trust, signature, validity dates) */ if (opt_ver) { long verify_result; - if ((verify_result = sycSSL_get_verify_result(xfd->para.openssl.ssl)) != X509_V_OK) { + if ((verify_result = sycSSL_get_verify_result(sfd->para.openssl.ssl)) != X509_V_OK) { const char *message = NULL; if (verify_result >= 0 && (size_t)verify_result < @@ -1912,7 +1900,7 @@ static int openssl_handle_peer_certificate(struct single *xfd, case 16: /* IPv6 */ inet_ntop(AF_INET6, data, aBuffer, sizeof(aBuffer)); if (peername != NULL) { - xioip6_pton(peername, &ip6bin, xfd->para.socket.ip.ai_flags); + xioip6_pton(peername, &ip6bin, sfd->para.socket.ip.ai_flags); if (memcmp(data, &ip6bin, sizeof(ip6bin)) == 0) { Debug2("subjectAltName \"%s\" matches peername \"%s\"", aBuffer, peername); @@ -1964,15 +1952,15 @@ static int openssl_handle_peer_certificate(struct single *xfd, return status; } -static int xioSSL_set_fd(struct single *xfd, int level) { +static int xioSSL_set_fd(struct single *sfd, int level) { unsigned long err; /* assign a network connection to the SSL object */ - if (sycSSL_set_fd(xfd->para.openssl.ssl, xfd->fd) <= 0) { + if (sycSSL_set_fd(sfd->para.openssl.ssl, sfd->fd) <= 0) { Msg(level, "SSL_set_fd() failed"); while (err = ERR_get_error()) { Msg2(level, "SSL_set_fd(, %d): %s", - xfd->fd, ERR_error_string(err, NULL)); + sfd->fd, ERR_error_string(err, NULL)); } return STAT_RETRYLATER; } @@ -1984,16 +1972,16 @@ static int xioSSL_set_fd(struct single *xfd, int level) { in case of an error condition, this function check forever and retry options and ev. sleeps an interval. It returns NORETRY when the caller should not retry for any reason. */ -static int xioSSL_connect(struct single *xfd, const char *opt_commonname, +static int xioSSL_connect(struct single *sfd, const char *opt_commonname, bool opt_ver, int level) { char error_string[120]; int errint, status, ret; unsigned long err; /* connect via SSL by performing handshake */ - if ((ret = sycSSL_connect(xfd->para.openssl.ssl)) <= 0) { + if ((ret = sycSSL_connect(sfd->para.openssl.ssl)) <= 0) { /*if (ERR_peek_error() == 0) Msg(level, "SSL_connect() failed");*/ - errint = SSL_get_error(xfd->para.openssl.ssl, ret); + errint = SSL_get_error(sfd->para.openssl.ssl, ret); switch (errint) { case SSL_ERROR_NONE: /* this is not an error, but I dare not continue for security reasons*/ @@ -2030,7 +2018,7 @@ static int xioSSL_connect(struct single *xfd, const char *opt_commonname, break; case SSL_ERROR_SSL: status = openssl_SSL_ERROR_SSL(level, "SSL_connect"); - if (openssl_handle_peer_certificate(xfd, opt_commonname, opt_ver, level/*!*/) < 0) { + if (openssl_handle_peer_certificate(sfd, opt_commonname, opt_ver, level/*!*/) < 0) { return STAT_RETRYLATER; } break; diff --git a/xio-pipe.c b/xio-pipe.c index 782e0d1..7d260c1 100644 --- a/xio-pipe.c +++ b/xio-pipe.c @@ -14,7 +14,7 @@ #if WITH_PIPE -static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3); +static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); static int xioopen_fifo_unnamed(xiofile_t *sock, struct opt *opts); @@ -77,7 +77,14 @@ static int xioopen_fifo_unnamed(xiofile_t *sock, struct opt *opts) { /* open a named or unnamed pipe/fifo */ -static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) { +static int xioopen_fifo( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ struct single *sfd = &xfd->stream; const char *pipename = argv[1]; int rw = (xioflags & XIO_ACCMODE); @@ -96,7 +103,8 @@ static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xiof } if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1,addrdesc->syntax); + return STAT_NORETRY; } if (applyopts_single(sfd, opts, PH_INIT) < 0) diff --git a/xio-posixmq.c b/xio-posixmq.c index 4a4b504..7c40ebb 100644 --- a/xio-posixmq.c +++ b/xio-posixmq.c @@ -19,7 +19,7 @@ static int _posixmq_unlink( const char *name, int level); /* message level on error */ -static int xioopen_posixmq(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dirs, int dummy, int dummy3); +static int xioopen_posixmq(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); const struct addrdesc xioaddr_posixmq_bidir = { "POSIXMQ-BIDIRECTIONAL", 1+XIO_RDWR, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY, XIO_RDWR, 0, 0 HELP(":") }; const struct addrdesc xioaddr_posixmq_read = { "POSIXMQ-READ", 1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY, XIO_RDONLY, 0, 0 HELP(":") }; @@ -37,14 +37,13 @@ static int xioopen_posixmq( struct opt *opts, int xioflags, xiofile_t *xfd, - groups_t groups, - int dirs, - int oneshot, - int dummy3) + const struct addrdesc *addrdesc) { /* We expect the form: /mqname */ xiosingle_t *sfd = &xfd->stream; const char *name; + int dirs = addrdesc->arg1; + int oneshot = addrdesc->arg2; bool opt_unlink_early = false; int oflag; bool opt_o_excl = false; @@ -61,8 +60,7 @@ static int xioopen_posixmq( return STAT_NORETRY; } if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } diff --git a/xio-progcall.c b/xio-progcall.c index e5ec2e5..5cbd505 100644 --- a/xio-progcall.c +++ b/xio-progcall.c @@ -312,8 +312,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ if (rw != XIO_WRONLY) { applyopts_cloexec(rdpip[0], popts); - applyopts(NULL, rdpip[0], popts, PH_FD); - applyopts(NULL, rdpip[1], copts, PH_FD); + applyopts(sfd, rdpip[0], popts, PH_FD); + applyopts(sfd, rdpip[1], copts, PH_FD); } if (rw != XIO_RDONLY) { @@ -326,8 +326,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ /* wrpip[1]: write by socat; wrpip[0]: read by child */ if (rw != XIO_RDONLY) { applyopts_cloexec(wrpip[1], popts); - applyopts(NULL, wrpip[1], popts, PH_FD); - applyopts(NULL, wrpip[0], copts, PH_FD); + applyopts(sfd, wrpip[1], popts, PH_FD); + applyopts(sfd, wrpip[0], copts, PH_FD); } if (sfd->howtoend == END_UNSPEC) { sfd->howtoend = END_CLOSE_KILL; @@ -362,19 +362,19 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ return -1; } popts = opts; - applyopts(NULL, sv[0], copts, PH_PASTSOCKET); - applyopts(NULL, sv[1], popts, PH_PASTSOCKET); + applyopts(sfd, sv[0], copts, PH_PASTSOCKET); + applyopts(sfd, sv[1], popts, PH_PASTSOCKET); applyopts_cloexec(sv[0], copts); - applyopts(NULL, sv[0], copts, PH_FD); - applyopts(NULL, sv[1], popts, PH_FD); + applyopts(sfd, sv[0], copts, PH_FD); + applyopts(sfd, sv[1], popts, PH_FD); - applyopts(NULL, sv[0], copts, PH_PREBIND); - applyopts(NULL, sv[0], copts, PH_BIND); - applyopts(NULL, sv[0], copts, PH_PASTBIND); - applyopts(NULL, sv[1], popts, PH_PREBIND); - applyopts(NULL, sv[1], popts, PH_BIND); - applyopts(NULL, sv[1], popts, PH_PASTBIND); + applyopts(sfd, sv[0], copts, PH_PREBIND); + applyopts(sfd, sv[0], copts, PH_BIND); + applyopts(sfd, sv[0], copts, PH_PASTBIND); + applyopts(sfd, sv[1], popts, PH_PREBIND); + applyopts(sfd, sv[1], popts, PH_BIND); + applyopts(sfd, sv[1], popts, PH_PASTBIND); if (sfd->howtoend == END_UNSPEC) { sfd->howtoend = END_SHUTDOWN_KILL; @@ -437,7 +437,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ #endif /* this for child, was after fork */ - applyopts(NULL, ttyfd, copts, PH_FD); + applyopts(sfd, ttyfd, copts, PH_FD); Info1("opened pseudo terminal %s", tn); Close(ptyfd); @@ -464,8 +464,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ applyopts_cloexec(ttyfd, copts); } - applyopts(NULL, ttyfd, copts, PH_LATE); - applyopts(NULL, ttyfd, copts, PH_LATE2); + applyopts(sfd, ttyfd, copts, PH_LATE); + applyopts(sfd, ttyfd, copts, PH_LATE2); } else #endif /* HAVE_PTY */ if (usepipes) { @@ -515,10 +515,10 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ /* applyopts_cloexec(fdi, *copts);*/ /* option is already consumed! */ } - applyopts(NULL, fdi, copts, PH_LATE); - applyopts(NULL, fdo, copts, PH_LATE); - applyopts(NULL, fdi, copts, PH_LATE2); - applyopts(NULL, fdo, copts, PH_LATE2); + applyopts(sfd, fdi, copts, PH_LATE); + applyopts(sfd, fdo, copts, PH_LATE); + applyopts(sfd, fdi, copts, PH_LATE2); + applyopts(sfd, fdo, copts, PH_LATE2); } else { /* socketpair */ Close(sv[0]); @@ -545,8 +545,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ Close(sv[1]); } - applyopts(NULL, fdi, copts, PH_LATE); - applyopts(NULL, fdi, copts, PH_LATE2); + applyopts(sfd, fdi, copts, PH_LATE); + applyopts(sfd, fdi, copts, PH_LATE2); } if (withfork) { Info("notifying parent that child process is ready"); @@ -554,8 +554,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ } } /* withfork */ else { - applyopts(NULL, -1, copts, PH_LATE); - applyopts(NULL, -1, copts, PH_LATE2); + applyopts(sfd, -1, copts, PH_LATE); + applyopts(sfd, -1, copts, PH_LATE2); } _xioopen_setdelayeduser(); if (withstderr) { diff --git a/xio-proxy.c b/xio-proxy.c index 80fe29a..29730a1 100644 --- a/xio-proxy.c +++ b/xio-proxy.c @@ -20,10 +20,7 @@ #define PROXYPORT "8080" -static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *fd, - groups_t groups, int dummy1, int dummy2, - int dummy3); +static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); const struct optdesc opt_proxyport = { "proxyport", NULL, OPT_PROXYPORT, GROUP_HTTP, PH_LATE, TYPE_STRING, OFUNC_SPEC }; const struct optdesc opt_ignorecr = { "ignorecr", NULL, OPT_IGNORECR, GROUP_HTTP, PH_LATE, TYPE_BOOL, OFUNC_SPEC }; @@ -57,15 +54,15 @@ enum { returns <0 when error occurs */ static ssize_t - xioproxy_recvbytes(struct single *xfd, char *buff, size_t buflen, int level) { + xioproxy_recvbytes(struct single *sfd, char *buff, size_t buflen, int level) { ssize_t result; do { /* we need at least buflen bytes... */ - result = Read(xfd->fd, buff, buflen); + result = Read(sfd->fd, buff, buflen); } while (result < 0 && errno == EINTR); /*! EAGAIN? */ if (result < 0) { Msg4(level, "read(%d, %p, "F_Zu"): %s", - xfd->fd, buff, buflen, strerror(errno)); + sfd->fd, buff, buflen, strerror(errno)); return result; } if (result == 0) { @@ -78,12 +75,16 @@ static ssize_t #define BUFLEN 2048 -static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, - groups_t groups, int dummy1, int dummy2, - int dummy3) { +static int xioopen_proxy_connect( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ /* we expect the form: host:host:port */ - struct single *xfd = &xxfd->stream; + struct single *sfd = &xxfd->stream; struct opt *opts0 = NULL; struct proxyvars struct_proxyvars = { 0 }, *proxyvars = &struct_proxyvars; /* variables to be filled with address option values */ @@ -105,16 +106,17 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, int result; if (argc != 4) { - Error1("%s: 3 parameters required", argv[0]); + xio_syntax(argv[0], 3, argc-1, addrdesc->syntax); return STAT_NORETRY; } proxyname = argv[1]; targetname = argv[2]; targetport = argv[3]; - xfd->howtoend = END_SHUTDOWN; - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; - applyopts(xfd, 1, opts, PH_INIT); + sfd->howtoend = END_SHUTDOWN; + if (applyopts_single(sfd, opts, PH_INIT) < 0) + return -1; + applyopts(sfd, 1, opts, PH_INIT); retropt_int(opts, OPT_SO_TYPE, &socktype); @@ -127,7 +129,7 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, } result = _xioopen_proxy_prepare(proxyvars, opts, targetname, targetport, - xfd->para.socket.ip.ai_flags); + sfd->para.socket.ip.ai_flags); if (result != STAT_OK) return result; @@ -142,7 +144,7 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, result = _xioopen_ipapp_prepare(opts, &opts0, proxyname, proxyport, &pf, ipproto, - xfd->para.socket.ip.ai_flags, + sfd->para.socket.ip.ai_flags, &themlist, us, &uslen, &needbind, &lowport, socktype); if (result != STAT_OK) @@ -168,14 +170,14 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, Notice4("opening connection to %s:%u via proxy %s:%s", proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport); #if WITH_RETRY - if (xfd->forever || xfd->retry || ai_sorted[i] != NULL) { + if (sfd->forever || sfd->retry || ai_sorted[i] != NULL) { level = E_INFO; } else #endif /* WITH_RETRY */ level = E_ERROR; result = - _xioopen_connect(xfd, + _xioopen_connect(sfd, needbind?us:NULL, sizeof(*us), themp->ai_addr, themp->ai_addrlen, opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, lowport, level); @@ -190,10 +192,10 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (xfd->forever || xfd->retry) { - --xfd->retry; + if (sfd->forever || sfd->retry) { + --sfd->retry; if (result == STAT_RETRYLATER) - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); continue; } #endif /* WITH_RETRY */ @@ -204,19 +206,19 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, } } xiofreeaddrinfo(themlist); - applyopts(xfd, -1, opts, PH_ALL); + applyopts(sfd, -1, opts, PH_ALL); - if ((result = _xio_openlate(xfd, opts)) < 0) + if ((result = _xio_openlate(sfd, opts)) < 0) return result; - result = _xioopen_proxy_connect(xfd, proxyvars, level); + result = _xioopen_proxy_connect(sfd, proxyvars, level); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (xfd->forever || xfd->retry--) { - if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL); + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); continue; } #endif /* WITH_RETRY */ @@ -232,24 +234,24 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, if (dofork) { pid_t pid; int level = E_ERROR; - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { level = E_WARN; } - while ((pid = xio_fork(false, level, xfd->shutup)) < 0) { - if (xfd->forever || --xfd->retry) { - Nanosleep(&xfd->intervall, NULL); continue; + while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { + if (sfd->forever || --sfd->retry) { + Nanosleep(&sfd->intervall, NULL); continue; } return STAT_RETRYLATER; } if (pid == 0) { /* child process */ - xfd->forever = false; xfd->retry = 0; + sfd->forever = false; sfd->retry = 0; break; } /* parent process */ - Close(xfd->fd); - Nanosleep(&xfd->intervall, NULL); + Close(sfd->fd); + Nanosleep(&sfd->intervall, NULL); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); continue; } else @@ -357,7 +359,7 @@ int _xioopen_proxy_prepare( return STAT_OK; } -int _xioopen_proxy_connect(struct single *xfd, +int _xioopen_proxy_connect(struct single *sfd, struct proxyvars *proxyvars, int level) { size_t offset; @@ -387,11 +389,11 @@ int _xioopen_proxy_connect(struct single *xfd, * xiosanitize(request, strlen(request), textbuff) = '\0'; Info1("sending \"%s\"", textbuff); /* write errors are assumed to always be hard errors, no retry */ - if (writefull(xfd->fd, request, strlen(request)) < 0) { + if (writefull(sfd->fd, request, strlen(request)) < 0) { Msg4(level, "write(%d, %p, "F_Zu"): %s", - xfd->fd, request, strlen(request), strerror(errno)); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + sfd->fd, request, strlen(request), strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } return STAT_RETRYLATER; } @@ -417,11 +419,11 @@ int _xioopen_proxy_connect(struct single *xfd, *next = '\0'; Info1("sending \"%s\\r\\n\"", header); *next++ = '\r'; *next++ = '\n'; *next++ = '\0'; - if (writefull(xfd->fd, header, strlen(header)) < 0) { + if (writefull(sfd->fd, header, strlen(header)) < 0) { Msg4(level, "write(%d, %p, "F_Zu"): %s", - xfd->fd, header, strlen(header), strerror(errno)); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + sfd->fd, header, strlen(header), strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } return STAT_RETRYLATER; } @@ -430,11 +432,11 @@ int _xioopen_proxy_connect(struct single *xfd, } Info("sending \"\\r\\n\""); - if (writefull(xfd->fd, "\r\n", 2) < 0) { + if (writefull(sfd->fd, "\r\n", 2) < 0) { Msg2(level, "write(%d, \"\\r\\n\", 2): %s", - xfd->fd, strerror(errno)); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + sfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } return STAT_RETRYLATER; } @@ -450,7 +452,7 @@ int _xioopen_proxy_connect(struct single *xfd, offset = 0; /* up to where the buffer is filled (relative) */ /*eol;*/ /* points to the first lineterm of the current line */ do { - sresult = xioproxy_recvbytes(xfd, buff+offset, 1, level); + sresult = xioproxy_recvbytes(sfd, buff+offset, 1, level); if (sresult <= 0) { state = XIOSTATE_ERROR; break; /* leave read cycles */ diff --git a/xio-pty.c b/xio-pty.c index 49a2418..d1ff2a0 100644 --- a/xio-pty.c +++ b/xio-pty.c @@ -18,7 +18,7 @@ #define MAXPTYNAMELEN 64 -static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3); +static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); const struct addrdesc xioaddr_pty = { "PTY", 3, xioopen_pty, GROUP_NAMED|GROUP_FD|GROUP_TERMIOS|GROUP_PTY, 0, 0, 0 HELP("") }; @@ -28,7 +28,14 @@ const struct optdesc opt_pty_wait_slave = { "pty-wait-slave", "wait-slave", OPT_ const struct optdesc opt_pty_intervall = { "pty-interval", NULL, OPT_PTY_INTERVALL, GROUP_PTY, PH_EARLY, TYPE_TIMESPEC, OFUNC_SPEC, 0, 0 }; #endif /* HAVE_POLL */ -static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) { +static int xioopen_pty( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ /* we expect the form: filename */ struct single *sfd = &xfd->stream; int ptyfd = -1, ttyfd = -1; @@ -49,7 +56,8 @@ static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xiofl struct timespec pollintv = { PTY_INTERVALL }; if (argc != 1) { - Error2("%s: wrong number of parameters (%d instead of 0)", argv[0], argc-1); + xio_syntax(argv[0], 0, argc-1, addrdesc->syntax); + return STAT_NORETRY; } sfd->howtoend = END_CLOSE; diff --git a/xio-rawip.c b/xio-rawip.c index 467e088..e54bac3 100644 --- a/xio-rawip.c +++ b/xio-rawip.c @@ -17,22 +17,10 @@ #include "xio-rawip.h" -static -int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *fd, groups_t groups, int pf, - int dummy2, int dummy3); -static -int xioopen_rawip_datagram(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *fd, groups_t groups, int pf, - int dummy2, int dummy3); -static -int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int pf, int socktype, int dummy3); -static -int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int pf, int socktype, int ipproto); +static int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); +static int xioopen_rawip_datagram(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); +static int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); +static int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); static int _xioopen_rawip_sendto(const char *hostname, const char *protname, @@ -62,21 +50,25 @@ const struct addrdesc xioaddr_rawip6_recv = { "IP6-RECV", 1+XIO_RDONLY, /* we expect the form: host:protocol */ /* struct sockaddr_in sa;*/ /* socklen_t salen;*/ -static -int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int pf, int dummy2, int dummy3) { +static int xioopen_rawip_sendto( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ + int pf = addrdesc->arg1; int result; if (argc != 3) { - Error2("%s: wrong number of parameters (%d instead of 2)", - argv[0], argc-1); + xio_syntax(argv[0], 2, argc-1, addrdesc->syntax); return STAT_NORETRY; } xioinit_ip(&pf, xioparms.preferred_ip); if ((result = _xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd, - groups, &pf)) != STAT_OK) { + addrdesc->groups, &pf)) != STAT_OK) { return result; } _xio_openlate(&xxfd->stream, opts); @@ -95,7 +87,7 @@ int _xioopen_rawip_sendto(const char *hostname, const char *protname, struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int *pf) { char *garbage; - xiosingle_t *xfd = &xxfd->stream; + xiosingle_t *sfd = &xxfd->stream; union sockaddr_union us; socklen_t uslen; int feats = 1; /* option bind supports only address, not port */ @@ -114,95 +106,106 @@ int _xioopen_rawip_sendto(const char *hostname, const char *protname, /*return STAT_NORETRY;*/ } - xfd->howtoend = END_SHUTDOWN; + sfd->howtoend = END_SHUTDOWN; retropt_int(opts, OPT_PROTOCOL_FAMILY, pf); - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; - applyopts(xfd, -1, opts, PH_INIT); + if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; + applyopts(sfd, -1, opts, PH_INIT); - xfd->salen = sizeof(xfd->peersa); + sfd->salen = sizeof(sfd->peersa); if ((result = xioresolve(hostname, NULL, *pf, socktype, ipproto, - &xfd->peersa, &xfd->salen, - xfd->para.socket.ip.ai_flags)) + &sfd->peersa, &sfd->salen, + sfd->para.socket.ip.ai_flags)) != STAT_OK) { return result; } if (*pf == PF_UNSPEC) { - *pf = xfd->peersa.soa.sa_family; + *pf = sfd->peersa.soa.sa_family; } uslen = socket_init(*pf, &us); - xfd->dtype = XIODATA_RECVFROM_SKIPIP; + sfd->dtype = XIODATA_RECVFROM_SKIPIP; if (retropt_bind(opts, *pf, socktype, ipproto, &us.soa, &uslen, feats, - xfd->para.socket.ip.ai_flags) + sfd->para.socket.ip.ai_flags) != STAT_NOACTION) { needbind = true; } return _xioopen_dgram_sendto(needbind?&us:NULL, uslen, - opts, xioflags, xfd, groups, *pf, socktype, ipproto, 0); + opts, xioflags, sfd, groups, *pf, socktype, ipproto, 0); } /* we expect the form: address:protocol */ -static -int xioopen_rawip_datagram(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int pf, int dummy2, int dummy3) { - xiosingle_t *xfd = &xxfd->stream; +static int xioopen_rawip_datagram( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ + xiosingle_t *sfd = &xxfd->stream; + int pf = addrdesc->arg1; char *rangename; int result; if (argc != 3) { - Error2("%s: wrong number of parameters (%d instead of 2)", - argv[0], argc-1); + xio_syntax(argv[0], 2, argc-1, addrdesc->syntax); return STAT_NORETRY; } xioinit_ip(&pf, xioparms.preferred_ip); if ((result = _xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd, - groups, &pf)) != STAT_OK) { + addrdesc->groups, &pf)) != STAT_OK) { return result; } - xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; + sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; if (pf == PF_INET) { - xfd->dtype |= XIOREAD_RECV_SKIPIP; + sfd->dtype |= XIOREAD_RECV_SKIPIP; } - xfd->para.socket.la.soa.sa_family = xfd->peersa.soa.sa_family; + sfd->para.socket.la.soa.sa_family = sfd->peersa.soa.sa_family; /* which reply packets will be accepted - determine by range option */ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (xioparserange(rangename, pf, &xfd->para.socket.range, - xfd->para.socket.ip.ai_flags) + if (xioparserange(rangename, pf, &sfd->para.socket.range, + sfd->para.socket.ip.ai_flags) < 0) { free(rangename); return STAT_NORETRY; } - xfd->para.socket.dorange = true; - xfd->dtype |= XIOREAD_RECV_CHECKRANGE; + sfd->para.socket.dorange = true; + sfd->dtype |= XIOREAD_RECV_CHECKRANGE; free(rangename); } #if WITH_LIBWRAP - xio_retropt_tcpwrap(xfd, opts); + xio_retropt_tcpwrap(sfd, opts); #endif /* WITH_LIBWRAP */ - _xio_openlate(xfd, opts); + _xio_openlate(sfd, opts); return STAT_OK; } -static -int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int pf, int socktype, int dummy3) { +static int xioopen_rawip_recvfrom( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ + struct single *sfd = &xfd->stream; const char *protname = argv[1]; + int pf = addrdesc->arg1; + int socktype = addrdesc->arg2; char *garbage; union sockaddr_union us; socklen_t uslen = sizeof(us); @@ -211,8 +214,7 @@ int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts, int result; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } @@ -226,7 +228,7 @@ int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts, protname); /*return STAT_NORETRY;*/ } - xfd->stream.howtoend = END_NONE; + sfd->howtoend = END_NONE; retropt_socket_pf(opts, &pf); if (pf == PF_UNSPEC) { @@ -244,28 +246,34 @@ int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts, } if (retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, 1, - xfd->stream.para.socket.ip.ai_flags) + sfd->para.socket.ip.ai_flags) != STAT_NOACTION) { needbind = true; } - xfd->stream.dtype = XIODATA_RECVFROM_SKIPIP_ONE; + sfd->dtype = XIODATA_RECVFROM_SKIPIP_ONE; if ((result = - _xioopen_dgram_recvfrom(&xfd->stream, xioflags, needbind?&us.soa:NULL, + _xioopen_dgram_recvfrom(sfd, xioflags, needbind?&us.soa:NULL, uslen, opts, pf, socktype, ipproto, E_ERROR)) != STAT_OK) { return result; } - _xio_openlate(&xfd->stream, opts); + _xio_openlate(sfd, opts); return STAT_OK; } -static -int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int pf, int socktype, int dummy3) { +static int xioopen_rawip_recv( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ const char *protname = argv[1]; + int pf = addrdesc->arg1; + int socktype = addrdesc->arg2; char *garbage; bool needbind = false; union sockaddr_union us; @@ -274,8 +282,7 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, int result; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } diff --git a/xio-readline.c b/xio-readline.c index 42b076d..b29139c 100644 --- a/xio-readline.c +++ b/xio-readline.c @@ -25,9 +25,7 @@ uses stdin!! /* length of buffer for dynamic prompt */ #define READLINE_MAXPROMPT 512 -static int xioopen_readline(int argc, const char *argv[], struct opt *opts, - int rw, xiofile_t *xfd, groups_t groups, - int dummy1, int dummy2, int dummy3); +static int xioopen_readline(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *xfd, const struct addrdesc *addrdesc); const struct addrdesc xioaddr_readline = { "READLINE", 3, xioopen_readline, GROUP_FD|GROUP_TERMIOS|GROUP_READLINE, 0, 0, 0 HELP(NULL) }; @@ -37,9 +35,14 @@ const struct optdesc opt_prompt = { "prompt", NULL, OPT_PROMPT, const struct optdesc opt_noprompt = { "noprompt", NULL, OPT_NOPROMPT, GROUP_READLINE, PH_LATE, TYPE_BOOL, OFUNC_SPEC, 0 }; const struct optdesc opt_noecho = { "noecho", NULL, OPT_NOECHO, GROUP_READLINE, PH_LATE, TYPE_STRING, OFUNC_SPEC, 0 }; -static int xioopen_readline(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int dummy1, int dummy2, int dummy3) { +static int xioopen_readline( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ struct single *sfd = &xfd->stream; int rw = (xioflags & XIO_ACCMODE); char msgbuf[256], *cp = msgbuf; @@ -47,7 +50,7 @@ static int xioopen_readline(int argc, const char *argv[], struct opt *opts, char *noecho = NULL; if (argc != 1) { - Error1("%s: 0 parameters required", argv[0]); + xio_syntax(argv[0], 0, argc-1, addrdesc->syntax); return STAT_NORETRY; } diff --git a/xio-socket.c b/xio-socket.c index ba0960c..d23d2ee 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -30,30 +30,12 @@ #include "xio-tcpwrap.h" -static -int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int dummy1, int dummy2, int dummy3); -static -int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int dummy1, int dummy2, int dummy3); -static -int xioopen_socket_sendto(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int dummy1, int dummy2, int dummy3); -static -int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int dummy1, int dummy2, int dummy3); -static -int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int dummy1, int socktype, int dummy3); -static -int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int dummy1, int dummy2, int dummy3); +static int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); +static int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); +static int xioopen_socket_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); +static int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); +static int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); +static int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); static int _xioopen_socket_sendto(const char *pfname, const char *type, @@ -68,7 +50,7 @@ xiolog_ancillary_socket(struct single *sfd, struct cmsghdr *cmsg, int *num, char *envbuff, int envlen, char *valbuff, int vallen); static int xiobind( - struct single *xfd, + struct single *sfd, union sockaddr_union *us, size_t uslen, struct opt *opts, @@ -215,10 +197,14 @@ const struct optdesc opt_null_eof = { "null-eof", NULL, OPT_NULL_EOF, GROUP_SOCK #if WITH_GENERICSOCKET -static -int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int dummy1, int dummy2, int dummy3) { +static int xioopen_socket_connect( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ struct single *sfd = &xxfd->stream; const char *pfname = argv[1]; const char *protname = argv[2]; @@ -233,8 +219,7 @@ int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, int result; if (argc != 4) { - Error2("%s: wrong number of parameters (%d instead of 3)", - argv[0], argc-1); + xio_syntax(argv[0], 3, argc-1, addrdesc->syntax); return STAT_NORETRY; } @@ -297,10 +282,14 @@ int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, } #if WITH_LISTEN -static -int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int dummy1, int dummy2, int dummy3) { +static int xioopen_socket_listen( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ struct single *sfd = &xxfd->stream; const char *pfname = argv[1]; const char *protname = argv[2]; @@ -314,8 +303,7 @@ int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, int result; if (argc != 4) { - Error2("%s: wrong number of parameters (%d instead of 3)", - argv[0], argc-1); + xio_syntax(argv[0], 3, argc-1, addrdesc->syntax); return STAT_NORETRY; } @@ -368,20 +356,23 @@ int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, #endif /* WITH_LISTEN */ /* we expect the form: ...:domain:type:protocol:remote-address */ -static -int xioopen_socket_sendto(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int dummy1, int dummy2, int dummy3) { +static int xioopen_socket_sendto( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ int result; if (argc != 5) { - Error2("%s: wrong number of parameters (%d instead of 4)", - argv[0], argc-1); + xio_syntax(argv[0], 4, argc-1, addrdesc->syntax); return STAT_NORETRY; } if ((result = _xioopen_socket_sendto(argv[1], argv[2], argv[3], argv[4], - opts, xioflags, xxfd, groups)) + opts, xioflags, xxfd, addrdesc->groups)) != STAT_OK) { return result; } @@ -482,24 +473,28 @@ int _xioopen_socket_sendto(const char *pfname, const char *type, /* we expect the form: ...:domain:socktype:protocol:local-address */ static -int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int dummy, int summy2, int dummy3) { - struct single *xfd = &xxfd->stream; +int xioopen_socket_recvfrom( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ + struct single *sfd = &xxfd->stream; const char *pfname = argv[1]; const char *typename = argv[2]; const char *protname = argv[3]; const char *address = argv[4]; char *garbage; - union sockaddr_union *us = &xfd->para.socket.la; + union sockaddr_union *us = &sfd->para.socket.la; socklen_t uslen; size_t ussize; int pf, socktype, proto; char *rangename; int result; if (argc != 5) { - Error2("%s: wrong number of parameters (%d instead of 4)", - argv[0], argc-1); + xio_syntax(argv[0], 4, argc-1, addrdesc->syntax); return STAT_NORETRY; } @@ -521,7 +516,7 @@ int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts, retropt_socket_pf(opts, &pf); retropt_int(opts, OPT_SO_TYPE, &socktype); /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ - xfd->howtoend = END_NONE; + sfd->howtoend = END_NONE; ussize = 0; if ((result = @@ -537,35 +532,40 @@ int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts, + sizeof(us->soa.sa_len); #endif ; - xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; + sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (xioparserange(rangename, 0, &xfd->para.socket.range, - xfd->para.socket.ip.ai_flags) + if (xioparserange(rangename, 0, &sfd->para.socket.range, + sfd->para.socket.ip.ai_flags) < 0) { free(rangename); return STAT_NORETRY; } - xfd->para.socket.dorange = true; + sfd->para.socket.dorange = true; free(rangename); } if ((result = - _xioopen_dgram_recvfrom(xfd, xioflags, &us->soa, uslen, + _xioopen_dgram_recvfrom(sfd, xioflags, &us->soa, uslen, opts, pf, socktype, proto, E_ERROR)) != STAT_OK) { return result; } - _xio_openlate(xfd, opts); + _xio_openlate(sfd, opts); return STAT_OK; } /* we expect the form: ...:domain:type:protocol:local-address */ static -int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int dummy1, int dummy2, int dummy3) { - struct single *xfd = &xxfd->stream; +int xioopen_socket_recv( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ + struct single *sfd = &xxfd->stream; const char *pfname = argv[1]; const char *typename = argv[2]; const char *protname = argv[3]; @@ -578,8 +578,7 @@ int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts, int result; if (argc != 5) { - Error2("%s: wrong number of parameters (%d instead of 4)", - argv[0], argc-1); + xio_syntax(argv[0], 4, argc-1, addrdesc->syntax); return STAT_NORETRY; } @@ -601,7 +600,7 @@ int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts, retropt_socket_pf(opts, &pf); retropt_int(opts, OPT_SO_TYPE, &socktype); /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ - xfd->howtoend = END_NONE; + sfd->howtoend = END_NONE; ussize = 0; if ((result = @@ -617,37 +616,41 @@ int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts, +sizeof(us.soa.sa_len) #endif ; - xfd->dtype = XIOREAD_RECV; - xfd->para.socket.la.soa.sa_family = pf; + sfd->dtype = XIOREAD_RECV; + sfd->para.socket.la.soa.sa_family = pf; if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (xioparserange(rangename, 0, &xfd->para.socket.range, - xfd->para.socket.ip.ai_flags) + if (xioparserange(rangename, 0, &sfd->para.socket.range, + sfd->para.socket.ip.ai_flags) < 0) { free(rangename); return STAT_NORETRY; } - xfd->para.socket.dorange = true; + sfd->para.socket.dorange = true; free(rangename); } if ((result = - _xioopen_dgram_recv(xfd, xioflags, &us.soa, + _xioopen_dgram_recv(sfd, xioflags, &us.soa, uslen, opts, pf, socktype, proto, E_ERROR)) != STAT_OK) { return result; } - _xio_openlate(xfd, opts); + _xio_openlate(sfd, opts); return STAT_OK; } /* we expect the form: ...:domain:type:protocol:remote-address */ -static -int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int dummy1, int dummy2, int dummy3) { - xiosingle_t *xfd = &xxfd->stream; +static int xioopen_socket_datagram( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ + xiosingle_t *sfd = &xxfd->stream; const char *pfname = argv[1]; const char *typename = argv[2]; const char *protname = argv[3]; @@ -659,8 +662,7 @@ int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts, int result; if (argc != 5) { - Error2("%s: wrong number of parameters (%d instead of 4)", - argv[0], argc-1); + xio_syntax(argv[0], 4, argc-1, addrdesc->syntax); return STAT_NORETRY; } @@ -671,50 +673,50 @@ int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts, retropt_socket_pf(opts, &pf); /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ - xfd->howtoend = END_SHUTDOWN; + sfd->howtoend = END_SHUTDOWN; - xfd->peersa.soa.sa_family = pf; + sfd->peersa.soa.sa_family = pf; themsize = 0; if ((result = - dalan(address, (uint8_t *)&xfd->peersa.soa.sa_data, &themsize, - sizeof(xfd->peersa), 'i')) + dalan(address, (uint8_t *)&sfd->peersa.soa.sa_data, &themsize, + sizeof(sfd->peersa), 'i')) < 0) { Error1("data too long: \"%s\"", address); } else if (result > 0) { Error1("syntax error in \"%s\"", address); } - xfd->salen = themsize + sizeof(sa_family_t); + sfd->salen = themsize + sizeof(sa_family_t); #if HAVE_STRUCT_SOCKADDR_SALEN - xfd->peersa.soa.sa_len = - sizeof(xfd->peersa.soa.sa_len) + sizeof(xfd->peersa.soa.sa_family) + + sfd->peersa.soa.sa_len = + sizeof(sfd->peersa.soa.sa_len) + sizeof(sfd->peersa.soa.sa_family) + themsize; #endif if ((result = _xioopen_socket_sendto(pfname, typename, protname, address, - opts, xioflags, xxfd, groups)) + opts, xioflags, xxfd, addrdesc->groups)) != STAT_OK) { return result; } - xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; + sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; - xfd->para.socket.la.soa.sa_family = xfd->peersa.soa.sa_family; + sfd->para.socket.la.soa.sa_family = sfd->peersa.soa.sa_family; /* which reply sockets will accept - determine by range option */ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (xioparserange(rangename, 0, &xfd->para.socket.range, - xfd->para.socket.ip.ai_flags) + if (xioparserange(rangename, 0, &sfd->para.socket.range, + sfd->para.socket.ip.ai_flags) < 0) { free(rangename); return STAT_NORETRY; } - xfd->para.socket.dorange = true; - xfd->dtype |= XIOREAD_RECV_CHECKRANGE; + sfd->para.socket.dorange = true; + sfd->dtype |= XIOREAD_RECV_CHECKRANGE; free(rangename); } - _xio_openlate(xfd, opts); + _xio_openlate(sfd, opts); return STAT_OK; } @@ -943,7 +945,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC returns 0 on success. */ -int xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen, +int xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, struct sockaddr *them, size_t themlen, struct opt *opts, int pf, int socktype, int protocol, bool alt) { @@ -963,22 +965,22 @@ int xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen, do { /* loop over retries and forks */ #if WITH_RETRY - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { level = E_INFO; } else #endif /* WITH_RETRY */ level = E_ERROR; result = - _xioopen_connect(xfd, us, uslen, them, themlen, opts, + _xioopen_connect(sfd, us, uslen, them, themlen, opts, pf, socktype, protocol, alt, level); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: - if (xfd->forever || xfd->retry) { - --xfd->retry; + if (sfd->forever || sfd->retry) { + --sfd->retry; if (result == STAT_RETRYLATER) { - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); } dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); continue; @@ -997,16 +999,16 @@ int xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen, if (dofork) { pid_t pid; int level = E_ERROR; - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { level = E_WARN; /* most users won't expect a problem here, so Notice is too weak */ } - while ((pid = xio_fork(false, level, xfd->shutup)) < 0) { - --xfd->retry; - if (xfd->forever || xfd->retry) { + while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { + --sfd->retry; + if (sfd->forever || sfd->retry) { dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); - Nanosleep(&xfd->intervall, NULL); continue; + Nanosleep(&sfd->intervall, NULL); continue; } return STAT_RETRYLATER; } @@ -1016,9 +1018,9 @@ int xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen, } /* parent process */ - Close(xfd->fd); + Close(sfd->fd); /* with and without retry */ - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); continue; /* with next socket() bind() connect() */ } else @@ -1124,7 +1126,7 @@ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */ OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, cloexec, OPT_RANGE, tcpwrap EINTR is not handled specially. */ -int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, +int _xioopen_dgram_recvfrom(struct single *sfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, int pf, int socktype, int proto, int level) { @@ -1143,25 +1145,25 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, Error("option fork not allowed here"); return STAT_NORETRY; } - xfd->flags |= XIO_DOESFORK; + sfd->flags |= XIO_DOESFORK; } - if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY; + if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY; - if ((xfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) { + if ((sfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) { return STAT_RETRYLATER; } - applyopts(xfd, -1, opts, PH_PASTSOCKET); + applyopts(sfd, -1, opts, PH_PASTSOCKET); - applyopts_cloexec(xfd->fd, opts); + applyopts_cloexec(sfd->fd, opts); - if (xiobind(xfd, (union sockaddr_union *)us, uslen, + if (xiobind(sfd, (union sockaddr_union *)us, uslen, opts, pf, 0, level) < 0) { return -1; } - applyopts(xfd, -1, opts, PH_PASTBIND); + applyopts(sfd, -1, opts, PH_PASTBIND); #if WITH_UNIX if (pf == AF_UNIX && us != NULL) { @@ -1173,18 +1175,18 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, /* for generic sockets, this has already been retrieved */ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (xioparserange(rangename, pf, &xfd->para.socket.range, - xfd->para.socket.ip.ai_flags) + if (xioparserange(rangename, pf, &sfd->para.socket.range, + sfd->para.socket.ip.ai_flags) < 0) { free(rangename); return STAT_NORETRY; } free(rangename); - xfd->para.socket.dorange = true; + sfd->para.socket.dorange = true; } #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP - xio_retropt_tcpwrap(xfd, opts); + xio_retropt_tcpwrap(sfd, opts); #endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */ if (xioparms.logopt == 'm') { @@ -1215,7 +1217,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, if (drop) { char *dummy[2]; - Recv(xfd->fd, dummy, sizeof(dummy), 0); + Recv(sfd->fd, dummy, sizeof(dummy), 0); drop = true; } @@ -1229,7 +1231,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, } else { Notice1("receiving IP protocol %u", proto); } - readfd.fd = xfd->fd; + readfd.fd = sfd->fd; readfd.events = POLLIN; if (xiopoll(&readfd, 1, NULL) > 0) { break; @@ -1239,8 +1241,8 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, continue; } - Msg2(level, "poll({%d,,},,-1): %s", xfd->fd, strerror(errno)); - Close(xfd->fd); + Msg2(level, "poll({%d,,},,-1): %s", sfd->fd, strerror(errno)); + Close(sfd->fd); return STAT_RETRYLATER; } while (true); @@ -1252,7 +1254,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, #if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN msgh.msg_controllen = sizeof(ctrlbuff); #endif - while ((rc = xiogetancillary(xfd->fd, + while ((rc = xiogetancillary(sfd->fd, &msgh, MSG_PEEK #ifdef MSG_TRUNC @@ -1267,12 +1269,12 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, sockaddr_info(&pa->soa, palen, peername, sizeof(peername))/*, sockaddr_info(&la->soa, sockname, sizeof(sockname))*/); - xiodopacketinfo(xfd, &msgh, true, true); + xiodopacketinfo(sfd, &msgh, true, true); - if (xiocheckpeer(xfd, pa, la) < 0) { + if (xiocheckpeer(sfd, pa, la) < 0) { /* drop packet */ char buff[512]; - Recv(xfd->fd, buff, sizeof(buff), 0); + Recv(sfd->fd, buff, sizeof(buff), 0); continue; } Info1("permitting packet from %s", @@ -1283,12 +1285,12 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, /*xiosetsockaddrenv("SOCK", la, lalen, proto);*/ xiosetsockaddrenv("PEER", pa, palen, proto); - applyopts(xfd, -1, opts, PH_FD); + applyopts(sfd, -1, opts, PH_FD); - applyopts(xfd, -1, opts, PH_CONNECTED); + applyopts(sfd, -1, opts, PH_CONNECTED); - xfd->peersa = *(union sockaddr_union *)pa; - xfd->salen = palen; + sfd->peersa = *(union sockaddr_union *)pa; + sfd->salen = palen; if (dofork) { Info("Generating socketpair that triggers parent when packet has been consumed"); @@ -1296,29 +1298,29 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, Error1("socketpair(PF_UNIX, SOCK_STREAM, 0, ...): %s", strerror(errno)); } - if ((pid = xio_fork(false, level, xfd->shutup)) < 0) { + if ((pid = xio_fork(false, level, sfd->shutup)) < 0) { Close(trigger[0]); Close(trigger[1]); - Close(xfd->fd); + Close(sfd->fd); return STAT_RETRYLATER; } if (pid == 0) { /* child */ Close(trigger[0]); - xfd->triggerfd = trigger[1]; - Fcntl_l(xfd->triggerfd, F_SETFD, FD_CLOEXEC); + sfd->triggerfd = trigger[1]; + Fcntl_l(sfd->triggerfd, F_SETFD, FD_CLOEXEC); #if WITH_RETRY /* !? */ - xfd->retry = 0; - xfd->forever = 0; + sfd->retry = 0; + sfd->forever = 0; level = E_ERROR; #endif /* WITH_RETRY */ #if WITH_UNIX /* with UNIX sockets: only listening parent is allowed to remove the socket file */ - xfd->opt_unlink_close = false; + sfd->opt_unlink_close = false; #endif /* WITH_UNIX */ break; @@ -1337,7 +1339,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, break; } } - if ((result = _xio_openlate(xfd, opts)) != 0) + if ((result = _xio_openlate(sfd, opts)) != 0) return STAT_NORETRY; return STAT_OK; @@ -1345,23 +1347,23 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, /* returns STAT_* */ -int _xioopen_dgram_recv(struct single *xfd, int xioflags, +int _xioopen_dgram_recv(struct single *sfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, int pf, int socktype, int proto, int level) { char *rangename; - if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY; + if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY; - if ((xfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) { + if ((sfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) { return STAT_RETRYLATER; } - applyopts(xfd, -1, opts, PH_PASTSOCKET); + applyopts(sfd, -1, opts, PH_PASTSOCKET); - applyopts_cloexec(xfd->fd, opts); + applyopts_cloexec(sfd->fd, opts); - if (xiobind(xfd, (union sockaddr_union *)us, uslen, opts, pf, 0, level) < 0) { + if (xiobind(sfd, (union sockaddr_union *)us, uslen, opts, pf, 0, level) < 0) { return -1; } @@ -1375,19 +1377,19 @@ int _xioopen_dgram_recv(struct single *xfd, int xioflags, #if WITH_IP4 /*|| WITH_IP6*/ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (xioparserange(rangename, pf, &xfd->para.socket.range, - xfd->para.socket.ip.ai_flags) + if (xioparserange(rangename, pf, &sfd->para.socket.range, + sfd->para.socket.ip.ai_flags) < 0) { free(rangename); return STAT_NORETRY; } free(rangename); - xfd->para.socket.dorange = true; + sfd->para.socket.dorange = true; } #endif #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP - xio_retropt_tcpwrap(xfd, opts); + xio_retropt_tcpwrap(sfd, opts); #endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */ if (xioparms.logopt == 'm') { @@ -1599,15 +1601,15 @@ int xiocheckrange(union sockaddr_union *sa, struct xiorange *range) { return -1; } -int xiocheckpeer(xiosingle_t *xfd, +int xiocheckpeer(xiosingle_t *sfd, union sockaddr_union *pa, union sockaddr_union *la) { char infobuff[256]; int result; #if WITH_IP4 - if (xfd->para.socket.dorange) { + if (sfd->para.socket.dorange) { if (pa == NULL) { return -1; } - if (xiocheckrange(pa, &xfd->para.socket.range) < 0) { + if (xiocheckrange(pa, &sfd->para.socket.range) < 0) { char infobuff[256]; Warn1("refusing connection from %s due to range option", sockaddr_info(&pa->soa, 0, @@ -1621,11 +1623,11 @@ int xiocheckpeer(xiosingle_t *xfd, #endif /* WITH_IP4 */ #if WITH_TCP || WITH_UDP - if (xfd->para.socket.ip.dosourceport) { + if (sfd->para.socket.ip.dosourceport) { if (pa == NULL) { return -1; } #if WITH_IP4 if (pa->soa.sa_family == AF_INET && - ntohs(((struct sockaddr_in *)pa)->sin_port) != xfd->para.socket.ip.sourceport) { + ntohs(((struct sockaddr_in *)pa)->sin_port) != sfd->para.socket.ip.sourceport) { Warn1("refusing connection from %s due to wrong sourceport", sockaddr_info(&pa->soa, 0, infobuff, sizeof(infobuff))); @@ -1634,7 +1636,7 @@ int xiocheckpeer(xiosingle_t *xfd, #endif /* WITH_IP4 */ #if WITH_IP6 if (pa->soa.sa_family == AF_INET6 && - ntohs(((struct sockaddr_in6 *)pa)->sin6_port) != xfd->para.socket.ip.sourceport) { + ntohs(((struct sockaddr_in6 *)pa)->sin6_port) != sfd->para.socket.ip.sourceport) { Warn1("refusing connection from %s due to wrong sourceport", sockaddr_info(&pa->soa, 0, infobuff, sizeof(infobuff))); @@ -1644,7 +1646,7 @@ int xiocheckpeer(xiosingle_t *xfd, Info1("permitting connection from %s due to sourceport option", sockaddr_info(&pa->soa, 0, infobuff, sizeof(infobuff))); - } else if (xfd->para.socket.ip.lowport) { + } else if (sfd->para.socket.ip.lowport) { if (pa == NULL) { return -1; } if (pa->soa.sa_family == AF_INET && ntohs(((struct sockaddr_in *)pa)->sin_port) >= IPPORT_RESERVED) { @@ -1670,7 +1672,7 @@ int xiocheckpeer(xiosingle_t *xfd, #endif /* WITH_TCP || WITH_UDP */ #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP - result = xio_tcpwrap_check(xfd, la, pa); + result = xio_tcpwrap_check(sfd, la, pa); if (result < 0) { char infobuff[256]; Warn1("refusing connection from %s due to tcpwrapper option", @@ -2052,7 +2054,7 @@ xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]) { } int xiobind( - struct single *xfd, + struct single *sfd, union sockaddr_union *us, size_t uslen, struct opt *opts, @@ -2068,8 +2070,8 @@ int xiobind( applyopts_named(us->un.sun_path, opts, PH_PREOPEN); } #endif - applyopts(xfd, xfd->fd, opts, PH_PREBIND); - applyopts(xfd, xfd->fd, opts, PH_BIND); + applyopts(sfd, sfd->fd, opts, PH_PREBIND); + applyopts(sfd, sfd->fd, opts, PH_BIND); #if WITH_TCP || WITH_UDP if (alt) { union sockaddr_union sin, *sinp; @@ -2125,13 +2127,13 @@ int xiobind( i = N = XIO_IPPORT_LOWER + dv.rem; do { /* loop over lowport bind() attempts */ *port = htons(i); - if (Bind(xfd->fd, &sinp->soa, sizeof(*sinp)) < 0) { + if (Bind(sfd->fd, &sinp->soa, sizeof(*sinp)) < 0) { Msg4(errno==EADDRINUSE?E_INFO:level, - "bind(%d, {%s}, "F_Zd"): %s", xfd->fd, + "bind(%d, {%s}, "F_Zd"): %s", sfd->fd, sockaddr_info(&sinp->soa, sizeof(*sinp), infobuff, sizeof(infobuff)), sizeof(*sinp), strerror(errno)); if (errno != EADDRINUSE) { - Close(xfd->fd); + Close(sfd->fd); return STAT_RETRYLATER; } } else { @@ -2141,7 +2143,7 @@ int xiobind( if (i == N) { Msg(level, "no low port available"); /*errno = EADDRINUSE; still assigned */ - Close(xfd->fd); + Close(sfd->fd); return STAT_RETRYLATER; } } while (i != N); @@ -2154,11 +2156,11 @@ int xiobind( applyopts_named(us->un.sun_path, opts, PH_PREOPEN); } #endif - if (Bind(xfd->fd, &us->soa, uslen) < 0) { + if (Bind(sfd->fd, &us->soa, uslen) < 0) { Msg4(level, "bind(%d, {%s}, "F_Zd"): %s", - xfd->fd, sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)), + sfd->fd, sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); - Close(xfd->fd); + Close(sfd->fd); return STAT_RETRYLATER; } } @@ -2168,7 +2170,7 @@ int xiobind( } #endif - applyopts(xfd, -1, opts, PH_PASTBIND); + applyopts(sfd, -1, opts, PH_PASTBIND); return 0; } diff --git a/xio-socketpair.c b/xio-socketpair.c index 8b3f3cd..f9b3977 100644 --- a/xio-socketpair.c +++ b/xio-socketpair.c @@ -14,8 +14,7 @@ #if WITH_SOCKETPAIR -static int xioopen_socketpair(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3); - +static int xioopen_socketpair(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); const struct addrdesc xioaddr_socketpair = { "SOCKETPAIR", 3, xioopen_socketpair, GROUP_FD|GROUP_SOCKET, 0, 0, 0 HELP(":") }; @@ -27,10 +26,7 @@ static int xioopen_socketpair( struct opt *opts, int xioflags, xiofile_t *xfd, - groups_t groups , - int dummy1, - int dummy2, - int dummy3) + const struct addrdesc *addrdesc) { struct single *sfd = &xfd->stream; struct opt *opts2; @@ -41,7 +37,8 @@ static int xioopen_socketpair( int result; if (argc != 1) { - Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); + return STAT_NORETRY; } sfd->para.bipipe.socktype = SOCK_DGRAM; diff --git a/xio-socks.c b/xio-socks.c index 3885b36..32616c8 100644 --- a/xio-socks.c +++ b/xio-socks.c @@ -27,10 +27,7 @@ enum { #define SOCKSPORT "1080" #define BUFF_LEN (SIZEOF_STRUCT_SOCKS4+512) -static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *fd, - groups_t groups, int dummy1, int dummy2, - int dummy3); +static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); const struct optdesc opt_socksport = { "socksport", NULL, OPT_SOCKSPORT, GROUP_IP_SOCKS4, PH_LATE, TYPE_STRING, OFUNC_SPEC }; const struct optdesc opt_socksuser = { "socksuser", NULL, OPT_SOCKSUSER, GROUP_IP_SOCKS4, PH_LATE, TYPE_NAME, OFUNC_SPEC }; @@ -39,12 +36,17 @@ const struct addrdesc xioaddr_socks4_connect = { "SOCKS4", 3, xioopen_socks4_con const struct addrdesc xioaddr_socks4a_connect = { "SOCKS4A", 3, xioopen_socks4_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS4|GROUP_CHILD|GROUP_RETRY, 1, 0, 0 HELP(":::") }; -static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, - groups_t groups, int socks4a, int dummy2, - int dummy3) { +static int xioopen_socks4_connect( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ /* we expect the form: host:host:port */ - struct single *xfd = &xxfd->stream; + struct single *sfd = &xxfd->stream; + int socks4a = addrdesc->arg1; struct opt *opts0 = NULL; const char *sockdname; char *socksport; const char *targetname, *targetport; @@ -67,16 +69,16 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts int result; if (argc != 4) { - Error1("%s: 3 parameters required", argv[0]); + xio_syntax(argv[0], 3, argc-1, addrdesc->syntax); return STAT_NORETRY; } sockdname = argv[1]; targetname = argv[2]; targetport = argv[3]; - xfd->howtoend = END_SHUTDOWN; - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; - applyopts(xfd, 1, opts, PH_INIT); + sfd->howtoend = END_SHUTDOWN; + if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; + applyopts(sfd, 1, opts, PH_INIT); retropt_int(opts, OPT_SO_TYPE, &socktype); @@ -99,7 +101,7 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts result = _xioopen_ipapp_prepare(opts, &opts0, sockdname, socksport, &pf, ipproto, - xfd->para.socket.ip.ai_flags, + sfd->para.socket.ip.ai_flags, &themlist, us, &uslen, &needbind, &lowport, socktype); @@ -119,15 +121,16 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts /* we try to resolve the target address _before_ connecting to the socks server: this avoids unnecessary socks connects and timeouts */ result = - _xioopen_socks4_connect0(xfd, targetname, socks4a, sockhead, + _xioopen_socks4_connect0(sfd, targetname, socks4a, sockhead, (ssize_t *)&buflen, level); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (xfd->forever || xfd->retry--) { - if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL); + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); continue; } #endif /* WITH_RETRY */ @@ -143,7 +146,7 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts sockaddr_info(themp->ai_addr, themp->ai_addrlen, infobuff, sizeof(infobuff))); #if WITH_RETRY - if (xfd->forever || xfd->retry || ai_sorted[i] != NULL) { + if (sfd->forever || sfd->retry || ai_sorted[i] != NULL) { level = E_INFO; } else #endif /* WITH_RETRY */ @@ -151,27 +154,25 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts /* this cannot fork because we retrieved fork option above */ result = - _xioopen_connect(xfd, + _xioopen_connect(sfd, needbind?us:NULL, sizeof(*us), themp->ai_addr, themp->ai_addrlen, - opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, - lowport, level); + opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, lowport, level); if (result == STAT_OK) break; - themp = ai_sorted[i++]; - if (themp == NULL) { + themp = ai_sorted[i++]; + if (themp == NULL) result = STAT_RETRYLATER; - } } switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (xfd->forever || xfd->retry) { - --xfd->retry; + if (sfd->forever || sfd->retry) { + --sfd->retry; if (result == STAT_RETRYLATER) - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); continue; } #endif /* WITH_RETRY */ @@ -181,19 +182,19 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts return result; } xiofreeaddrinfo(themlist); - applyopts(xfd, -1, opts, PH_ALL); + applyopts(sfd, -1, opts, PH_ALL); - if ((result = _xio_openlate(xfd, opts)) < 0) + if ((result = _xio_openlate(sfd, opts)) < 0) return result; - result = _xioopen_socks4_connect(xfd, sockhead, buflen, level); + result = _xioopen_socks4_connect(sfd, sockhead, buflen, level); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (xfd->forever || xfd->retry--) { - if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL); + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); continue; } #endif /* WITH_RETRY */ @@ -209,26 +210,27 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts if (dofork) { pid_t pid; int level = E_ERROR; - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { level = E_WARN; /* most users won't expect a problem here, so Notice is too weak */ } - while ((pid = xio_fork(false, level, xfd->shutup)) < 0) { - if (xfd->forever || --xfd->retry) { - Nanosleep(&xfd->intervall, NULL); + while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { + if (sfd->forever || --sfd->retry) { + Nanosleep(&sfd->intervall, NULL); continue; } return STAT_RETRYLATER; } if (pid == 0) { /* child process */ - xfd->forever = false; xfd->retry = 0; + sfd->forever = false; + sfd->retry = 0; break; } /* parent process */ - Close(xfd->fd); - Nanosleep(&xfd->intervall, NULL); + Close(sfd->fd); + Nanosleep(&sfd->intervall, NULL); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); continue; } else @@ -282,7 +284,7 @@ int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **soc /* called within retry/fork loop, before connect() */ int - _xioopen_socks4_connect0(struct single *xfd, + _xioopen_socks4_connect0(struct single *sfd, const char *hostname, /* socks target host */ int socks4a, struct socks4 *sockhead, @@ -298,7 +300,7 @@ int if ((result = xioresolve(hostname, NULL, PF_INET, SOCK_STREAM, IPPROTO_TCP, &sau, &saulen, - xfd->para.socket.ip.ai_flags)) + sfd->para.socket.ip.ai_flags)) != STAT_OK) { return result; /*! STAT_RETRY? */ } @@ -330,7 +332,7 @@ int /* perform socks4 client dialog on existing FD. Called within fork/retry loop, after connect() */ -int _xioopen_socks4_connect(struct single *xfd, +int _xioopen_socks4_connect(struct single *sfd, struct socks4 *sockhead, size_t headlen, int level) { @@ -365,11 +367,11 @@ int _xioopen_socks4_connect(struct single *xfd, } } #endif /* WITH_MSGLEVEL <= E_DEBUG */ - if (writefull(xfd->fd, sockhead, headlen) < 0) { + if (writefull(sfd->fd, sockhead, headlen) < 0) { Msg4(level, "write(%d, %p, "F_Zu"): %s", - xfd->fd, sockhead, headlen, strerror(errno)); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + sfd->fd, sockhead, headlen, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } return STAT_RETRYLATER; /* retry complete open cycle */ } @@ -379,20 +381,20 @@ int _xioopen_socks4_connect(struct single *xfd, while (bytes >= 0) { /* loop over answer chunks until complete or error */ /* receive socks answer */ do { - result = Read(xfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes); + result = Read(sfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes); } while (result < 0 && errno == EINTR); if (result < 0) { Msg4(level, "read(%d, %p, "F_Zu"): %s", - xfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes, + sfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes, strerror(errno)); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } } if (result == 0) { Msg(level, "read(): EOF during read of socks reply, peer might not be a socks4 server"); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } return STAT_RETRYLATER; } @@ -431,9 +433,9 @@ int _xioopen_socks4_connect(struct single *xfd, case SOCKS_CD_GRANTED: /* Notice("socks: connect request succeeded"); */ #if 0 - if (Getsockname(xfd->fd, (struct sockaddr *)&us, &uslen) < 0) { + if (Getsockname(sfd->fd, (struct sockaddr *)&us, &uslen) < 0) { Warn4("getsockname(%d, %p, {%d}): %s", - xfd->fd, &us, uslen, strerror(errno)); + sfd->fd, &us, uslen, strerror(errno)); } Notice1("successfully connected from %s via socks4", sockaddr_info((struct sockaddr *)&us, infobuff, sizeof(infobuff))); diff --git a/xio-socks5.c b/xio-socks5.c index 4f78b96..b0d9d01 100644 --- a/xio-socks5.c +++ b/xio-socks5.c @@ -48,10 +48,7 @@ #define SOCKS5_STATUS_COMMAND_NOT_SUPPORTED 7 #define SOCKS5_STATUS_ADDRESS_TYPE_NOT_SUPPORTED 8 -static int xioopen_socks5(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, - groups_t groups, int dummy1, int dummy2, - int dummy3); +static int xioopen_socks5(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc); const struct addrdesc xioaddr_socks5_connect = { "SOCKS5-CONNECT", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_CONNECT, 0, 0 HELP("::::") }; @@ -92,7 +89,7 @@ static const char * _xioopen_socks5_strerror(uint8_t r) * send(0x050100) followed by "return read() == 0x0500", but will be easier to * extend for other auth mode support. */ -static int _xioopen_socks5_handshake(struct single *xfd, int level) +static int _xioopen_socks5_handshake(struct single *sfd, int level) { int result; ssize_t bytes; @@ -106,8 +103,8 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level) if (client_hello == NULL) { Msg2(level, "malloc(%d): %s", client_hello_size, strerror(errno)); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } /* malloc failed - could succeed later, so retry then */ @@ -138,12 +135,12 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level) } #endif - if (writefull(xfd->fd, client_hello, client_hello_size) < 0) { + if (writefull(sfd->fd, client_hello, client_hello_size) < 0) { Msg4(level, "write(%d, %p, %d): %s", - xfd->fd, client_hello, client_hello_size, + sfd->fd, client_hello, client_hello_size, strerror(errno)); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } free(client_hello); @@ -156,22 +153,22 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level) Info("waiting for socks5 reply"); while (bytes >= 0) { do { - result = Read(xfd->fd, server_hello_ptr + bytes, + result = Read(sfd->fd, server_hello_ptr + bytes, sizeof(struct socks5_server_hello)-bytes); } while (result < 0 && errno == EINTR); if (result < 0) { Msg4(level, "read(%d, %p, "F_Zu"): %s", - xfd->fd, server_hello_ptr + bytes, + sfd->fd, server_hello_ptr + bytes, sizeof(struct socks5_server_hello)-bytes, strerror(errno)); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } } if (result == 0) { Msg(level, "read(): EOF during read of SOCKS5 server hello, peer might not be a SOCKS5 server"); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } @@ -197,16 +194,16 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level) if (server_hello.version != SOCKS5_VERSION) { Msg2(level, "SOCKS5 Server Hello version was %d, not the expected %d, peer might not be a SOCKS5 server", server_hello.version, SOCKS5_VERSION); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } return STAT_RETRYLATER; } if (server_hello.method == SOCKS5_AUTH_FAIL) { Msg(level, "SOCKS5 authentication negotiation failed - client & server have no common supported methods"); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } return STAT_RETRYLATER; } @@ -214,8 +211,8 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level) if (server_hello.method != SOCKS5_AUTH_NONE) { Msg1(level, "SOCKS5 server requested unsupported auth method (%d)", server_hello.method); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } return STAT_RETRYLATER; } @@ -303,7 +300,7 @@ static struct socks5_request *_xioopen_socks5_prepare_request( * Reads a server reply after a request has been sent */ static int _xioopen_socks5_read_reply( - struct single *xfd, struct socks5_reply *reply, int level) + struct single *sfd, struct socks5_reply *reply, int level) { int result = 0; int bytes_read = 0; @@ -313,24 +310,24 @@ static int _xioopen_socks5_read_reply( while (bytes_to_read >= 0) { Info("reading SOCKS5 reply"); do { - result = Read(xfd->fd, + result = Read(sfd->fd, ((unsigned char *)reply) + bytes_read, bytes_to_read-bytes_read); } while (result < 0 && errno == EINTR); if (result < 0) { Msg4(level, "read(%d, %p, %d): %s", - xfd->fd, ((unsigned char *)reply) + bytes_read, + sfd->fd, ((unsigned char *)reply) + bytes_read, bytes_to_read-bytes_read, strerror(errno)); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } return STAT_RETRYLATER; } if (result == 0) { Msg(level, "read(): EOF during read of SOCKS5 reply"); - if (Close(xfd->fd) < 0) { + if (Close(sfd->fd) < 0) { Info2("close(%d): %s", - xfd->fd, strerror(errno)); + sfd->fd, strerror(errno)); } return STAT_RETRYLATER; } @@ -356,9 +353,9 @@ static int _xioopen_socks5_read_reply( default: Msg1(level, "invalid SOCKS5 reply address type (%d)", reply->address_type); - if (Close(xfd->fd) < 0) { + if (Close(sfd->fd) < 0) { Info2("close(%d): %s", - xfd->fd, strerror(errno)); + sfd->fd, strerror(errno)); } return STAT_RETRYLATER; } @@ -388,7 +385,7 @@ static int _xioopen_socks5_read_reply( * If command is BIND we receive two replies. */ static int _xioopen_socks5_request( - struct single *xfd, const char *target_name, const char *target_port, + struct single *sfd, const char *target_name, const char *target_port, uint8_t socks_command, int level) { struct socks5_request *req; @@ -397,8 +394,8 @@ static int _xioopen_socks5_request( req = _xioopen_socks5_prepare_request(&bytes, target_name, target_port, socks_command, level); if (req == NULL) { - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } /* Prepare_request could fail due to malloc, but most likely @@ -420,11 +417,11 @@ static int _xioopen_socks5_request( } #endif - if (writefull(xfd->fd, req, bytes) < 0) { + if (writefull(sfd->fd, req, bytes) < 0) { Msg4(level, "write(%d, %p, %d): %s", - xfd->fd, req, bytes, strerror(errno)); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + sfd->fd, req, bytes, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } free(req); return STAT_RETRYLATER; @@ -434,14 +431,14 @@ static int _xioopen_socks5_request( struct socks5_reply *reply = Malloc(SOCKS5_MAX_REPLY_SIZE); if (reply == NULL) { - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } return STAT_RETRYLATER; } - result = _xioopen_socks5_read_reply(xfd, reply, level); + result = _xioopen_socks5_read_reply(sfd, reply, level); if (result != STAT_OK) { free(reply); return result; @@ -454,8 +451,8 @@ static int _xioopen_socks5_request( if (reply->version != SOCKS5_VERSION) { Msg2(level, "SOCKS5 reply version was %d, not the expected %d, peer might not be a SOCKS5 server", reply->version, SOCKS5_VERSION); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } free(reply); return STAT_RETRYLATER; @@ -466,7 +463,7 @@ static int _xioopen_socks5_request( Notice("listening on remote host, waiting for connection"); /* TODO: nicer debug output */ /* For BIND, we read two replies */ - result = _xioopen_socks5_read_reply(xfd, reply, level); + result = _xioopen_socks5_read_reply(sfd, reply, level); if (result != STAT_OK) { free(reply); return result; @@ -484,8 +481,8 @@ static int _xioopen_socks5_request( Msg2(level, "SOCKS5 server error %d: %s", reply->reply, _xioopen_socks5_strerror(reply->reply)); - if (Close(xfd->fd) < 0) { - Info2("close(%d): %s", xfd->fd, strerror(errno)); + if (Close(sfd->fd) < 0) { + Info2("close(%d): %s", sfd->fd, strerror(errno)); } free(reply); return STAT_RETRYLATER; @@ -497,17 +494,21 @@ static int _xioopen_socks5_request( /* Same function for all socks5-modes, determined by argv[0] */ static int xioopen_socks5( - int argc, const char *argv[], struct opt *opts, int xioflags, - xiofile_t *xxfd, groups_t groups, int socks_command, int dummy2, - int dummy3) + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) { + int socks_command = addrdesc->arg1; bool dofork = false; int socktype = SOCK_STREAM; int pf = PF_UNSPEC; int ipproto = IPPROTO_TCP; int level, result; struct opt *opts0 = NULL; - struct single *xfd = &xxfd->stream; + struct single *sfd = &xxfd->stream; const char *socks_server, *target_name, *target_port, *socks_port; union sockaddr_union us_sa, *us = &us_sa; socklen_t uslen = sizeof(us_sa); @@ -521,14 +522,7 @@ static int xioopen_socks5( return STAT_NORETRY; } if (argc != 5) { -#if WITH_HELP - Error2("%s: 4 parameters required like %s", argv[0], - socks_command==SOCKS5_COMMAND_CONNECT ? - xioaddr_socks5_connect.syntax : - xioaddr_socks5_listen.syntax); -#else - Error1("%s: 4 parameters required", argv[0]); -#endif + xio_syntax(argv[0], 4, argc-1, addrdesc->syntax); return STAT_NORETRY; } @@ -537,16 +531,16 @@ static int xioopen_socks5( target_name = argv[3]; target_port = argv[4]; - xfd->howtoend = END_SHUTDOWN; - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; - applyopts(xfd, -1, opts, PH_INIT); + sfd->howtoend = END_SHUTDOWN; + if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; + applyopts(sfd, -1, opts, PH_INIT); retropt_int(opts, OPT_SO_TYPE, &socktype); retropt_bool(opts, OPT_FORK, &dofork); result = _xioopen_ipapp_prepare(opts, &opts0, socks_server, socks_port, &pf, ipproto, - xfd->para.socket.ip.ai_flags, + sfd->para.socket.ip.ai_flags, &themlist, us, &uslen, &needbind, &lowport, socktype); @@ -555,7 +549,7 @@ static int xioopen_socks5( do { #if WITH_RETRY - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { level = E_INFO; } else { level = E_ERROR; @@ -568,7 +562,7 @@ static int xioopen_socks5( Notice1("opening connection to %s", sockaddr_info(themp->ai_addr, themp->ai_addrlen, infobuff, sizeof(infobuff))); - result = _xioopen_connect(xfd, needbind?us:NULL, sizeof(*us), + result = _xioopen_connect(sfd, needbind?us:NULL, sizeof(*us), themp->ai_addr, themp->ai_addrlen, opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, lowport, level); @@ -583,8 +577,8 @@ static int xioopen_socks5( #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (xfd->forever || xfd->retry-- ) { - if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL); + if (sfd->forever || sfd->retry-- ) { + if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); continue; } #endif @@ -594,24 +588,24 @@ static int xioopen_socks5( } } xiofreeaddrinfo(themlist); - applyopts(xfd, -1, opts, PH_ALL); + applyopts(sfd, -1, opts, PH_ALL); - if ((result = _xio_openlate(xfd, opts)) < 0) + if ((result = _xio_openlate(sfd, opts)) < 0) return result; - if ((result = _xioopen_socks5_handshake(xfd, level)) != STAT_OK) { + if ((result = _xioopen_socks5_handshake(sfd, level)) != STAT_OK) { return result; } - result = _xioopen_socks5_request(xfd, target_name, target_port, socks_command, level); + result = _xioopen_socks5_request(sfd, target_name, target_port, socks_command, level); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if ( xfd->forever || xfd->retry-- ) { - if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL); + if ( sfd->forever || sfd->retry-- ) { + if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); continue; } #endif @@ -627,24 +621,24 @@ static int xioopen_socks5( if (dofork) { pid_t pid; int level = E_ERROR; - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { level = E_WARN; } - while ((pid = xio_fork(false, level, xfd->shutup)) < 0) { - if (xfd->forever || --xfd->retry) { - Nanosleep(&xfd->intervall, NULL); + while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { + if (sfd->forever || --sfd->retry) { + Nanosleep(&sfd->intervall, NULL); continue; } return STAT_RETRYLATER; } if ( pid == 0 ) { - xfd->forever = false; - xfd->retry = 0; + sfd->forever = false; + sfd->retry = 0; break; } - Close(xfd->fd); - Nanosleep(&xfd->intervall, NULL); + Close(sfd->fd); + Nanosleep(&sfd->intervall, NULL); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); continue; diff --git a/xio-stdio.c b/xio-stdio.c index 92bbb93..1cd123c 100644 --- a/xio-stdio.c +++ b/xio-stdio.c @@ -13,8 +13,8 @@ #if WITH_STDIO -static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3); -static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int fd, int dummy2, int dummy3); +static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); +static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); /* we specify all option groups that we can imagine for a FD, becasue the @@ -135,7 +135,14 @@ int xioopen_stdio_bi(xiofile_t *sock) { /* wrap around unidirectional xioopensingle and xioopen_fd to automatically determine stdin or stdout fd depending on rw. Do not set FD_CLOEXEC flag. */ -static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3) { +static int xioopen_stdio( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *fd, + const struct addrdesc *addrdesc) +{ int rw = (xioflags&XIO_ACCMODE); if (argc != 1) { @@ -149,13 +156,21 @@ static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xio Notice2("using %s for %s", &("stdin\0\0\0stdout"[rw<<3]), ddirection[rw]); - return xioopen_fd(opts, rw, &fd->stream, rw, dummy2, dummy3); + return xioopen_fd(opts, rw, &fd->stream, rw); } /* wrap around unidirectional xioopensingle and xioopen_fd to automatically determine stdin or stdout fd depending on rw. Do not set FD_CLOEXEC flag. */ -static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int fd, int dummy2, int dummy3) { +static int xioopen_stdfd( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ int rw = (xioflags&XIO_ACCMODE); + int fd = addrdesc->arg1; if (argc != 1) { Error2("%s: wrong number of parameters (%d instead of 0)", argv[0], argc-1); @@ -163,6 +178,6 @@ static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xio Notice2("using %s for %s", &("stdin\0\0\0stdout\0\0stderr"[fd<<3]), ddirection[rw]); - return xioopen_fd(opts, rw, &xfd->stream, fd, dummy2, dummy3); + return xioopen_fd(opts, rw, &xfd->stream, fd); } #endif /* WITH_STDIO */ diff --git a/xio-system.c b/xio-system.c index e9f6b9e..ebe1bfb 100644 --- a/xio-system.c +++ b/xio-system.c @@ -13,22 +13,19 @@ #if WITH_SYSTEM -static int xioopen_system(int arg, const char *argv[], struct opt *opts, - int xioflags, /* XIO_RDONLY etc. */ - xiofile_t *fd, - groups_t groups, - int dummy1, int dummy2, int dummy3 - ); +static int xioopen_system(int arg, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); const struct addrdesc xioaddr_system = { "SYSTEM", 3, xioopen_system, GROUP_FD|GROUP_FORK|GROUP_EXEC|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_TERMIOS|GROUP_FIFO|GROUP_PTY|GROUP_PARENT, 1, 0, 0 HELP(":") }; -static int xioopen_system(int argc, const char *argv[], struct opt *opts, - int xioflags, /* XIO_RDONLY etc. */ - xiofile_t *xfd, - groups_t groups, - int dummy1, int dummy2, int dummy3 - ) { +static int xioopen_system( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, /* XIO_RDONLY etc. */ + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ struct single *sfd = &xfd->stream; int status; char *path = NULL; @@ -36,7 +33,13 @@ static int xioopen_system(int argc, const char *argv[], struct opt *opts, int result; const char *string = argv[1]; - status = _xioopen_foxec(xioflags, sfd, groups, &opts, &duptostderr); + if (argc != 2) { + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); + return STAT_NORETRY; + } + + status = + _xioopen_foxec(xioflags, sfd, addrdesc->groups, &opts, &duptostderr); if (status < 0) return status; if (status == 0) { /* child */ diff --git a/xio-tcpwrap.c b/xio-tcpwrap.c index 8b2fe5c..26a3a1f 100644 --- a/xio-tcpwrap.c +++ b/xio-tcpwrap.c @@ -32,42 +32,44 @@ int allow_severity=10, deny_severity=10; /* returns 0 if option was found and could be applied returns 1 if option was not found returns -1 if option was found but failed */ -int xio_retropt_tcpwrap(xiosingle_t *xfd, struct opt *opts) { +int xio_retropt_tcpwrap( + struct single *sfd, + struct opt *opts) { bool dolibwrap = false; dolibwrap = retropt_string(opts, OPT_TCPWRAPPERS, - &xfd->para.socket.ip.libwrapname) >= 0 || dolibwrap; + &sfd->para.socket.ip.libwrapname) >= 0 || dolibwrap; dolibwrap = retropt_string(opts, OPT_TCPWRAP_ETC, - &xfd->para.socket.ip.tcpwrap_etc) >= 0 || dolibwrap; + &sfd->para.socket.ip.tcpwrap_etc) >= 0 || dolibwrap; #if defined(HAVE_HOSTS_ALLOW_TABLE) dolibwrap = retropt_string(opts, OPT_TCPWRAP_HOSTS_ALLOW_TABLE, - &xfd->para.socket.ip.hosts_allow_table) >= 0 || dolibwrap; + &sfd->para.socket.ip.hosts_allow_table) >= 0 || dolibwrap; #endif #if defined(HAVE_HOSTS_DENY_TABLE) dolibwrap = retropt_string(opts, OPT_TCPWRAP_HOSTS_DENY_TABLE, - &xfd->para.socket.ip.hosts_deny_table) >= 0 || dolibwrap; + &sfd->para.socket.ip.hosts_deny_table) >= 0 || dolibwrap; #endif if (dolibwrap) { - xfd->para.socket.ip.dolibwrap = true; - if (xfd->para.socket.ip.libwrapname == NULL) { - xfd->para.socket.ip.libwrapname = (char *)diag_get_string('p'); + sfd->para.socket.ip.dolibwrap = true; + if (sfd->para.socket.ip.libwrapname == NULL) { + sfd->para.socket.ip.libwrapname = (char *)diag_get_string('p'); } #if defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE) - if (xfd->para.socket.ip.tcpwrap_etc) { - if (xfd->para.socket.ip.hosts_allow_table == NULL) { - xfd->para.socket.ip.hosts_allow_table = - Malloc(strlen(xfd->para.socket.ip.tcpwrap_etc)+1+11+1); - sprintf(xfd->para.socket.ip.hosts_allow_table, "%s/hosts.allow", - xfd->para.socket.ip.tcpwrap_etc); + if (sfd->para.socket.ip.tcpwrap_etc) { + if (sfd->para.socket.ip.hosts_allow_table == NULL) { + sfd->para.socket.ip.hosts_allow_table = + Malloc(strlen(sfd->para.socket.ip.tcpwrap_etc)+1+11+1); + sprintf(sfd->para.socket.ip.hosts_allow_table, "%s/hosts.allow", + sfd->para.socket.ip.tcpwrap_etc); } - if (xfd->para.socket.ip.hosts_deny_table == NULL) { - xfd->para.socket.ip.hosts_deny_table = - Malloc(strlen(xfd->para.socket.ip.tcpwrap_etc)+1+10+1); - sprintf(xfd->para.socket.ip.hosts_deny_table, "%s/hosts.deny", - xfd->para.socket.ip.tcpwrap_etc); + if (sfd->para.socket.ip.hosts_deny_table == NULL) { + sfd->para.socket.ip.hosts_deny_table = + Malloc(strlen(sfd->para.socket.ip.tcpwrap_etc)+1+10+1); + sprintf(sfd->para.socket.ip.hosts_deny_table, "%s/hosts.deny", + sfd->para.socket.ip.tcpwrap_etc); } } #endif /* defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE) */ @@ -79,8 +81,10 @@ int xio_retropt_tcpwrap(xiosingle_t *xfd, struct opt *opts) { /* returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitely allowed */ -int xio_tcpwrap_check(xiosingle_t *xfd, union sockaddr_union *us, - union sockaddr_union *them) { +int xio_tcpwrap_check( + struct single *sfd, + union sockaddr_union *us, + union sockaddr_union *them) { char *save_hosts_allow_table, *save_hosts_deny_table; struct request_info ri; #if WITH_IP6 @@ -90,25 +94,25 @@ int xio_tcpwrap_check(xiosingle_t *xfd, union sockaddr_union *us, #endif int allow; - if (!xfd->para.socket.ip.dolibwrap) { + if (!sfd->para.socket.ip.dolibwrap) { return 0; } if (us == NULL || them == NULL) { return -1; } #if defined(HAVE_HOSTS_ALLOW_TABLE) save_hosts_allow_table = hosts_allow_table; - if (xfd->para.socket.ip.hosts_allow_table) { + if (sfd->para.socket.ip.hosts_allow_table) { Debug1("hosts_allow_table = \"%s\"", - xfd->para.socket.ip.hosts_allow_table); - hosts_allow_table = xfd->para.socket.ip.hosts_allow_table; + sfd->para.socket.ip.hosts_allow_table); + hosts_allow_table = sfd->para.socket.ip.hosts_allow_table; } #endif /* defined(HAVE_HOSTS_ALLOW_TABLE) */ #if defined(HAVE_HOSTS_DENY_TABLE) save_hosts_deny_table = hosts_deny_table; - if (xfd->para.socket.ip.hosts_deny_table) { + if (sfd->para.socket.ip.hosts_deny_table) { Debug1("hosts_deny_table = \"%s\"", - xfd->para.socket.ip.hosts_deny_table); - hosts_deny_table = xfd->para.socket.ip.hosts_deny_table; + sfd->para.socket.ip.hosts_deny_table); + hosts_deny_table = sfd->para.socket.ip.hosts_deny_table; } #endif /* defined(HAVE_HOSTS_DENY_TABLE) */ @@ -132,14 +136,14 @@ int xio_tcpwrap_check(xiosingle_t *xfd, union sockaddr_union *us, Warn1("inet_ntop(): %s", strerror(errno)); } Debug7("request_init(%p, RQ_FILE, %d, RQ_CLIENT_SIN, {%s:%u}, RQ_SERVER_SIN, {%s:%u}, RQ_DAEMON, \"%s\", 0", - &ri, xfd->fd, clientaddr, + &ri, sfd->fd, clientaddr, ntohs(((struct sockaddr_in *)them)->sin_port), serveraddr, ntohs(us->ip4.sin_port), - xfd->para.socket.ip.libwrapname?xfd->para.socket.ip.libwrapname:(char *)diag_get_string('p')); - request_init(&ri, RQ_FILE, xfd->fd, + sfd->para.socket.ip.libwrapname?sfd->para.socket.ip.libwrapname:(char *)diag_get_string('p')); + request_init(&ri, RQ_FILE, sfd->fd, RQ_CLIENT_SIN, them, RQ_SERVER_SIN, &us->soa, - RQ_DAEMON, xfd->para.socket.ip.libwrapname?xfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'), 0); + RQ_DAEMON, sfd->para.socket.ip.libwrapname?sfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'), 0); Debug("request_init() ->"); Debug1("sock_methods(%p)", &ri); diff --git a/xio-tun.c b/xio-tun.c index 4dc3bb6..9aee6e3 100644 --- a/xio-tun.c +++ b/xio-tun.c @@ -16,7 +16,7 @@ #include "xio-tun.h" -static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3); +static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); /****** TUN options ******/ const struct optdesc opt_tun_device = { "tun-device", NULL, OPT_TUN_DEVICE, GROUP_TUN, PH_OPEN, TYPE_FILENAME, OFUNC_SPEC }; @@ -45,7 +45,14 @@ static const struct optname xio_route_options[] = { } ; #endif -static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) { +static int xioopen_tun( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ struct single *sfd = &xfd->stream; char *tundevice = NULL; char *tunname = NULL, *tuntype = NULL; @@ -61,8 +68,13 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl int result; if (argc > 2 || argc < 0) { +#if WITH_HELP + Error3("%s: wrong number of parameters (%d instead of 0 or 1); usage: %s", + argv[0], argc-1, addrdesc->syntax); +#else Error2("%s: wrong number of parameters (%d instead of 0 or 1)", argv[0], argc-1); +#endif } if (retropt_string(opts, OPT_TUN_DEVICE, &tundevice) != 0) { @@ -74,7 +86,8 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl namedargv[1] = tundevice; /* open the tun cloning device */ - if ((result = _xioopen_named_early(2, namedargv, xfd, groups, &exists, opts)) < 0) { + if ((result = _xioopen_named_early(2, namedargv, xfd, addrdesc->groups, + &exists, opts, addrdesc->syntax)) < 0) { return result; } diff --git a/xio-udp.c b/xio-udp.c index 8c75ba9..eb3db58 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -19,22 +19,10 @@ #include "xio-udp.h" -static -int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int pf, int socktype, int ipproto); -static -int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int pf, int socktype, int ipproto); -static -int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int pf, int socktype, int ipproto); -static -int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int pf, int socktype, int ipproto); +static int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); +static int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); +static int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); +static int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); static int _xioopen_udp_sendto(const char *hostname, const char *servname, @@ -283,18 +271,25 @@ int _xioopen_ipdgram_listen(struct single *sfd, } /* we expect the form: port */ -int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, - groups_t groups, int pf, int ipproto, - int protname) { +int xioopen_ipdgram_listen( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ struct single *sfd = &xfd->stream; const char *portname = argv[1]; + int pf = addrdesc->arg1; + int ipproto = addrdesc->arg2; union sockaddr_union us; int socktype = SOCK_DGRAM; socklen_t uslen; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); + return STAT_NORETRY; } xioinit_ip(&pf, xioparms.default_ip); @@ -342,21 +337,27 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, opts, pf, socktype, ipproto); } -static -int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int pf, int socktype, int ipproto) { +static int xioopen_udp_sendto( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ + int pf = addrdesc->arg1; + int socktype = addrdesc->arg2; + int ipproto = addrdesc->arg3; int result; if (argc != 3) { - Error2("%s: wrong number of parameters (%d instead of 2)", - argv[0], argc-1); + xio_syntax(argv[0], 2, argc-1, addrdesc->syntax); return STAT_NORETRY; } retropt_socket_pf(opts, &pf); if ((result = _xioopen_udp_sendto(argv[1], argv[2], opts, xioflags, xfd, - groups, pf, socktype, ipproto)) + addrdesc->groups, pf, socktype, ipproto)) != STAT_OK) { return result; } @@ -375,75 +376,83 @@ int _xioopen_udp_sendto(const char *hostname, const char *servname, struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int pf, int socktype, int ipproto) { - xiosingle_t *xfd = &xxfd->stream; + struct single *sfd = &xxfd->stream; union sockaddr_union us; socklen_t uslen; int feats = 3; /* option bind supports address and port */ bool needbind = false; int result; - xfd->howtoend = END_SHUTDOWN; + sfd->howtoend = END_SHUTDOWN; - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; - applyopts(xfd, -1, opts, PH_INIT); + /* ...res_opts[] */ + if (applyopts_single(sfd, opts, PH_INIT) < 0) + return -1; + applyopts(sfd, -1, opts, PH_INIT); - xfd->salen = sizeof(xfd->peersa); + sfd->salen = sizeof(sfd->peersa); if ((result = xioresolve(hostname, servname, pf, socktype, ipproto, - &xfd->peersa, &xfd->salen, - xfd->para.socket.ip.ai_flags)) + &sfd->peersa, &sfd->salen, + sfd->para.socket.ip.ai_flags)) != STAT_OK) { return result; } if (pf == PF_UNSPEC) { - pf = xfd->peersa.soa.sa_family; + pf = sfd->peersa.soa.sa_family; } uslen = socket_init(pf, &us); if (retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, feats, - xfd->para.socket.ip.ai_flags) + sfd->para.socket.ip.ai_flags) != STAT_NOACTION) { needbind = true; } if (retropt_ushort(opts, OPT_SOURCEPORT, - &xfd->para.socket.ip.sourceport) >= 0) { + &sfd->para.socket.ip.sourceport) >= 0) { switch (pf) { #if WITH_IP4 case PF_INET: - us.ip4.sin_port = htons(xfd->para.socket.ip.sourceport); + us.ip4.sin_port = htons(sfd->para.socket.ip.sourceport); break; #endif #if WITH_IP6 case PF_INET6: - us.ip6.sin6_port = htons(xfd->para.socket.ip.sourceport); + us.ip6.sin6_port = htons(sfd->para.socket.ip.sourceport); break; #endif } needbind = true; } - retropt_bool(opts, OPT_LOWPORT, &xfd->para.socket.ip.lowport); + retropt_bool(opts, OPT_LOWPORT, &sfd->para.socket.ip.lowport); - xfd->dtype = XIODATA_RECVFROM; + sfd->dtype = XIODATA_RECVFROM; return _xioopen_dgram_sendto(needbind?&us:NULL, uslen, - opts, xioflags, xfd, groups, + opts, xioflags, sfd, groups, pf, socktype, ipproto, - xfd->para.socket.ip.lowport); + sfd->para.socket.ip.lowport); } -static -int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int pf, int socktype, int ipproto) { - xiosingle_t *xfd = &xxfd->stream; +static int xioopen_udp_datagram( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ + struct single *sfd = &xxfd->stream; + int pf = addrdesc->arg1; + int socktype = addrdesc->arg2; + int ipproto = addrdesc->arg3; char *rangename; char *hostname; int result; if (argc != 3) { - Error2("%s: wrong number of parameters (%d instead of 2)", - argv[0], argc-1); + xio_syntax(argv[0], 2, argc-1, addrdesc->syntax); return STAT_NORETRY; } @@ -453,65 +462,71 @@ int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts, } /* only accept packets with correct remote ports */ - if (retropt_ushort(opts, OPT_SOURCEPORT, &xfd->para.socket.ip.sourceport) + if (retropt_ushort(opts, OPT_SOURCEPORT, &sfd->para.socket.ip.sourceport) >= 0) { - xfd->para.socket.ip.dosourceport = true; - xfd->para.socket.ip.sourceport = ntohs(xfd->peersa.ip4.sin_port); + sfd->para.socket.ip.dosourceport = true; + sfd->para.socket.ip.sourceport = ntohs(sfd->peersa.ip4.sin_port); } retropt_socket_pf(opts, &pf); result = - _xioopen_udp_sendto(hostname, argv[2], opts, xioflags, xxfd, groups, - pf, socktype, ipproto); + _xioopen_udp_sendto(hostname, argv[2], opts, xioflags, xxfd, + addrdesc->groups, pf, socktype, ipproto); free(hostname); if (result != STAT_OK) { return result; } - xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; + sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; - xfd->para.socket.la.soa.sa_family = xfd->peersa.soa.sa_family; + sfd->para.socket.la.soa.sa_family = sfd->peersa.soa.sa_family; /* which reply packets will be accepted - determine by range option */ - if (retropt_string(opts, OPT_RANGE, &rangename) - >= 0) { - if (xioparserange(rangename, pf, &xfd->para.socket.range, - xfd->para.socket.ip.ai_flags) + if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { + if (xioparserange(rangename, pf, &sfd->para.socket.range, + sfd->para.socket.ip.ai_flags) < 0) { free(rangename); return STAT_NORETRY; } - xfd->para.socket.dorange = true; - xfd->dtype |= XIOREAD_RECV_CHECKRANGE; + sfd->para.socket.dorange = true; + sfd->dtype |= XIOREAD_RECV_CHECKRANGE; free(rangename); } #if WITH_LIBWRAP - xio_retropt_tcpwrap(xfd, opts); + xio_retropt_tcpwrap(sfd, opts); #endif /* WITH_LIBWRAP */ - _xio_openlate(xfd, opts); + _xio_openlate(sfd, opts); return STAT_OK; } -static -int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int pf, int socktype, int ipproto) { +static int xioopen_udp_recvfrom( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ + struct single *sfd = &xfd->stream; + int pf = addrdesc->arg1; + int socktype = addrdesc->arg2; + int ipproto = addrdesc->arg3; union sockaddr_union us; socklen_t uslen = sizeof(us); int ai_flags2[2]; int result; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } xioinit_ip(&pf, xioparms.default_ip); - xfd->stream.howtoend = END_NONE; + sfd->howtoend = END_NONE; retropt_socket_pf(opts, &pf); if (pf == PF_UNSPEC) { #if WITH_IP4 && WITH_IP6 @@ -548,7 +563,7 @@ int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts, socklen_t lalen = sizeof(la); if (retropt_bind(opts, pf, socktype, ipproto, &la.soa, &lalen, 1, - xfd->stream.para.socket.ip.ai_flags) + sfd->para.socket.ip.ai_flags) != STAT_NOACTION) { switch (pf) { #if WITH_IP4 @@ -561,14 +576,14 @@ int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts, } } - if (retropt_ushort(opts, OPT_SOURCEPORT, &xfd->stream.para.socket.ip.sourceport) >= 0) { - xfd->stream.para.socket.ip.dosourceport = true; + if (retropt_ushort(opts, OPT_SOURCEPORT, &sfd->para.socket.ip.sourceport) >= 0) { + sfd->para.socket.ip.dosourceport = true; } - retropt_bool(opts, OPT_LOWPORT, &xfd->stream.para.socket.ip.lowport); + retropt_bool(opts, OPT_LOWPORT, &sfd->para.socket.ip.lowport); xfd->stream.dtype = XIODATA_RECVFROM_ONE; if ((result = - _xioopen_dgram_recvfrom(&xfd->stream, xioflags, &us.soa, uslen, + _xioopen_dgram_recvfrom(sfd, xioflags, &us.soa, uslen, opts, pf, socktype, ipproto, E_ERROR)) != STAT_OK) { return result; @@ -578,10 +593,17 @@ int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts, } -static -int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, groups_t groups, - int pf, int socktype, int ipproto) { +static int xioopen_udp_recv( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xfd, + const struct addrdesc *addrdesc) +{ + int pf = addrdesc->arg1; + int socktype = addrdesc->arg2; + int ipproto = addrdesc->arg3; union sockaddr_union us; socklen_t uslen = sizeof(us); char *rangename; @@ -589,8 +611,7 @@ int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts, int result; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } diff --git a/xio-udp.h b/xio-udp.h index 027b140..e8058d4 100644 --- a/xio-udp.h +++ b/xio-udp.h @@ -28,9 +28,6 @@ extern int _xioopen_ipdgram_listen(struct single *sfd, int xioflags, union sockaddr_union *us, socklen_t uslen, struct opt *opts, int pf, int socktype, int ipproto); -extern int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, - int rw, xiofile_t *fd, - groups_t groups, int af, int ipproto, - int protname); +extern int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *xfd, const struct addrdesc *addrdesc); #endif /* !defined(__xio_udp_h_included) */ diff --git a/xio-unix.c b/xio-unix.c index 453c592..4d7dfad 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -24,16 +24,12 @@ # define ABSTRACT 0 #endif -static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3); -static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3); -static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3); -static int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3); -static -int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int abstract, int dummy2, int dummy3); -static -int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3); +static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc); +static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc); +static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc); +static int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc); +static int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc); +static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc); /* the first free parameter is 0 for "normal" unix domain sockets, or 1 for abstract unix sockets (Linux); the second and third free parameter are @@ -115,10 +111,17 @@ xiosetunix(int pf, } #if WITH_LISTEN -static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3) { +static int xioopen_unix_listen( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ /* we expect the form: filename */ const char *name; - xiosingle_t *xfd = &xxfd->stream; + xiosingle_t *sfd = &xxfd->stream; int pf = PF_UNIX; int socktype = SOCK_STREAM; int protocol = 0; @@ -127,35 +130,35 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i struct opt *opts0 = NULL; pid_t pid = Getpid(); bool opt_unlink_early = false; - bool opt_unlink_close = (abstract != 1); + bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1); int result; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } name = argv[1]; - xfd->para.socket.un.tight = true; + sfd->para.socket.un.tight = true; retropt_socket_pf(opts, &pf); - xfd->howtoend = END_SHUTDOWN; + sfd->howtoend = END_SHUTDOWN; - if (!(ABSTRACT && abstract)) { + if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) { /* only for non abstract because abstract do not work in file system */ retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); } - if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY; - applyopts(xfd, -1, opts, PH_INIT); + if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY; + applyopts(sfd, -1, opts, PH_INIT); applyopts_named(name, opts, PH_EARLY); /* umask! */ - applyopts_offset(xfd, opts); - applyopts(xfd, -1, opts, PH_EARLY); + applyopts_offset(sfd, opts); + applyopts(sfd, -1, opts, PH_EARLY); - uslen = xiosetunix(pf, &us, name, abstract, xfd->para.socket.un.tight); + uslen = xiosetunix(pf, &us, name, addrdesc->arg1/*abstract*/, + sfd->para.socket.un.tight); - if (!(ABSTRACT && abstract)) { + if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) { if (opt_unlink_early) { xio_unlink(name, E_ERROR); } else { @@ -166,10 +169,10 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i } } if (opt_unlink_close) { - if ((xfd->unlink_close = strdup(name)) == NULL) { + if ((sfd->unlink_close = strdup(name)) == NULL) { Error1("strdup(\"%s\"): out of memory", name); } - xfd->opt_unlink_close = true; + sfd->opt_unlink_close = true; } /* trying to set user-early, perm-early etc. here is useless because @@ -180,17 +183,17 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i /* this may fork() */ if ((result = - xioopen_listen(xfd, xioflags, + xioopen_listen(sfd, xioflags, (struct sockaddr *)&us, uslen, opts, opts0, pf, socktype, protocol)) != 0) return result; - if (!(ABSTRACT && abstract)) { + if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) { if (opt_unlink_close) { if (pid != Getpid()) { /* in a child process - do not unlink-close here! */ - xfd->opt_unlink_close = false; + sfd->opt_unlink_close = false; } } } @@ -200,10 +203,17 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i #endif /* WITH_LISTEN */ -static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3) { +static int xioopen_unix_connect( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ /* we expect the form: filename */ const char *name; - struct single *xfd = &xxfd->stream; + struct single *sfd = &xxfd->stream; const struct opt *namedopt; int pf = PF_UNIX; int socktype = SOCK_STREAM; @@ -211,7 +221,7 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, struct sockaddr_un them, us; socklen_t themlen, uslen = sizeof(us); bool needbind = false; - bool opt_unlink_close = (abstract != 1); + bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1); bool dofork = false; struct opt *opts0; char infobuff[256]; @@ -219,29 +229,30 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int result; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } name = argv[1]; - xfd->para.socket.un.tight = true; + sfd->para.socket.un.tight = true; retropt_socket_pf(opts, &pf); - xfd->howtoend = END_SHUTDOWN; - if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY; - applyopts(xfd, -1, opts, PH_INIT); - applyopts_offset(xfd, opts); - applyopts(xfd, -1, opts, PH_EARLY); + sfd->howtoend = END_SHUTDOWN; + if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY; + applyopts(sfd, -1, opts, PH_INIT); + applyopts_offset(sfd, opts); + applyopts(sfd, -1, opts, PH_EARLY); - themlen = xiosetunix(pf, &them, name, abstract, xfd->para.socket.un.tight); + themlen = xiosetunix(pf, &them, name, addrdesc->arg1/*abstract*/, + sfd->para.socket.un.tight); - if (!(ABSTRACT && abstract)) { - /* only for non abstract because abstract do not work in file system */ + if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) { + /* Only for non abstract because abstract do not work in file system */ retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); } if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen, - (abstract<<1)|xfd->para.socket.un.tight, NULL) - == STAT_OK) { + (addrdesc->arg1/*abstract*/<<1)|sfd->para.socket.un.tight, + sfd->para.socket.ip.ai_flags) + == STAT_OK) { needbind = true; } @@ -251,10 +262,10 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, } if (opt_unlink_close && needbind) { - if ((xfd->unlink_close = strdup(us.sun_path)) == NULL) { + if ((sfd->unlink_close = strdup(us.sun_path)) == NULL) { Error1("strdup(\"%s\"): out of memory", name); } - xfd->opt_unlink_close = true; + sfd->opt_unlink_close = true; } retropt_bool(opts, OPT_FORK, &dofork); @@ -267,14 +278,14 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, do { /* loop over retries and forks */ #if WITH_RETRY - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { level = E_INFO; } else #endif /* WITH_RETRY */ level = E_ERROR; result = - _xioopen_connect(xfd, + _xioopen_connect(sfd, needbind?(union sockaddr_union *)&us:NULL, uslen, (struct sockaddr *)&them, themlen, opts, pf, socktype, protocol, false, level); @@ -289,10 +300,10 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: - if (xfd->forever || xfd->retry) { - --xfd->retry; + if (sfd->forever || sfd->retry) { + --sfd->retry; if (result == STAT_RETRYLATER) { - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); } dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); continue; @@ -311,16 +322,16 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, if (dofork) { pid_t pid; int level = E_ERROR; - if (xfd->forever || xfd->retry) { + if (sfd->forever || sfd->retry) { level = E_WARN; /* most users won't expect a problem here, so Notice is too weak */ } - while ((pid = xio_fork(false, level, xfd->shutup)) < 0) { - --xfd->retry; - if (xfd->forever || xfd->retry) { + while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { + --sfd->retry; + if (sfd->forever || sfd->retry) { dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); - Nanosleep(&xfd->intervall, NULL); continue; + Nanosleep(&sfd->intervall, NULL); continue; } return STAT_RETRYLATER; } @@ -330,9 +341,9 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, } /* parent process */ - Close(xfd->fd); + Close(sfd->fd); /* with and without retry */ - Nanosleep(&xfd->intervall, NULL); + Nanosleep(&sfd->intervall, NULL); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); continue; /* with next socket() bind() connect() */ } else @@ -342,17 +353,31 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, } } while (true); - if ((result = _xio_openlate(xfd, opts)) < 0) { + if (opt_unlink_close && needbind) { + if ((sfd->unlink_close = strndup(us.sun_path, sizeof(us.sun_path))) == NULL) { + Error2("strndup(\"%s\", "F_Zu"): out of memory", name, sizeof(us.sun_path)); + } + sfd->opt_unlink_close = true; + } + + if ((result = _xio_openlate(sfd, opts)) < 0) { return result; } return STAT_OK; } -static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy, int dummy3) { +static int xioopen_unix_sendto( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ /* we expect the form: filename */ const char *name; - xiosingle_t *xfd = &xxfd->stream; + xiosingle_t *sfd = &xxfd->stream; const struct opt *namedopt; int pf = PF_UNIX; int socktype = SOCK_DGRAM; @@ -360,33 +385,33 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i union sockaddr_union us; socklen_t uslen = sizeof(us); bool needbind = false; - bool opt_unlink_close = (abstract != 1); + bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1); int result; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } name = argv[1]; - xfd->para.socket.un.tight = true; + sfd->para.socket.un.tight = true; retropt_socket_pf(opts, &pf); - xfd->howtoend = END_SHUTDOWN; - applyopts_offset(xfd, opts); + sfd->howtoend = END_SHUTDOWN; + applyopts_offset(sfd, opts); - xfd->salen = xiosetunix(pf, &xfd->peersa.un, name, abstract, xfd->para.socket.un.tight); + sfd->salen = xiosetunix(pf, &sfd->peersa.un, name, addrdesc->arg1/*abstract*/, sfd->para.socket.un.tight); - if (!(ABSTRACT && abstract)) { + if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) { /* only for non abstract because abstract do not work in file system */ retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); } - xfd->dtype = XIODATA_RECVFROM; + sfd->dtype = XIODATA_RECVFROM; if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, - (abstract<<1)| xfd->para.socket.un.tight, NULL) - == STAT_OK) { + (addrdesc->arg1/*abstract*/<<1)| sfd->para.socket.un.tight, + sfd->para.socket.ip.ai_flags) + == STAT_OK) { needbind = true; } @@ -395,34 +420,39 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i Error1("Option \"%s\" only with bind option", namedopt->desc->defname); } - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; - applyopts(xfd, -1, opts, PH_INIT); + if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; + applyopts(sfd, -1, opts, PH_INIT); result = _xioopen_dgram_sendto(needbind?(union sockaddr_union *)&us:NULL, uslen, - opts, xioflags, xfd, groups, + opts, xioflags, sfd, addrdesc->groups, pf, socktype, protocol, 0); if (result != 0) { return result; } if (opt_unlink_close && needbind) { - if ((xfd->unlink_close = strdup(us.un.sun_path)) == NULL) { - Error1("strdup(\"%s\"): out of memory", name); + if ((sfd->unlink_close = strndup(us.un.sun_path, sizeof(us.un.sun_path))) == NULL) { + Error2("strndup(\"%s\", "F_Zu"): out of memory", name, sizeof(us.un.sun_path)); } - xfd->opt_unlink_close = true; + sfd->opt_unlink_close = true; } return STAT_OK; } static -int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int abstract, int dummy2, int dummy3) { +int xioopen_unix_recvfrom( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ /* we expect the form: filename */ const char *name; - xiosingle_t *xfd = &xxfd->stream; + xiosingle_t *sfd = &xxfd->stream; int pf = PF_UNIX; int socktype = SOCK_DGRAM; int protocol = 0; @@ -430,40 +460,41 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, socklen_t uslen; bool needbind = true; bool opt_unlink_early = false; - bool opt_unlink_close = (abstract != 1); + bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1); if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } name = argv[1]; - xfd->para.socket.un.tight = true; + sfd->para.socket.un.tight = true; retropt_socket_pf(opts, &pf); - xfd->howtoend = END_NONE; - if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY; - applyopts(xfd, -1, opts, PH_INIT); + sfd->howtoend = END_NONE; + if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY; + applyopts(sfd, -1, opts, PH_INIT); applyopts_named(name, opts, PH_EARLY); /* umask! */ - applyopts_offset(xfd, opts); + applyopts_offset(sfd, opts); - if (!(ABSTRACT && abstract)) { + if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) { /* only for non abstract because abstract do not work in file system */ retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); } - applyopts(xfd, -1, opts, PH_EARLY); + applyopts(sfd, -1, opts, PH_EARLY); - uslen = xiosetunix(pf, &us, name, abstract, xfd->para.socket.un.tight); + uslen = xiosetunix(pf, &us, name, addrdesc->arg1/*abstract*/, + sfd->para.socket.un.tight); #if 0 if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen, - (abstract<<1)|xfd->para.socket.un.tight, NULL) - == STAT_OK) { + (addrdesc->arg1/*abstract*/<<1)|sfd->para.socket.un.tight, + sfd->para.socket.ip.ai_flags)) { + == STAT_OK) { } #endif - if (!(ABSTRACT && abstract)) { + if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) { if (opt_unlink_early) { xio_unlink(name, E_ERROR); } else { @@ -474,10 +505,10 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, } } if (opt_unlink_close) { - if ((xfd->unlink_close = strdup(name)) == NULL) { + if ((sfd->unlink_close = strdup(name)) == NULL) { Error1("strdup(\"%s\"): out of memory", name); } - xfd->opt_unlink_close = true; + sfd->opt_unlink_close = true; } /* trying to set user-early, perm-early etc. here is useless because @@ -485,66 +516,71 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, } applyopts_named(name, opts, PH_EARLY); /* umask! */ - xfd->para.socket.la.soa.sa_family = pf; + sfd->para.socket.la.soa.sa_family = pf; - xfd->dtype = XIODATA_RECVFROM_ONE; + sfd->dtype = XIODATA_RECVFROM_ONE; /* this may fork */ return - _xioopen_dgram_recvfrom(xfd, xioflags, + _xioopen_dgram_recvfrom(sfd, xioflags, needbind?(struct sockaddr *)&us:NULL, uslen, opts, pf, socktype, protocol, E_ERROR); } -static -int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int abstract, int dummy2, int dummy3) { +static int xioopen_unix_recv( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ /* we expect the form: filename */ const char *name; - xiosingle_t *xfd = &xxfd->stream; + xiosingle_t *sfd = &xxfd->stream; int pf = PF_UNIX; int socktype = SOCK_DGRAM; int protocol = 0; union sockaddr_union us; socklen_t uslen; bool opt_unlink_early = false; - bool opt_unlink_close = (abstract != 1); + bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1); int result; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } name = argv[1]; - xfd->para.socket.un.tight = true; + sfd->para.socket.un.tight = true; retropt_socket_pf(opts, &pf); - xfd->howtoend = END_SHUTDOWN; - if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY; - applyopts(xfd, -1, opts, PH_INIT); + sfd->howtoend = END_SHUTDOWN; + if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY; + applyopts(sfd, -1, opts, PH_INIT); applyopts_named(name, opts, PH_EARLY); /* umask! */ - applyopts_offset(xfd, opts); + applyopts_offset(sfd, opts); - if (!(ABSTRACT && abstract)) { + if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) { /* only for non abstract because abstract do not work in file system */ retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); } - applyopts(xfd, -1, opts, PH_EARLY); + applyopts(sfd, -1, opts, PH_EARLY); - uslen = xiosetunix(pf, &us.un, name, abstract, xfd->para.socket.un.tight); + uslen = xiosetunix(pf, &us.un, name, addrdesc->arg1/*abstract*/, + sfd->para.socket.un.tight); #if 0 if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, - (abstract<<1)|xfd->para.socket.un.tight, NULL) + (addrdesc->arg1/*abstract*/<<1)|sfd->para.socket.un.tight, + sfd->para.socket.ip.ai_flags) == STAT_OK) { } #endif - if (!(ABSTRACT && abstract)) { + if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) { if (opt_unlink_early) { xio_unlink(name, E_ERROR); } else { @@ -555,33 +591,41 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, } } if (opt_unlink_close) { - if ((xfd->unlink_close = strdup(name)) == NULL) { + if ((sfd->unlink_close = strdup(name)) == NULL) { Error1("strdup(\"%s\"): out of memory", name); } - xfd->opt_unlink_close = true; + sfd->opt_unlink_close = true; } } applyopts_named(name, opts, PH_EARLY); /* umask! */ - xfd->para.socket.la.soa.sa_family = pf; + sfd->para.socket.la.soa.sa_family = pf; - xfd->dtype = XIODATA_RECV; - result = _xioopen_dgram_recv(xfd, xioflags, &us.soa, uslen, + sfd->dtype = XIODATA_RECV; + result = _xioopen_dgram_recv(sfd, xioflags, &us.soa, uslen, opts, pf, socktype, protocol, E_ERROR); return result; } /* generic UNIX socket client, tries connect, SEQPACKET, send(to) */ -static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3) { +static int xioopen_unix_client( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ /* we expect the form: filename */ if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); + return STAT_NORETRY; } return - _xioopen_unix_client(&xxfd->stream, xioflags, groups, abstract, opts, - argv[1]); + _xioopen_unix_client(&xxfd->stream, xioflags, addrdesc->groups, + addrdesc->arg1/*abstract*/, opts, argv[1]); } /* establishes communication with an existing UNIX type socket. supports stream @@ -595,7 +639,7 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_CLOEXEC, OPT_USER, OPT_GROUP, ?OPT_FORK, */ int -_xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups, +_xioopen_unix_client(xiosingle_t *sfd, int xioflags, groups_t groups, int abstract, struct opt *opts, const char *name) { const struct opt *namedopt; int pf = PF_UNIX; @@ -608,23 +652,24 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups, struct opt *opts0; int result; - xfd->para.socket.un.tight = true; + sfd->para.socket.un.tight = true; retropt_socket_pf(opts, &pf); - xfd->howtoend = END_SHUTDOWN; - if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY; - applyopts(xfd, -1, opts, PH_INIT); - applyopts_offset(xfd, opts); + sfd->howtoend = END_SHUTDOWN; + if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY; + applyopts(sfd, -1, opts, PH_INIT); + applyopts_offset(sfd, opts); retropt_int(opts, OPT_SO_TYPE, &socktype); retropt_int(opts, OPT_SO_PROTOTYPE, &protocol); - applyopts(xfd, -1, opts, PH_EARLY); + applyopts(sfd, -1, opts, PH_EARLY); - themlen = xiosetunix(pf, &them.un, name, abstract, xfd->para.socket.un.tight); + themlen = xiosetunix(pf, &them.un, name, abstract, sfd->para.socket.un.tight); if (!(ABSTRACT && abstract)) { /* only for non abstract because abstract do not work in file system */ retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); } if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, - (abstract<<1)|xfd->para.socket.un.tight, NULL) + (abstract<<1)|sfd->para.socket.un.tight, + sfd->para.socket.ip.ai_flags) != STAT_NOACTION) { needbind = true; } @@ -635,10 +680,10 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups, } if (opt_unlink_close) { - if ((xfd->unlink_close = strdup(name)) == NULL) { + if ((sfd->unlink_close = strdup(name)) == NULL) { Error1("strdup(\"%s\"): out of memory", name); } - xfd->opt_unlink_close = true; + sfd->opt_unlink_close = true; } /* save options, because we might have to start again */ @@ -646,10 +691,10 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups, /* just a breakable block, helps to avoid goto */ do { - /* xfd->dtype = DATA_STREAM; // is default */ + /* sfd->dtype = DATA_STREAM; // is default */ /* this function handles AF_UNIX with EPROTOTYPE specially for us */ if ((result = - _xioopen_connect(xfd, + _xioopen_connect(sfd, needbind?&us:NULL, uslen, &them.soa, themlen, opts, pf, socktype?socktype:SOCK_STREAM, protocol, @@ -663,7 +708,7 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups, socktype = SOCK_SEQPACKET; if ((result = - _xioopen_connect(xfd, + _xioopen_connect(sfd, needbind?&us:NULL, uslen, (struct sockaddr *)&them, themlen, opts, pf, SOCK_SEQPACKET, protocol, @@ -675,14 +720,14 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups, xio_unlink(us.un.sun_path, E_ERROR); dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0; - xfd->peersa = them; - xfd->salen = sizeof(struct sockaddr_un); + sfd->peersa = them; + sfd->salen = sizeof(struct sockaddr_un); if ((result = _xioopen_dgram_sendto(needbind?&us:NULL, uslen, - opts, xioflags, xfd, groups, + opts, xioflags, sfd, groups, pf, SOCK_DGRAM, protocol, 0)) == 0) { - xfd->dtype = XIODATA_RECVFROM; + sfd->dtype = XIODATA_RECVFROM; break; } } while (0); @@ -694,7 +739,7 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups, return result; } - if ((result = _xio_openlate(xfd, opts)) < 0) { + if ((result = _xio_openlate(sfd, opts)) < 0) { return result; } return 0; diff --git a/xio-vsock.c b/xio-vsock.c index 8fc4a90..2ebc5b2 100644 --- a/xio-vsock.c +++ b/xio-vsock.c @@ -13,12 +13,8 @@ #include "xio-socket.h" #include "xio-vsock.h" -static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, - int dummy2, int dummy3); -static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, - int dummy2, int dummy3); +static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc); +static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc); static void xiolog_vsock_cid(void); @@ -45,26 +41,31 @@ static int vsock_addr_init(struct sockaddr_vm *sa, const char *cid_str, /* Performs a few steps during opening an address of type VSOCK */ -static int vsock_init(struct opt *opts, struct single *xfd) { +static int vsock_init(struct opt *opts, struct single *sfd) { - xfd->howtoend = END_SHUTDOWN; + sfd->howtoend = END_SHUTDOWN; - if (applyopts_single(xfd, opts, PH_INIT) < 0) + if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY; - applyopts(xfd, -1, opts, PH_INIT); - applyopts(xfd, -1, opts, PH_EARLY); + applyopts(sfd, -1, opts, PH_INIT); + applyopts(sfd, -1, opts, PH_EARLY); - xfd->dtype = XIODATA_STREAM; + sfd->dtype = XIODATA_STREAM; return STAT_OK; } -static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, - int abstract, int dummy2, int dummy3) { +static int xioopen_vsock_connect( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ /* we expect the form :cid:port */ - struct single *xfd = &xxfd->stream; + struct single *sfd = &xxfd->stream; struct sockaddr_vm sa, sa_local; socklen_t sa_len = sizeof(sa); bool needbind = false; @@ -74,8 +75,7 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts, int ret; if (argc != 3) { - Error2("%s: wrong number of parameters (%d instead of 2)", - argv[0], argc-1); + xio_syntax(argv[0], 2, argc-1, addrdesc->syntax); return STAT_NORETRY; } @@ -88,7 +88,7 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts, return ret; } - ret = vsock_init(opts, xfd); + ret = vsock_init(opts, sfd); if (ret) { return ret; } @@ -96,19 +96,20 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts, xiolog_vsock_cid(); ret = retropt_bind(opts, pf, socktype, protocol, - (struct sockaddr *)&sa_local, &sa_len, 3, NULL); + (struct sockaddr *)&sa_local, &sa_len, 3, + sfd->para.socket.ip.ai_flags); if (ret == STAT_NORETRY) return ret; if (ret == STAT_OK) needbind = true; - ret = xioopen_connect(xfd, needbind ? (union sockaddr_union *)&sa_local : NULL, + ret = xioopen_connect(sfd, needbind ? (union sockaddr_union *)&sa_local : NULL, sa_len, (struct sockaddr *)&sa, sizeof(sa), opts, pf, socktype, protocol, false); if (ret) return ret; - ret = _xio_openlate(xfd, opts); + ret = _xio_openlate(sfd, opts); if (ret < 0) return ret; @@ -117,11 +118,16 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts, #if WITH_LISTEN -static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, - int dummy2, int dummy3) { +static int xioopen_vsock_listen( + int argc, + const char *argv[], + struct opt *opts, + int xioflags, + xiofile_t *xxfd, + const struct addrdesc *addrdesc) +{ /* we expect the form :port */ - struct single *xfd = &xxfd->stream; + struct single *sfd = &xxfd->stream; struct sockaddr_vm sa, sa_bind; socklen_t sa_len = sizeof(sa_bind); struct opt *opts0; @@ -131,8 +137,7 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, int ret; if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } @@ -145,7 +150,7 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, return ret; } - ret = vsock_init(opts, xfd); + ret = vsock_init(opts, sfd); if (ret) { return ret; } @@ -153,7 +158,8 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, opts0 = copyopts(opts, GROUP_ALL); ret = retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&sa_bind, - &sa_len, 1, NULL); + &sa_len, 1, + sfd->para.socket.ip.ai_flags); if (ret == STAT_NORETRY) return ret; if (ret == STAT_OK) @@ -162,7 +168,7 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, xiolog_vsock_cid(); /* this may fork() */ - return xioopen_listen(xfd, xioflags, (struct sockaddr *)&sa, sizeof(sa), + return xioopen_listen(sfd, xioflags, (struct sockaddr *)&sa, sizeof(sa), opts, opts0, pf, socktype, protocol); } #endif /* WITH_LISTEN */ diff --git a/xio.h b/xio.h index efd5e99..b72bf2b 100644 --- a/xio.h +++ b/xio.h @@ -355,8 +355,7 @@ typedef union bipipe { struct addrdesc { const char *defname; /* main (canonical) name of address */ int directions; /* 1..read, 2..write, 3..both */ - int (*func)(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, groups_t groups, - int arg1, int arg2, int arg3); + int (*func)(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, const struct addrdesc *addrdesc); groups_t groups; int arg1; int arg2; diff --git a/xiohelp.c b/xiohelp.c index fc276c9..36edf7e 100644 --- a/xiohelp.c +++ b/xiohelp.c @@ -218,4 +218,16 @@ int xioopenhelp(FILE *of, return 0; } +/* This function may be used by address handling code to log syntax error */ +int xiohelp_syntax( + const char *addr, + int expectnum, + int isnum, + const char *syntax) +{ + Error4("%s: wrong number of parameters (%d instead of %d): usage: %s", + addr, isnum, expectnum, syntax); + return -1; +} + #endif /* WITH_HELP */ diff --git a/xiohelp.h b/xiohelp.h index cd3fa5b..3c7c0e4 100644 --- a/xiohelp.h +++ b/xiohelp.h @@ -11,4 +11,6 @@ extern int xioopenhelp(FILE *of, int level /* 0..only addresses, 1..and options */ ); +extern int xiohelp_syntax(const char *addr, int expectnum, int isnum, const char *syntax); + #endif /* !defined(__xiohelp_h_included) */ diff --git a/xioopen.c b/xioopen.c index eb532ab..110aef3 100644 --- a/xioopen.c +++ b/xioopen.c @@ -8,11 +8,11 @@ #include "xioopen.h" #include "xiomodes.h" +#include "xiohelp.h" #include "nestlex.h" static xiofile_t *xioallocfd(void); -xiosingle_t hugo; static xiosingle_t *xioparse_single(const char **addr); static xiofile_t *xioparse_dual(const char **addr); static int xioopen_dual(xiofile_t *xfd, int xioflags); @@ -668,8 +668,7 @@ int xioopen_single(xiofile_t *xfd, int xioflags) { xfd->stream.flags |= (xioflags & XIO_ACCMODE); result = (*addrdesc->func)(xfd->stream.argc, xfd->stream.argv, xfd->stream.opts, xioflags, xfd, - addrdesc->groups, addrdesc->arg1, - addrdesc->arg2, addrdesc->arg3); + addrdesc); #if HAVE_RESOLV_H if (do_res) @@ -690,3 +689,11 @@ int xioopen_single(xiofile_t *xfd, int xioflags) { return result; } +int xio_syntax( + const char *addr, + int expectnum, + int isnum, + const char *syntax) +{ + return xiohelp_syntax(addr, expectnum, isnum, syntax); +} diff --git a/xioopen.h b/xioopen.h index 8baad24..481b527 100644 --- a/xioopen.h +++ b/xioopen.h @@ -45,6 +45,12 @@ extern const struct optname optionnames[]; extern int xioopen_makedual(xiofile_t *file); +#if WITH_HELP +extern int xio_syntax(const char *addr, int expectnum, int isnum, const char *syntax); +#else +#define xio_syntax(a,e,i,s) Error3("%s: wrong number of parameters (%d instead of %d)", a, i, e); +#endif + #define retropt_2bytes(o,c,r) retropt_ushort(o,c,r) /* mode_t might be unsigned short or unsigned int or what else? */ diff --git a/xioopts.c b/xioopts.c index 4ba3058..a751ee4 100644 --- a/xioopts.c +++ b/xioopts.c @@ -151,7 +151,7 @@ bool xioopts_ignoregroups; #endif -static int applyopt_offset(struct single *xfd, struct opt *opt); +static int applyopt_offset(struct single *sfd, struct opt *opt); static int applyopt(struct single *sfd, int fd, struct opt *opt); @@ -4080,10 +4080,10 @@ int applyopts_fchown(int fd, struct opt *opts) { } /* caller must make sure that option is not yet consumed */ -static int applyopt_offset(struct single *xfd, struct opt *opt) { +static int applyopt_offset(struct single *sfd, struct opt *opt) { unsigned char *ptr; - ptr = (unsigned char *)xfd + opt->desc->major; + ptr = (unsigned char *)sfd + opt->desc->major; switch (opt->desc->type) { case TYPE_BOOL: *(bool *)ptr = opt->value.u_bool; break; @@ -4117,7 +4117,7 @@ static int applyopt_offset(struct single *xfd, struct opt *opt) { return 0; } -int applyopts_offset(struct single *xfd, struct opt *opts) { +int applyopts_offset(struct single *sfd, struct opt *opts) { struct opt *opt; opt = opts; while (opt->desc != ODESC_END) { @@ -4125,16 +4125,16 @@ int applyopts_offset(struct single *xfd, struct opt *opts) { opt->desc->func != OFUNC_OFFSET) { ++opt; continue; } - applyopt_offset(xfd, opt); + applyopt_offset(sfd, opt); opt->desc = ODESC_DONE; ++opt; } return 0; } -/* applies to xfd all OFUNC_EXT options belonging to phase +/* applies to sfd all OFUNC_EXT options belonging to phase returns -1 if an error occurred */ -int applyopts_single(struct single *xfd, struct opt *opts, enum e_phase phase) { +int applyopts_single(struct single *sfd, struct opt *opts, enum e_phase phase) { struct opt *opt; int rc = 0; @@ -4145,9 +4145,9 @@ int applyopts_single(struct single *xfd, struct opt *opts, enum e_phase phase) { if ((opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR) && (opt->desc->phase == phase && phase != PH_ALL)) { if (opt->desc->func < OFUNC_XIO) { - rc = applyopt(NULL, xfd->fd, opt); + rc = applyopt(NULL, sfd->fd, opt); } else { - rc = applyopt(xfd, -1, opt); + rc = applyopt(sfd, -1, opt); } if (rc == 0) opt->desc = ODESC_DONE;