socat-1.7.3.1/0000755000201000020100000000000012652745660012575 5ustar gerhardgerhardsocat-1.7.3.1/nestlex.c0000644000201000020100000001640212652637410014417 0ustar gerhardgerhard/* source: nestlex.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* a function for lexical scanning of nested character patterns */ #include "config.h" #include "mytypes.h" #include "sysincludes.h" static int _nestlex(const char **addr, char **token, ptrdiff_t *len, const char *ends[], const char *hquotes[], const char *squotes[], const char *nests[], bool dropquotes, bool c_esc, bool html_esc ); /* sub: scan a string and copy its value to output string end scanning when an unescaped, unnested string from ends array is found does not copy the end pattern does not write a trailing \0 to token allows escaping with \ and quoting (\ and quotes are removed) allows nesting with div. parens returns -1 if out string was too small returns 1 if addr ended unexpectedly returns 0 if token could be extracted successfully */ int nestlex(const char **addr, /* input string; aft points to end token */ char **token, /* output token; aft points to first unwritten char (caller might want to set it to \0) */ size_t *len, /* remaining bytes in token space (incl. \0) */ const char *ends[], /* list of end strings */ const char *hquotes[],/* list of strings that quote (hard qu.) */ const char *squotes[],/* list of strings that quote softly */ const char *nests[],/* list of strings that start nesting; every second one is matching end */ bool dropquotes, /* drop the outermost quotes */ bool c_esc, /* solve C char escapes: \n \t \0 etc */ bool html_esc /* solve HTML char escapes: %0d %08 etc */ ) { return _nestlex(addr, token, (ptrdiff_t *)len, ends, hquotes, squotes, nests, dropquotes, c_esc, html_esc); } static int _nestlex(const char **addr, char **token, ptrdiff_t *len, const char *ends[], const char *hquotes[], const char *squotes[], const char *nests[], bool dropquotes, bool c_esc, bool html_esc ) { const char *in = *addr; /* pointer into input string */ const char **endx; /* loops over end patterns */ const char **quotx; /* loops over quote patterns */ const char **nestx; /* loops over nest patterns */ char *out = *token; /* pointer into output token */ char c; int i; int result; while (true) { /* is this end of input string? */ if (*in == 0) { break; /* end of string */ } /* first check the end patterns (e.g. for ']') */ endx = ends; i = 0; while (*endx) { if (!strncmp(in, *endx, strlen(*endx))) { /* this end pattern matches */ *addr = in; *token = out; return 0; } ++endx; } /* check for hard quoting pattern */ quotx = hquotes; while (hquotes && *quotx) { if (!strncmp(in, *quotx, strlen(*quotx))) { /* this quote pattern matches */ const char *endnest[2]; if (dropquotes) { /* we strip this quote */ in += strlen(*quotx); } else { for (i = strlen(*quotx); i > 0; --i) { *out++ = *in++; if (--*len <= 0) { *addr = in; *token = out; return -1; } } } /* we call _nestlex recursively */ endnest[0] = *quotx; endnest[1] = NULL; result = _nestlex(&in, &out, len, endnest, NULL/*hquotes*/, NULL/*squotes*/, NULL/*nests*/, false, c_esc, html_esc); if (result == 0 && dropquotes) { /* we strip this quote */ in += strlen(*quotx); } else if (result < 0) { *addr = in; *token = out; return result; } else { /* we copy the trailing quote */ for (i = strlen(*quotx); i > 0; --i) { *out++ = *in++; if (--*len <= 0) { *addr = in; *token = out; return -1; } } } break; } ++quotx; } if (hquotes && *quotx != NULL) { /* there was a quote; string might continue with hard quote */ continue; } /* check for soft quoting pattern */ quotx = squotes; while (squotes && *quotx) { if (!strncmp(in, *quotx, strlen(*quotx))) { /* this quote pattern matches */ /* we strip this quote */ /* we call _nestlex recursively */ const char *endnest[2]; if (dropquotes) { /* we strip this quote */ in += strlen(*quotx); } else { for (i = strlen(*quotx); i > 0; --i) { *out++ = *in++; if (--*len <= 0) { *addr = in; *token = out; return -1; } } } endnest[0] = *quotx; endnest[1] = NULL; result = _nestlex(&in, &out, len, endnest, hquotes, squotes, nests, false, c_esc, html_esc); if (result == 0 && dropquotes) { /* we strip the trailing quote */ in += strlen(*quotx); } else if (result < 0) { *addr = in; *token = out; return result; } else { /* we copy the trailing quote */ for (i = strlen(*quotx); i > 0; --i) { *out++ = *in++; if (--*len <= 0) { *addr = in; *token = out; return -1; } } } break; } ++quotx; } if (squotes && *quotx != NULL) { /* there was a soft quote; string might continue with any quote */ continue; } /* check patterns that start a nested clause */ nestx = nests; i = 0; while (nests && *nestx) { if (!strncmp(in, *nestx, strlen(*nestx))) { /* this nest pattern matches */ const char *endnest[2]; endnest[0] = nestx[1]; endnest[1] = NULL; for (i = strlen(nestx[1]); i > 0; --i) { *out++ = *in++; if (--*len <= 0) { *addr = in; *token = out; return -1; } } result = _nestlex(&in, &out, len, endnest, hquotes, squotes, nests, false, c_esc, html_esc); if (result == 0) { /* copy endnest */ i = strlen(nestx[1]); while (i > 0) { *out++ = *in++; if (--*len <= 0) { *addr = in; *token = out; return -1; } --i; } } else if (result < 0) { *addr = in; *token = out; return result; } break; } nestx += 2; /* skip matching end pattern in table */ } if (nests && *nestx) { /* we handled a nested expression, continue loop */ continue; } /* "normal" data, possibly escaped */ c = *in++; if (c == '\\') { /* found a plain \ escaped part */ c = *in++; if (c == 0) { /* Warn("trailing '\\'");*/ break; } if (c_esc) { /* solve C char escapes: \n \t \0 etc */ switch (c) { case '0': c = '\0'; break; case 'a': c = '\a'; break; case 'b': c = '\b'; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; #if LATER case 'x': !!! 1 to 2 hex digits; break; case 'u': !!! 4 hex digits?; break; case 'U': !!! 8 hex digits?; break; #endif default: break; } } *out++ = c; --*len; if (*len <= 0) { *addr = in; *token = out; return -1; /* output overflow */ } continue; } /* just a simple char */ *out++ = c; --*len; if (*len <= 0) { *addr = in; *token = out; return -1; /* output overflow */ } } /* never come here? */ *addr = in; *token = out; return 0; /* OK */ } socat-1.7.3.1/xio-streams.c0000644000201000020100000000477611453022152015210 0ustar gerhardgerhard/* source: xio-streams.c */ /* Copyright Gerhard Rieger 2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains definitions and functions for handling POSIX STREAMS */ /* with this source file a new experimental approach is being introduced: normally when adding a new option at least four existing files have to be adapted; this is similar for new address types. in the future i would like to have a more automatic assembling of socat from topic oriented source files. this should make integration and control of contributions more easy. all code of a new topic - address and option definitions, open code, option handing code, ev.parser code, etc. should go into one source file. the selection of the desired code parts during the compilation is done by setting cpp defines. in the same was all public declarations should go in one header (.h) file. */ /* do not compile this file directly but include it from other .c files. with CPP defines you select one part you want to really get included: ENABLE_OPTIONS: activate the definition of the address option records ENABLE_APPLYOPTS: C code that applies the address option passed in opt */ #ifdef ENABLE_OPTIONS #ifdef I_POP const struct optdesc opt_streams_i_pop_all = { "streams-i-pop-all", "pop-all", OPT_STREAMS_I_POP_ALL, GROUP_FD, PH_FD, TYPE_BOOL, OFUNC_STREAMS_I_POP_ALL, 0, 0 }; #endif #ifdef I_PUSH const struct optdesc opt_streams_i_push = { "streams-i-push", "push", OPT_STREAMS_I_PUSH, GROUP_FD, PH_FD, TYPE_STRING, OFUNC_STREAMS_I_PUSH, 0, 0 }; #endif #elif defined(ENABLE_APPLYOPT) #if 0 void dummy(void) { if (0) { { ; #endif #ifdef I_POP } else if (opt->desc->func == OFUNC_STREAMS_I_POP_ALL) { while (Ioctl(fd, I_POP, 0) >= 0) { Warn2("ioctl(%d, I_POP, 0): %s", fd, strerror(errno)); } #endif #ifdef I_PUSH } else if (opt->desc->func == OFUNC_STREAMS_I_PUSH) { if (Ioctl(fd, I_PUSH, opt->value.u_string) < 0) { Warn3("ioctl(%d, I_PUSH, \"%s\"): %s", fd, opt->value.u_string, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } #endif #if 0 } } } #endif #else /* !defined(ENABLE_APPLYOPT) */ #include "xiosysincludes.h" #if WITH_STREAMS /* make this address configure dependend */ #include "xioopen.h" #include "xio-fd.h" #include "xio-socket.h" /* _xioopen_connect() */ #include "xio-listen.h" #include "xio-ipapp.h" #include "xio-openssl.h" #endif /* WITH_STREAMS */ #endif /* !defined(ENABLE_OPTIONS) */ socat-1.7.3.1/xiolayer.h0000644000201000020100000000122212161507435014566 0ustar gerhardgerhard/* source: xiolayer.h */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xiolayer_h_included #define __xiolayer_h_included 1 extern const struct optdesc opt_ignoreeof; extern const struct optdesc opt_cr; extern const struct optdesc opt_crnl; extern const struct optdesc opt_readbytes; extern const struct optdesc opt_lockfile; extern const struct optdesc opt_waitlock; extern const struct optdesc opt_escape; extern const struct optdesc opt_forever; extern const struct optdesc opt_intervall; extern const struct optdesc opt_retry; #endif /* !defined(__xiolayer_h_included) */ socat-1.7.3.1/xiolayer.c0000644000201000020100000000374412161507435014574 0ustar gerhardgerhard/* source: xiolayer.c */ /* Copyright Gerhard Rieger 2001-2009 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for common options */ #include "xiosysincludes.h" #include "xioopen.h" #include "xiolayer.h" /****** for ALL addresses - by application ******/ const struct optdesc opt_ignoreeof = { "ignoreeof", NULL, OPT_IGNOREEOF, GROUP_APPL, PH_LATE, TYPE_BOOL, OFUNC_EXT, XIO_OFFSETOF(ignoreeof), XIO_SIZEOF(ignoreeof) }; const struct optdesc opt_cr = { "cr", NULL, OPT_CR, GROUP_APPL, PH_LATE, TYPE_CONST, OFUNC_EXT, XIO_OFFSETOF(lineterm), XIO_SIZEOF(lineterm), LINETERM_CR }; const struct optdesc opt_crnl = { "crnl", NULL, OPT_CRNL, GROUP_APPL, PH_LATE, TYPE_CONST, OFUNC_EXT, XIO_OFFSETOF(lineterm), XIO_SIZEOF(lineterm), LINETERM_CRNL }; const struct optdesc opt_readbytes = { "readbytes", "bytes", OPT_READBYTES, GROUP_APPL, PH_LATE, TYPE_SIZE_T, OFUNC_EXT, XIO_OFFSETOF(readbytes), XIO_SIZEOF(readbytes) }; const struct optdesc opt_lockfile = { "lockfile", NULL, OPT_LOCKFILE, GROUP_APPL, PH_INIT, TYPE_FILENAME, OFUNC_EXT, 0, 0 }; const struct optdesc opt_waitlock = { "waitlock", NULL, OPT_WAITLOCK, GROUP_APPL, PH_INIT, TYPE_FILENAME, OFUNC_EXT, 0, 0 }; const struct optdesc opt_escape = { "escape", NULL, OPT_ESCAPE, GROUP_APPL, PH_INIT, TYPE_INT, OFUNC_OFFSET, XIO_OFFSETOF(escape), sizeof(((xiosingle_t *)0)->escape) }; /****** APPL addresses ******/ #if WITH_RETRY const struct optdesc opt_forever = { "forever", NULL, OPT_FOREVER, GROUP_RETRY, PH_INIT, TYPE_BOOL, OFUNC_EXT, XIO_OFFSETOF(forever), XIO_SIZEOF(forever) }; const struct optdesc opt_intervall = { "interval", NULL, OPT_INTERVALL, GROUP_RETRY, PH_INIT, TYPE_TIMESPEC, OFUNC_EXT, XIO_OFFSETOF(intervall), XIO_SIZEOF(intervall) }; const struct optdesc opt_retry = { "retry", NULL, OPT_RETRY, GROUP_RETRY, PH_INIT, TYPE_UINT, OFUNC_EXT, XIO_OFFSETOF(retry), XIO_SIZEOF(retry) }; #endif socat-1.7.3.1/xio-ip6.c0000644000201000020100000004421512455415361014233 0ustar gerhardgerhard/* source: xio-ip6.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for IP6 related functions */ #include "xiosysincludes.h" #if WITH_IP6 #include "xioopen.h" #include "xio-ascii.h" #include "xio-socket.h" #include "xio-ip.h" /* xiogetaddrinfo() */ #include "xio-ip6.h" static char *inet6addr_info(const struct in6_addr *sa, char *buff, size_t blen); #ifdef IPV6_V6ONLY const struct optdesc opt_ipv6_v6only = { "ipv6-v6only", "ipv6only", OPT_IPV6_V6ONLY, GROUP_SOCK_IP6, PH_PREBIND, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_V6ONLY }; #endif #ifdef IPV6_JOIN_GROUP const struct optdesc opt_ipv6_join_group = { "ipv6-join-group", "join-group", OPT_IPV6_JOIN_GROUP, GROUP_SOCK_IP6, PH_PASTBIND, TYPE_IP_MREQN, OFUNC_SOCKOPT, SOL_IPV6, IPV6_JOIN_GROUP }; #endif #ifdef IPV6_PKTINFO const struct optdesc opt_ipv6_pktinfo = { "ipv6-pktinfo", "pktinfo", OPT_IPV6_PKTINFO, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_PKTINFO }; #endif #ifdef IPV6_RECVPKTINFO const struct optdesc opt_ipv6_recvpktinfo = { "ipv6-recvpktinfo", "recvpktinfo", OPT_IPV6_RECVPKTINFO, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVPKTINFO }; #endif #ifdef IPV6_RTHDR const struct optdesc opt_ipv6_rthdr = { "ipv6-rthdr", "rthdr", OPT_IPV6_RTHDR, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RTHDR }; #endif #ifdef IPV6_RECVRTHDR const struct optdesc opt_ipv6_recvrthdr = { "ipv6-recvrthdr", "recvrthdr", OPT_IPV6_RECVRTHDR, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVRTHDR }; #endif #ifdef IPV6_AUTHHDR const struct optdesc opt_ipv6_authhdr = { "ipv6-authhdr", "authhdr", OPT_IPV6_AUTHHDR, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_AUTHHDR }; #endif #ifdef IPV6_DSTOPTS const struct optdesc opt_ipv6_dstopts = { "ipv6-dstopts", "dstopts", OPT_IPV6_DSTOPTS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_DSTOPTS }; #endif #ifdef IPV6_RECVDSTOPTS const struct optdesc opt_ipv6_recvdstopts = { "ipv6-recvdstopts", "recvdstopts", OPT_IPV6_RECVDSTOPTS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVDSTOPTS }; #endif #ifdef IPV6_HOPOPTS const struct optdesc opt_ipv6_hopopts = { "ipv6-hopopts", "hopopts", OPT_IPV6_HOPOPTS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_HOPOPTS }; #endif #ifdef IPV6_RECVHOPOPTS const struct optdesc opt_ipv6_recvhopopts = { "ipv6-recvhopopts", "recvhopopts", OPT_IPV6_RECVHOPOPTS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVHOPOPTS }; #endif #ifdef IPV6_FLOWINFO /* is in linux/in6.h */ const struct optdesc opt_ipv6_flowinfo= { "ipv6-flowinfo","flowinfo",OPT_IPV6_FLOWINFO,GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_FLOWINFO }; #endif #ifdef IPV6_HOPLIMIT const struct optdesc opt_ipv6_hoplimit= { "ipv6-hoplimit","hoplimit",OPT_IPV6_HOPLIMIT,GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_HOPLIMIT }; #endif const struct optdesc opt_ipv6_unicast_hops= { "ipv6-unicast-hops","unicast-hops",OPT_IPV6_UNICAST_HOPS,GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IPV6, IPV6_UNICAST_HOPS }; #ifdef IPV6_RECVHOPLIMIT const struct optdesc opt_ipv6_recvhoplimit= { "ipv6-recvhoplimit","recvhoplimit",OPT_IPV6_RECVHOPLIMIT,GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVHOPLIMIT }; #endif #ifdef IPV6_RECVERR const struct optdesc opt_ipv6_recverr = { "ipv6-recverr", "recverr", OPT_IPV6_RECVERR, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVERR }; #endif #ifdef IPV6_TCLASS const struct optdesc opt_ipv6_tclass = { "ipv6-tclass", "tclass", OPT_IPV6_TCLASS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IPV6, IPV6_TCLASS }; #endif #ifdef IPV6_RECVTCLASS const struct optdesc opt_ipv6_recvtclass = { "ipv6-recvtclass", "recvtclass", OPT_IPV6_RECVTCLASS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVTCLASS }; #endif #ifdef IPV6_RECVPATHMTU const struct optdesc opt_ipv6_recvpathmtu = { "ipv6-recvpathmtu", "recvpathmtu", OPT_IPV6_RECVPATHMTU, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVPATHMTU }; #endif int xioparsenetwork_ip6(const char *rangename, struct xiorange *range) { char *delimpos; /* absolute address of delimiter */ size_t delimind; /* index of delimiter in string */ unsigned int bits; /* netmask bits */ char *endptr; char *baseaddr; union sockaddr_union sockaddr; socklen_t sockaddrlen = sizeof(sockaddr); union xioin6_u *rangeaddr = (union xioin6_u *)&range->netaddr.ip6.sin6_addr; union xioin6_u *rangemask = (union xioin6_u *)&range->netmask.ip6.sin6_addr; union xioin6_u *nameaddr = (union xioin6_u *)&sockaddr.ip6.sin6_addr; if (rangename[0] != '[' || rangename[strlen(rangename)-1] != ']') { Error1("missing brackets for IPv6 range definition \"%s\"", rangename); return STAT_NORETRY; } if ((delimpos = strchr(rangename, '/')) == NULL) { Error1("xioparsenetwork_ip6(\"%s\",,): missing mask bits delimiter '/'", rangename); return STAT_NORETRY; } delimind = delimpos - rangename; if ((baseaddr = strdup(rangename+1)) == NULL) { Error1("strdup(\"%s\"): out of memory", rangename+1); return STAT_NORETRY; } baseaddr[delimind-1] = '\0'; if (xiogetaddrinfo(baseaddr, NULL, PF_INET6, 0, 0, &sockaddr, &sockaddrlen, 0, 0) != STAT_OK) { return STAT_NORETRY; } rangeaddr->u6_addr32[0] = nameaddr->u6_addr32[0]; rangeaddr->u6_addr32[1] = nameaddr->u6_addr32[1]; rangeaddr->u6_addr32[2] = nameaddr->u6_addr32[2]; rangeaddr->u6_addr32[3] = nameaddr->u6_addr32[3]; bits = strtoul(delimpos+1, &endptr, 10); if (! ((*(delimpos+1) != '\0') && (*endptr == '\0'))) { Error1("not a valid netmask in \"%s\"", rangename); bits = 128; /* most secure selection */ } else if (bits > 128) { Error1("netmask \"%s\" is too large", rangename); bits = 128; } /* I am starting to dislike C...uint32_t << 32 is undefined... */ if (bits == 0) { rangemask->u6_addr32[0] = 0; rangemask->u6_addr32[1] = 0; rangemask->u6_addr32[2] = 0; rangemask->u6_addr32[3] = 0; } else if (bits <= 32) { rangemask->u6_addr32[0] = htonl(0xffffffff << (32-bits)); rangemask->u6_addr32[1] = 0; rangemask->u6_addr32[2] = 0; rangemask->u6_addr32[3] = 0; } else if (bits <= 64) { rangemask->u6_addr32[0] = 0xffffffff; rangemask->u6_addr32[1] = htonl(0xffffffff << (64-bits)); rangemask->u6_addr32[2] = 0; rangemask->u6_addr32[3] = 0; } else if (bits <= 96) { rangemask->u6_addr32[0] = 0xffffffff; rangemask->u6_addr32[1] = 0xffffffff; rangemask->u6_addr32[2] = htonl(0xffffffff << (96-bits)); rangemask->u6_addr32[3] = 0; } else { rangemask->u6_addr32[0] = 0xffffffff; rangemask->u6_addr32[1] = 0xffffffff; rangemask->u6_addr32[2] = 0xffffffff; rangemask->u6_addr32[3] = htonl(0xffffffff << (128-bits)); } return 0; } int xiorange_ip6andmask(struct xiorange *range) { int i; #if 0 range->addr.s6_addr32[0] &= range->mask.s6_addr32[0]; range->addr.s6_addr32[1] &= range->mask.s6_addr32[1]; range->addr.s6_addr32[2] &= range->mask.s6_addr32[2]; range->addr.s6_addr32[3] &= range->mask.s6_addr32[3]; #else for (i = 0; i < 16; ++i) { range->netaddr.ip6.sin6_addr.s6_addr[i] &= range->netmask.ip6.sin6_addr.s6_addr[i]; } #endif return 0; } /* check if peer address is within permitted range. return >= 0 if so. */ int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange *range) { union xioin6_u masked; int i; char peername[256]; union xioin6_u *rangeaddr = (union xioin6_u *)&range->netaddr.ip6.sin6_addr; union xioin6_u *rangemask = (union xioin6_u *)&range->netmask.ip6; Debug16("permitted client subnet: [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]:[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]", htons(rangeaddr->u6_addr16[0]), htons(rangeaddr->u6_addr16[1]), htons(rangeaddr->u6_addr16[2]), htons(rangeaddr->u6_addr16[3]), htons(rangeaddr->u6_addr16[4]), htons(rangeaddr->u6_addr16[5]), htons(rangeaddr->u6_addr16[6]), htons(rangeaddr->u6_addr16[7]), htons(rangemask->u6_addr16[0]), htons(rangemask->u6_addr16[1]), htons(rangemask->u6_addr16[2]), htons(rangemask->u6_addr16[3]), htons(rangemask->u6_addr16[4]), htons(rangemask->u6_addr16[5]), htons(rangemask->u6_addr16[6]), htons(rangemask->u6_addr16[7])); Debug1("client address is %s", sockaddr_inet6_info(pa, peername, sizeof(peername))); for (i = 0; i < 4; ++i) { masked.u6_addr32[i] = pa->sin6_addr.s6_addr[i] & rangemask->u6_addr16[i]; } Debug8("masked address is [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]", htons(masked.u6_addr16[0]), htons(masked.u6_addr16[1]), htons(masked.u6_addr16[2]), htons(masked.u6_addr16[3]), htons(masked.u6_addr16[4]), htons(masked.u6_addr16[5]), htons(masked.u6_addr16[6]), htons(masked.u6_addr16[7])); if (masked.u6_addr32[0] != rangeaddr->u6_addr32[0] || masked.u6_addr32[1] != rangeaddr->u6_addr32[1] || masked.u6_addr32[2] != rangeaddr->u6_addr32[2] || masked.u6_addr32[3] != rangeaddr->u6_addr32[3]) { Debug1("client address %s is not permitted", peername); return -1; } return 0; } #if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) /* provides info about the ancillary message: converts the ancillary message in *cmsg into a form useable for further processing. knows the specifics of common message types. returns the number of resulting syntax elements in *num returns a sequence of \0 terminated type strings in *typbuff returns a sequence of \0 terminated name strings in *nambuff returns a sequence of \0 terminated value strings in *valbuff the respective len parameters specify the available space in the buffers returns STAT_OK on success */ int xiolog_ancillary_ip6(struct cmsghdr *cmsg, int *num, char *typbuff, int typlen, char *nambuff, int namlen, char *envbuff, int envlen, char *valbuff, int vallen) { char scratch1[42]; /* can hold an IPv6 address in ASCII */ char scratch2[32]; size_t msglen; *num = 1; /* good for most message types */ msglen = cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg); envbuff[0] = '\0'; switch (cmsg->cmsg_type) { #if defined(IPV6_PKTINFO) && HAVE_STRUCT_IN6_PKTINFO case IPV6_PKTINFO: { struct in6_pktinfo *pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg); *num = 2; typbuff[0] = '\0'; strncat(typbuff, "IPV6_PKTINFO", typlen-1); snprintf(nambuff, namlen, "%s%c%s", "dstaddr", '\0', "if"); snprintf(envbuff, envlen, "%s%c%s", "IPV6_DSTADDR", '\0', "IPV6_IF"); snprintf(valbuff, vallen, "%s%c%s", inet6addr_info(&pktinfo->ipi6_addr, scratch1, sizeof(scratch1)), '\0', xiogetifname(pktinfo->ipi6_ifindex, scratch2, -1)); } return STAT_OK; #endif /* defined(IPV6_PKTINFO) && HAVE_STRUCT_IN6_PKTINFO */ #ifdef IPV6_HOPLIMIT case IPV6_HOPLIMIT: typbuff[0] = '\0'; strncat(typbuff, "IPV6_HOPLIMIT", typlen-1); nambuff[0] = '\0'; strncat(nambuff, "hoplimit", namlen-1); { int *intp = (int *)CMSG_DATA(cmsg); snprintf(valbuff, vallen, "%d", *intp); } return STAT_OK; #endif /* defined(IPV6_HOPLIMIT) */ #ifdef IPV6_RTHDR case IPV6_RTHDR: typbuff[0] = '\0'; strncat(typbuff, "IPV6_RTHDR", typlen-1); nambuff[0] = '\0'; strncat(nambuff, "rthdr", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #endif /* defined(IPV6_RTHDR) */ #ifdef IPV6_AUTHHDR case IPV6_AUTHHDR: typbuff[0] = '\0'; strncat(typbuff, "IPV6_AUTHHDR", typlen-1); nambuff[0] = '\0'; strncat(nambuff, "authhdr", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #endif #ifdef IPV6_DSTOPTS case IPV6_DSTOPTS: typbuff[0] = '\0'; strncat(typbuff, "IPV6_DSTOPTS", typlen-1); nambuff[0] = '\0'; strncat(nambuff, "dstopts", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #endif /* defined(IPV6_DSTOPTS) */ #ifdef IPV6_HOPOPTS case IPV6_HOPOPTS: typbuff[0] = '\0'; strncat(typbuff, "IPV6_HOPOPTS", typlen-1); nambuff[0] = '\0'; strncat(nambuff, "hopopts", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #endif /* defined(IPV6_HOPOPTS) */ #ifdef IPV6_FLOWINFO case IPV6_FLOWINFO: typbuff[0] = '\0'; strncat(typbuff, "IPV6_FLOWINFO", typlen-1); nambuff[0] = '\0'; strncat(nambuff, "flowinfo", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #endif #ifdef IPV6_TCLASS case IPV6_TCLASS: typbuff[0] = '\0'; strncat(typbuff, "IPV6_TCLASS", typlen-1); nambuff[0] = '\0'; strncat(nambuff, "tclass", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #endif default: snprintf(typbuff, typlen, "IPV6.%u", cmsg->cmsg_type); nambuff[0] = '\0'; strncat(nambuff, "data", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; } return STAT_OK; } #endif /* defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) */ /* convert the IP6 socket address to human readable form. buff should be at least 50 chars long. output includes the port number */ static char *inet6addr_info(const struct in6_addr *sa, char *buff, size_t blen) { if (xio_snprintf(buff, blen, "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]", #if HAVE_IP6_SOCKADDR==0 (sa->s6_addr[0]<<8)+sa->s6_addr[1], (sa->s6_addr[2]<<8)+sa->s6_addr[3], (sa->s6_addr[4]<<8)+sa->s6_addr[5], (sa->s6_addr[6]<<8)+sa->s6_addr[7], (sa->s6_addr[8]<<8)+sa->s6_addr[9], (sa->s6_addr[10]<<8)+sa->s6_addr[11], (sa->s6_addr[12]<<8)+sa->s6_addr[13], (sa->s6_addr[14]<<8)+sa->s6_addr[15] #elif HAVE_IP6_SOCKADDR==1 ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[0]), ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[1]), ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[2]), ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[3]), ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[4]), ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[5]), ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[6]), ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[7]) #elif HAVE_IP6_SOCKADDR==2 ntohs(((unsigned short *)&sa->u6_addr16)[0]), ntohs(((unsigned short *)&sa->u6_addr16)[1]), ntohs(((unsigned short *)&sa->u6_addr16)[2]), ntohs(((unsigned short *)&sa->u6_addr16)[3]), ntohs(((unsigned short *)&sa->u6_addr16)[4]), ntohs(((unsigned short *)&sa->u6_addr16)[5]), ntohs(((unsigned short *)&sa->u6_addr16)[6]), ntohs(((unsigned short *)&sa->u6_addr16)[7]) #elif HAVE_IP6_SOCKADDR==3 ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[0]), ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[1]), ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[2]), ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[3]), ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[4]), ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[5]), ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[6]), ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[7]) #elif HAVE_IP6_SOCKADDR==4 (sa->_S6_un._S6_u8[0]<<8)|(sa->_S6_un._S6_u8[1]&0xff), (sa->_S6_un._S6_u8[2]<<8)|(sa->_S6_un._S6_u8[3]&0xff), (sa->_S6_un._S6_u8[4]<<8)|(sa->_S6_un._S6_u8[5]&0xff), (sa->_S6_un._S6_u8[6]<<8)|(sa->_S6_un._S6_u8[7]&0xff), (sa->_S6_un._S6_u8[8]<<8)|(sa->_S6_un._S6_u8[9]&0xff), (sa->_S6_un._S6_u8[10]<<8)|(sa->_S6_un._S6_u8[11]&0xff), (sa->_S6_un._S6_u8[12]<<8)|(sa->_S6_un._S6_u8[13]&0xff), (sa->_S6_un._S6_u8[14]<<8)|(sa->_S6_un._S6_u8[15]&0xff) #elif HAVE_IP6_SOCKADDR==5 ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[0]), ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[1]), ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[2]), ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[3]), ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[4]), ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[5]), ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[6]), ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[7]) #endif ) >= blen) { Warn("sockaddr_inet6_info(): buffer too short"); buff[blen-1] = '\0'; } return buff; } /* returns information that can be used for constructing an environment variable describing the socket address. if idx is 0, this function writes "ADDR" into namebuff and the IP address into valuebuff, and returns 1 (which means that one more info is there). if idx is 1, it writes "PORT" into namebuff and the port number into valuebuff, and returns 0 (no more info) namelen and valuelen contain the max. allowed length of output chars in the respective buffer. on error this function returns -1. */ int xiosetsockaddrenv_ip6(int idx, char *namebuff, size_t namelen, char *valuebuff, size_t valuelen, struct sockaddr_in6 *sa, int ipproto) { switch (idx) { case 0: strcpy(namebuff, "ADDR"); snprintf(valuebuff, valuelen, "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]", (sa->sin6_addr.s6_addr[0]<<8)+ sa->sin6_addr.s6_addr[1], (sa->sin6_addr.s6_addr[2]<<8)+ sa->sin6_addr.s6_addr[3], (sa->sin6_addr.s6_addr[4]<<8)+ sa->sin6_addr.s6_addr[5], (sa->sin6_addr.s6_addr[6]<<8)+ sa->sin6_addr.s6_addr[7], (sa->sin6_addr.s6_addr[8]<<8)+ sa->sin6_addr.s6_addr[9], (sa->sin6_addr.s6_addr[10]<<8)+ sa->sin6_addr.s6_addr[11], (sa->sin6_addr.s6_addr[12]<<8)+ sa->sin6_addr.s6_addr[13], (sa->sin6_addr.s6_addr[14]<<8)+ sa->sin6_addr.s6_addr[15]); switch (ipproto) { case IPPROTO_TCP: case IPPROTO_UDP: #ifdef IPPROTO_SCTP case IPPROTO_SCTP: #endif return 1; /* there is port information to also be retrieved */ default: return 0; /* no port info coming */ } case 1: strcpy(namebuff, "PORT"); snprintf(valuebuff, valuelen, "%u", ntohs(sa->sin6_port)); return 0; } return -1; } #endif /* WITH_IP6 */ socat-1.7.3.1/xio-tcpwrap.c0000644000201000020100000001350211453022152015175 0ustar gerhardgerhard/* source: xio-tcpwrap.c */ /* Copyright Gerhard Rieger 2006-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for tcpwrapper handling stuff */ #include "xiosysincludes.h" #if WITH_LIBWRAP #include "tcpd.h" #endif #include "xioopen.h" #include "xio-tcpwrap.h" #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP const struct optdesc opt_tcpwrappers = { "tcpwrappers", "tcpwrap", OPT_TCPWRAPPERS, GROUP_RANGE, PH_ACCEPT, TYPE_STRING_NULL, OFUNC_SPEC }; const struct optdesc opt_tcpwrap_etc = { "tcpwrap-etc", "tcpwrap-dir", OPT_TCPWRAP_ETC, GROUP_RANGE, PH_ACCEPT, TYPE_FILENAME, OFUNC_SPEC }; #if defined(HAVE_HOSTS_ALLOW_TABLE) const struct optdesc opt_tcpwrap_hosts_allow_table = { "tcpwrap-hosts-allow-table", "allow-table", OPT_TCPWRAP_HOSTS_ALLOW_TABLE, GROUP_RANGE, PH_ACCEPT, TYPE_FILENAME, OFUNC_SPEC }; #endif #if defined(HAVE_HOSTS_DENY_TABLE) const struct optdesc opt_tcpwrap_hosts_deny_table = { "tcpwrap-hosts-deny-table", "deny-table", OPT_TCPWRAP_HOSTS_DENY_TABLE, GROUP_RANGE, PH_ACCEPT, TYPE_FILENAME, OFUNC_SPEC }; #endif /* they are declared only externally with libwrap and would be unresolved without these definitions */ 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) { bool dolibwrap = false; dolibwrap = retropt_string(opts, OPT_TCPWRAPPERS, &xfd->para.socket.ip.libwrapname) >= 0 || dolibwrap; dolibwrap = retropt_string(opts, OPT_TCPWRAP_ETC, &xfd->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; #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; #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'); } #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 (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); } } #endif /* defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE) */ return 0; } return 1; } /* 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) { char *save_hosts_allow_table, *save_hosts_deny_table; struct request_info ri; #if WITH_IP6 char clientaddr[INET6_ADDRSTRLEN] = "", serveraddr[INET6_ADDRSTRLEN] = ""; #else char clientaddr[INET_ADDRSTRLEN] = "", serveraddr[INET_ADDRSTRLEN] = ""; #endif int allow; if (!xfd->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) { Debug1("hosts_allow_table = \"%s\"", xfd->para.socket.ip.hosts_allow_table); hosts_allow_table = xfd->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) { Debug1("hosts_deny_table = \"%s\"", xfd->para.socket.ip.hosts_deny_table); hosts_deny_table = xfd->para.socket.ip.hosts_deny_table; } #endif /* defined(HAVE_HOSTS_DENY_TABLE) */ hosts_access_verbose = 32767; if (inet_ntop(them->soa.sa_family, #if WITH_IP6 them->soa.sa_family==PF_INET6 ? (void *)&them->ip6.sin6_addr : #endif (void *)&them->ip4.sin_addr, clientaddr, sizeof(clientaddr)) == NULL) { Warn1("inet_ntop(): %s", strerror(errno)); } if (inet_ntop(us->soa.sa_family, #if WITH_IP6 us->soa.sa_family==PF_INET6 ? (void *)&us->ip6.sin6_addr : #endif (void *)&us->ip4.sin_addr, serveraddr, sizeof(serveraddr)) == NULL) { 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, 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, 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); Debug("request_init() ->"); Debug1("sock_methods(%p)", &ri); sock_methods(&ri); Debug("sock_methods() ->"); Debug1("hosts_access(%p)", &ri); allow = hosts_access(&ri); Debug1("hosts_access() -> %d", allow); #if defined(HAVE_HOSTS_ALLOW_TABLE) hosts_allow_table = save_hosts_allow_table; #endif #if defined(HAVE_HOSTS_DENY_TABLE) hosts_deny_table = save_hosts_deny_table; #endif if (allow == 0) { return -1; } return 1; } #endif /* (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */ socat-1.7.3.1/xio-gopen.c0000644000201000020100000000727212161511320014631 0ustar gerhardgerhard/* source: xio-gopen.c */ /* Copyright Gerhard Rieger 2001-2010 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of generic open type */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-named.h" #include "xio-unix.h" #include "xio-gopen.h" #if WITH_GOPEN static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); const struct addrdesc addr_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 *fd, unsigned groups, int dummy1, int dummy2, int dummy3) { const char *filename = argv[1]; flags_t openflags = (xioflags & XIO_ACCMODE); mode_t st_mode; bool exists; bool opt_unlink_close = false; int result; if ((result = _xioopen_named_early(argc, argv, fd, GROUP_NAMED|groups, &exists, opts)) < 0) { return result; } st_mode = result; if (exists) { /* file (or at least named entry) exists */ if ((xioflags&XIO_ACCMODE) != XIO_RDONLY) { openflags |= O_APPEND; } } else { openflags |= O_CREAT; } /* note: when S_ISSOCK was undefined, it always gives 0 */ if (exists && S_ISSOCK(st_mode)) { #if WITH_UNIX union sockaddr_union us; socklen_t uslen = sizeof(us); char infobuff[256]; Info1("\"%s\" is a socket, connecting to it", filename); result = _xioopen_unix_client(&fd->stream, xioflags, groups, 0, opts, filename); if (result < 0) { return result; } applyopts_named(filename, opts, PH_PASTOPEN); /* unlink-late */ if (Getsockname(fd->stream.fd, (struct sockaddr *)&us, &uslen) < 0) { Warn4("getsockname(%d, %p, {%d}): %s", fd->stream.fd, &us, uslen, strerror(errno)); } else { Notice1("successfully connected via %s", sockaddr_unix_info(&us.un, uslen, infobuff, sizeof(infobuff))); } #else Error("\"%s\" is a socket, but UNIX socket support is not compiled in"); return -1; #endif /* WITH_UNIX */ } else { /* a file name */ Info1("\"%s\" is not a socket, open()'ing it", filename); retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); if (opt_unlink_close) { if ((fd->stream.unlink_close = strdup(filename)) == NULL) { Error1("strdup(\"%s\"): out of memory", filename); } fd->stream.opt_unlink_close = true; } Notice3("opening %s \"%s\" for %s", filetypenames[(st_mode&S_IFMT)>>12], filename, ddirection[(xioflags&XIO_ACCMODE)]); if ((result = _xioopen_open(filename, openflags, opts)) < 0) return result; #ifdef I_PUSH if (S_ISCHR(st_mode)) { Ioctl(result, I_PUSH, "ptem"); Ioctl(result, I_PUSH, "ldterm"); Ioctl(result, I_PUSH, "ttcompat"); } #endif fd->stream.fd = result; #if WITH_TERMIOS if (Isatty(fd->stream.fd)) { if (Tcgetattr(fd->stream.fd, &fd->stream.savetty) < 0) { Warn2("cannot query current terminal settings on fd %d: %s", fd->stream.fd, strerror(errno)); } else { fd->stream.ttyvalid = true; } } #endif /* WITH_TERMIOS */ applyopts_named(filename, opts, PH_FD); applyopts(fd->stream.fd, opts, PH_FD); applyopts_cloexec(fd->stream.fd, opts); } if ((result = applyopts2(fd->stream.fd, opts, PH_PASTSOCKET, PH_CONNECTED)) < 0) return result; if ((result = _xio_openlate(&fd->stream, opts)) < 0) return result; return 0; } #endif /* WITH_GOPEN */ socat-1.7.3.1/fdname.c0000644000201000020100000001742412161511320014156 0ustar gerhardgerhard/* source: fdname.c */ /* Copyright Gerhard Rieger 2003-2011 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* the subroutine sockname prints the basic info about the address of a socket NOTE: it works on UNIX (kernel) file descriptors, not on libc files! */ #include "config.h" #include "xioconfig.h" /* what features are enabled */ #include "sysincludes.h" #include "mytypes.h" #include "compat.h" #include "error.h" #include "sycls.h" #include "sysutils.h" #include "filan.h" struct sockopt { int so; char *name; }; int statname(const char *file, int fd, int filetype, FILE *outfile); int cdevname(int fd, FILE *outfile); int sockname(int fd, FILE *outfile); int unixame(int fd, FILE *outfile); int tcpname(int fd, FILE *outfile); int fdname(const char *file, int fd, FILE *outfile, const char *numform) { struct stat buf = {0}; int filetype; Debug1("checking file descriptor %u", fd); if (fd >= 0) { if (Fstat(fd, &buf) < 0) { if (errno == EBADF) { Debug2("fstat(%d): %s", fd, strerror(errno)); return -1; } else { Error2("fstat(%d): %s", fd, strerror(errno)); } } filetype = (buf.st_mode&S_IFMT)>>12; if (numform != NULL) { fprintf(outfile, numform, fd); } return statname(file, fd, filetype, outfile); } else { if (Stat(file, &buf) < 0) { Error2("stat(\"%s\"): %s", file, strerror(errno)); } filetype = (buf.st_mode&S_IFMT)>>12; return statname(file, -1, filetype, outfile); } } #if HAVE_PROC_DIR_FD static int procgetfdname(int fd, char *filepath, size_t pathsize) { static pid_t pid = -1; char procpath[PATH_MAX]; int len; /* even if configure has shown that we have /proc, we must check if it exists at runtime, because we might be in a chroot environment */ #if HAVE_STAT64 { struct stat64 buf; if (Stat64("/proc", &buf) < 0) { return -1; } if (!S_ISDIR(buf.st_mode)) { return -1; } } #else /* !HAVE_STAT64 */ { struct stat buf; if (Stat("/proc", &buf) < 0) { return -1; } if (!S_ISDIR(buf.st_mode)) { return -1; } } #endif /* !HAVE_STAT64 */ if (pid < 0) pid = Getpid(); snprintf(procpath, sizeof(procpath), "/proc/"F_pid"/fd/%d", pid, fd); if ((len = Readlink(procpath, filepath, pathsize-1)) < 0) { Error4("readlink(\"%s\", %p, "F_Zu"): %s", procpath, filepath, pathsize, strerror(errno)); return -1; } filepath[len] = '\0'; return 0; } #endif /* HAVE_PROC_DIR_FD */ int statname(const char *file, int fd, int filetype, FILE *outfile) { char filepath[PATH_MAX]; filepath[0] = '\0'; #if HAVE_PROC_DIR_FD if (fd >= 0) { procgetfdname(fd, filepath, sizeof(filepath)); if (filepath[0] == '/') { file = filepath; } } #endif /* HAVE_PROC_DIR_FD */ /* now see for type specific infos */ switch (filetype) { case (S_IFIFO>>12): /* 1, FIFO */ fputs("pipe", outfile); if (file) fprintf(outfile, " %s", file); break; case (S_IFCHR>>12): /* 2, character device */ if (cdevname(fd, outfile) == 0) { if (file) fprintf(outfile, " %s", file); } break; case (S_IFDIR>>12): /* 4, directory */ fputs("dir", outfile); if (file) fprintf(outfile, " %s", file); break; case (S_IFBLK>>12): /* 6, block device */ fputs("blkdev", outfile); if (file) fprintf(outfile, " %s", file); break; case (S_IFREG>>12): /* 8, regular file */ fputs("file", outfile); if (file) fprintf(outfile, " %s", file); break; case (S_IFLNK>>12): /* 10, symbolic link */ fputs("link", outfile); if (file) fprintf(outfile, " %s", file); break; case (S_IFSOCK>>12): /* 12, socket */ #if _WITH_SOCKET if (fd >= 0) { sockname(fd, outfile); } else if (file) { fprintf(outfile, "socket %s", file); } else { fputs("socket", outfile); } #else Error("SOCKET support not compiled in"); return -1; #endif /* !_WITH_SOCKET */ break; } /* ioctl() */ fputc('\n', outfile); return 0; } /* character device analysis */ /* return -1 on error, 0 if no name was found, or 1 if it printed ttyname */ int cdevname(int fd, FILE *outfile) { int ret; if ((ret = Isatty(fd)) < 0) { Error2("isatty(%d): %s", fd, strerror(errno)); return -1; } if (ret > 0) { char *name; fputs("tty", outfile); if ((name = Ttyname(fd)) != NULL) { fputc(' ', outfile); fputs(name, outfile); return 1; } } else { fputs("chrdev", outfile); } return 0; } #if _WITH_SOCKET int sockname(int fd, FILE *outfile) { #define FDNAME_OPTLEN 256 #define FDNAME_NAMELEN 256 socklen_t optlen; int opttype; #ifdef SO_ACCEPTCONN int optacceptconn; #endif int result /*0, i*/; char namebuff[FDNAME_NAMELEN]; char peerbuff[FDNAME_NAMELEN]; /* in Linux these optcodes are 'enum', but on AIX they are bits! */ union sockaddr_union sockname, peername; /* the longest I know of */ socklen_t namelen; #if 0 && defined(SIOCGIFNAME) /*Linux struct ifreq ifc = {{{ 0 }}};*/ struct ifreq ifc = {{ 0 }}; #endif optlen = FDNAME_OPTLEN; Getsockopt(fd, SOL_SOCKET, SO_TYPE, &opttype, &optlen); #ifdef SO_ACCEPTCONN Getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &optacceptconn, &optlen); #endif namelen = sizeof(sockname); result = Getsockname(fd, &sockname.soa, &namelen); if (result < 0) { Error2("getsockname(%d): %s", fd, strerror(errno)); return -1; } namelen = sizeof(peername); result = Getpeername(fd, (struct sockaddr *)&peername, &namelen); if (result < 0) { Error2("getpeername(%d): %s", fd, strerror(errno)); } switch (sockname.soa.sa_family) { #if WITH_UNIX case AF_UNIX: fprintf(outfile, "unix%s%s %s", opttype==SOCK_DGRAM?"datagram":"", #ifdef SO_ACCEPTCONN optacceptconn?"(listening)": #endif "", sockaddr_unix_info(&sockname.un, namelen, namebuff, sizeof(namebuff))); break; #endif #if WITH_IP4 case AF_INET: switch (opttype) { #if WITH_TCP case SOCK_STREAM: fprintf(outfile, "tcp%s %s %s", #ifdef SO_ACCEPTCONN optacceptconn?"(listening)": #endif "", sockaddr_inet4_info(&sockname.ip4, namebuff, sizeof(namebuff)), sockaddr_inet4_info(&peername.ip4, peerbuff, sizeof(peerbuff))); break; #endif #if WITH_UDP case SOCK_DGRAM: fprintf(outfile, "udp%s %s %s", #ifdef SO_ACCEPTCONN optacceptconn?"(listening)": #endif "", sockaddr_inet4_info(&sockname.ip4, namebuff, sizeof(namebuff)), sockaddr_inet4_info(&peername.ip4, peerbuff, sizeof(peerbuff))); break; #endif default: fprintf(outfile, "ip %s", sockaddr_inet4_info(&sockname.ip4, namebuff, sizeof(namebuff))); break; } break; #endif /* WITH_IP4 */ #if WITH_IP6 case AF_INET6: switch (opttype) { #if WITH_TCP case SOCK_STREAM: fprintf(outfile, "tcp6%s %s %s", #ifdef SO_ACCEPTCONN optacceptconn?"(listening)": #endif "", sockaddr_inet6_info(&sockname.ip6, namebuff, sizeof(namebuff)), sockaddr_inet6_info(&peername.ip6, peerbuff, sizeof(peerbuff))); break; #endif #if WITH_UDP case SOCK_DGRAM: fprintf(outfile, "udp6%s %s %s", #ifdef SO_ACCEPTCONN optacceptconn?"(listening)": #endif "", sockaddr_inet6_info(&sockname.ip6, namebuff, sizeof(namebuff)), sockaddr_inet6_info(&peername.ip6, peerbuff, sizeof(peerbuff))); break; #endif default: fprintf(outfile, "ip6 %s", sockaddr_inet6_info(&sockname.ip6, namebuff, sizeof(namebuff))); break; } #endif /* WITH_IP6 */ default: fputs("socket", outfile); } return result; #undef FDNAME_OPTLEN #undef FDNAME_NAMELEN } #endif /* _WITH_SOCKET */ socat-1.7.3.1/FAQ0000644000201000020100000000751711453022151013116 0ustar gerhardgerhard Q: What is the clue of socat? A: socat probably doesn't have any clue. It is more an attempt to smoothly integrate similar I/O features that are usually handled differently under UNIX. Q: What does the prefix XIO mean? A: XIO means "extended input/output". It is a library/API that provides a common way for handling files, sockets and other forms of I/O. Its advantage is that the application may reduce its I/O to open / read+write / close calls, while the user controls all I/O details (and even basic process properties) by packing options into the filename string. This is the basic part of socat. Q: Is there a Windows port of socat available? A: Try with Cygwin from http://www.cygwin.com/, or upgrade to Linux. Q: I succeeded to configure and make socat, but ./test.sh says something like: ./test.sh: No such file or directory A: You need a bash shell, and its location must be correctly specified in the first line of test.sh, e.g. /usr/local/bin/bash instead of /bin/bash. Q: configure disables readline / openssl / libwrap support because it does not find an include file / the library. How can I tell configure where these files are? A: For include locations, use the environment variable CPPFLAGS, for library locations use LIBS, e.g.: export CPPFLAGS="-I/home/user/ssl/include" export LIBS="-L/home/user/ssl/lib" On some systems (SunOS), you might also need to set LD_LIBRARY_PATH: export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/home/user/ssl/lib" Then try again: make distclean; ./configure; make Q: I succeeded to make socat, but the test.sh script fails for many tests. Is my socat build corrupt? A: Probably your socat program is ok; the tests have been developed on Linux 2.4, and there they usually succeed. But the following OS differences result in errors on non Linux systems: * Linux allows to bind a socket to any address of range 127.0.0.0/8, not only 127.0.0.1. Some tests are built on this feature, but they might fail on other systems. * Your OS might have no IP6 implementation * MacOS X has some difficulties, e.g. distinguishing sockets and pipes. * the OpenSSL tests require OpenSSL support by socat, must have openssl in $PATH, and "openssl s_server ..." needs enough entropy to generate a key. Q: When I specify a dual address (two partial addresses linked with "!!") on the command line, I get some message "event not found", and my shell history has the line truncated. Not even protecting the '!'s with '\' helps. A: '!' is appearently used by your shell as history expansion character. Say "set +H" and add this line to your (bash) profile. Q: On Solaris, socat was built successfully, but when started, it gets killed with something like "ld.so.1: ./socat: fatal: libreadline.so.4: open failed: no such file or directory" A: The configure script finds your libreadline, but the runtime loader doesn't. Add the directory where the library resides to your LD_LIBRARY_PATH variable, e.g.: LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/sfw/lib/ make distclean; ./configure; make Q: On Solaris, socat was built successfully, but when started, an assertion fails: "xioinitialize.c:25: failed assertion `3 << opt_crdly.arg3 == CRDLY' A: Probably, in a second attempt you set the correct LD_LIBARY_PATH for socat, but it had not been set during the ./configure run, or you did not "make clean" before running configure. Try it again: make distclean; ./configure; make Q: A socat process, run in background from an interactive shell, is always stopped with all its child processes after about 5 minutes. killall -9 socat is required to clean the system and allow socat to be started again. A: The terminal (window) might have the TOSTOP flag set and one of the socat processes wants to write to the terminal. Clear this flag in your shell: stty -tostop and start socat again. Thanks to Philippe Teuwen for reporting this situation. socat-1.7.3.1/xio-socks.c0000644000201000020100000003137412455415362014662 0ustar gerhardgerhard/* source: xio-socks.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of socks4 type */ #include "xiosysincludes.h" #if WITH_SOCKS4 || WITH_SOCKS4A #include "xioopen.h" #include "xio-ascii.h" #include "xio-socket.h" #include "xio-ip.h" #include "xio-ipapp.h" #include "xio-socks.h" enum { SOCKS_CD_GRANTED = 90, SOCKS_CD_FAILED, SOCKS_CD_NOIDENT, SOCKS_CD_IDENTFAILED } ; #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, unsigned groups, int dummy1, int dummy2, int dummy3); 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 }; const struct addrdesc addr_socks4_connect = { "socks4", 3, xioopen_socks4_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS4|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":::") }; const struct addrdesc addr_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, unsigned groups, int socks4a, int dummy2, int dummy3) { /* we expect the form: host:host:port */ struct single *xfd = &xxfd->stream; struct opt *opts0 = NULL; const char *sockdname; char *socksport; const char *targetname, *targetport; int pf = PF_UNSPEC; int ipproto = IPPROTO_TCP; bool dofork = false; union sockaddr_union us_sa, *us = &us_sa; union sockaddr_union them_sa, *them = &them_sa; socklen_t uslen = sizeof(us_sa); socklen_t themlen = sizeof(them_sa); bool needbind = false; bool lowport = false; unsigned char buff[BUFF_LEN]; struct socks4 *sockhead = (struct socks4 *)buff; size_t buflen = sizeof(buff); int socktype = SOCK_STREAM; int level; int result; if (argc != 4) { Error1("%s: 3 parameters required", argv[0]); 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(-1, opts, PH_INIT); retropt_int(opts, OPT_SO_TYPE, &socktype); retropt_bool(opts, OPT_FORK, &dofork); result = _xioopen_socks4_prepare(targetport, opts, &socksport, sockhead, &buflen); if (result != STAT_OK) return result; result = _xioopen_ipapp_prepare(opts, &opts0, sockdname, socksport, &pf, ipproto, xfd->para.socket.ip.res_opts[1], xfd->para.socket.ip.res_opts[0], them, &themlen, us, &uslen, &needbind, &lowport, socktype); Notice5("opening connection to %s:%u via socks4 server %s:%s as user \"%s\"", targetname, ntohs(sockhead->port), sockdname, socksport, sockhead->userid); do { /* loop over failed connect and socks-request attempts */ #if WITH_RETRY if (xfd->forever || xfd->retry) { level = E_INFO; } else #endif /* WITH_RETRY */ level = E_ERROR; /* 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, (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); continue; } #endif /* WITH_RETRY */ default: return result; } /* this cannot fork because we retrieved fork option above */ result = _xioopen_connect (xfd, needbind?(struct sockaddr *)us:NULL, sizeof(*us), (struct sockaddr *)them, themlen, opts, pf, socktype, IPPROTO_TCP, lowport, 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); continue; } #endif /* WITH_RETRY */ default: return result; } applyopts(xfd->fd, opts, PH_ALL); if ((result = _xio_openlate(xfd, opts)) < 0) return result; result = _xioopen_socks4_connect(xfd, 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); continue; } #endif /* WITH_RETRY */ default: return result; } if (dofork) { xiosetchilddied(); /* set SIGCHLD handler */ } #if WITH_RETRY if (dofork) { pid_t pid; int level = E_ERROR; if (xfd->forever || xfd->retry) { level = E_WARN; /* most users won't expect a problem here, so Notice is too weak */ } while ((pid = xio_fork(false, level)) < 0) { if (xfd->forever || --xfd->retry) { Nanosleep(&xfd->intervall, NULL); continue; } return STAT_RETRYLATER; } if (pid == 0) { /* child process */ xfd->forever = false; xfd->retry = 0; break; } /* parent process */ Close(xfd->fd); Nanosleep(&xfd->intervall, NULL); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); continue; } else #endif /* WITH_RETRY */ { break; } } while (true); /* end of complete open loop - drop out on success */ return 0; } int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen) { struct servent *se; char *userid; /* generate socks header - points to final target */ sockhead->version = 4; sockhead->action = 1; sockhead->port = parseport(targetport, IPPROTO_TCP); /* network byte order */ if (retropt_string(opts, OPT_SOCKSPORT, socksport) < 0) { if ((se = getservbyname("socks", "tcp")) != NULL) { Debug1("\"socks/tcp\" resolves to %u", ntohs(se->s_port)); if ((*socksport = Malloc(6)) == NULL) { return -1; } sprintf(*socksport, "%u", ntohs(se->s_port)); } else { Debug1("cannot resolve service \"socks/tcp\", using %s", SOCKSPORT); if ((*socksport = strdup(SOCKSPORT)) == NULL) { errno = ENOMEM; return -1; } } } if (retropt_string(opts, OPT_SOCKSUSER, &userid) < 0) { if ((userid = getenv("LOGNAME")) == NULL) { if ((userid = getenv("USER")) == NULL) { userid = "anonymous"; } } } sockhead->userid[0] = '\0'; strncat(sockhead->userid, userid, *headlen-SIZEOF_STRUCT_SOCKS4-1); *headlen = SIZEOF_STRUCT_SOCKS4+strlen(userid)+1; return STAT_OK; } /* called within retry/fork loop, before connect() */ int _xioopen_socks4_connect0(struct single *xfd, const char *hostname, /* socks target host */ int socks4a, struct socks4 *sockhead, ssize_t *headlen, /* get available space, return used length*/ int level) { int result; if (!socks4a) { union sockaddr_union sau; socklen_t saulen = sizeof(sau); if ((result = xiogetaddrinfo(hostname, NULL, PF_INET, SOCK_STREAM, IPPROTO_TCP, &sau, &saulen, xfd->para.socket.ip.res_opts[1], xfd->para.socket.ip.res_opts[0])) != STAT_OK) { return result; /*! STAT_RETRY? */ } memcpy(&sockhead->dest, &sau.ip4.sin_addr, 4); } #if WITH_SOCKS4A else { /*! noresolve */ sockhead->dest = htonl(0x00000001); /* three bytes zero */ } #endif /* WITH_SOCKS4A */ #if WITH_SOCKS4A if (socks4a) { /* SOCKS4A requires us to append the host name to resolve after the user name's trailing 0 byte. */ char* insert_position = (char*) sockhead + *headlen; insert_position[0] = '\0'; strncat(insert_position, hostname, BUFF_LEN-*headlen-1); ((char *)sockhead)[BUFF_LEN-1] = 0; *headlen += strlen(hostname) + 1; if (*headlen > BUFF_LEN) { *headlen = BUFF_LEN; } } #endif /* WITH_SOCKS4A */ return STAT_OK; } /* perform socks4 client dialog on existing FD. Called within fork/retry loop, after connect() */ int _xioopen_socks4_connect(struct single *xfd, struct socks4 *sockhead, size_t headlen, int level) { ssize_t bytes; int result; unsigned char buff[SIZEOF_STRUCT_SOCKS4]; struct socks4 *replyhead = (struct socks4 *)buff; char *destdomname = NULL; /* send socks header (target addr+port, +auth) */ #if WITH_MSGLEVEL <= E_INFO if (ntohl(sockhead->dest) <= 0x000000ff) { destdomname = strchr(sockhead->userid, '\0')+1; } Info11("sending socks4%s request VN=%d DC=%d DSTPORT=%d DSTIP=%d.%d.%d.%d USERID=%s%s%s", destdomname?"a":"", sockhead->version, sockhead->action, ntohs(sockhead->port), ((unsigned char *)&sockhead->dest)[0], ((unsigned char *)&sockhead->dest)[1], ((unsigned char *)&sockhead->dest)[2], ((unsigned char *)&sockhead->dest)[3], sockhead->userid, destdomname?" DESTNAME=":"", destdomname?destdomname:""); #endif /* WITH_MSGLEVEL <= E_INFO */ #if WITH_MSGLEVEL <= E_DEBUG { char *msgbuff; if ((msgbuff = Malloc(3*headlen)) != NULL) { xiohexdump((const unsigned char *)sockhead, headlen, msgbuff); Debug1("sending socks4(a) request data %s", msgbuff); } } #endif /* WITH_MSGLEVEL <= E_DEBUG */ if (writefull(xfd->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)); } return STAT_RETRYLATER; /* retry complete open cycle */ } bytes = 0; Info("waiting for socks reply"); 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); } while (result < 0 && errno == EINTR); if (result < 0) { Msg4(level, "read(%d, %p, "F_Zu"): %s", xfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes, strerror(errno)); if (Close(xfd->fd) < 0) { Info2("close(%d): %s", xfd->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)); } return STAT_RETRYLATER; } #if WITH_MSGLEVEL <= E_DEBUG { char msgbuff[3*SIZEOF_STRUCT_SOCKS4]; * xiohexdump((const unsigned char *)replyhead+bytes, result, msgbuff) = '\0'; Debug2("received socks4 reply data (offset "F_Zd"): %s", bytes, msgbuff); } #endif /* WITH_MSGLEVEL <= E_DEBUG */ bytes += result; if (bytes == SIZEOF_STRUCT_SOCKS4) { Debug1("received all "F_Zd" bytes", bytes); break; } Debug2("received %d bytes, waiting for "F_Zu" more bytes", result, SIZEOF_STRUCT_SOCKS4-bytes); } if (result <= 0) { /* we had a problem while reading socks answer */ return STAT_RETRYLATER; /* retry complete open cycle */ } Info7("received socks reply VN=%u CD=%u DSTPORT=%u DSTIP=%u.%u.%u.%u", replyhead->version, replyhead->action, ntohs(replyhead->port), ((uint8_t *)&replyhead->dest)[0], ((uint8_t *)&replyhead->dest)[1], ((uint8_t *)&replyhead->dest)[2], ((uint8_t *)&replyhead->dest)[3]); if (replyhead->version != 0) { Warn1("socks: reply code version is not 0 (%d)", replyhead->version); } switch (replyhead->action) { case SOCKS_CD_GRANTED: /* Notice("socks: connect request succeeded"); */ #if 0 if (Getsockname(xfd->fd, (struct sockaddr *)&us, &uslen) < 0) { Warn4("getsockname(%d, %p, {%d}): %s", xfd->fd, &us, uslen, strerror(errno)); } Notice1("successfully connected from %s via socks4", sockaddr_info((struct sockaddr *)&us, infobuff, sizeof(infobuff))); #else Notice("successfully connected via socks4"); #endif break; case SOCKS_CD_FAILED: Msg(level, "socks: connect request rejected or failed"); return STAT_RETRYLATER; case SOCKS_CD_NOIDENT: Msg(level, "socks: ident refused by client"); return STAT_RETRYLATER; case SOCKS_CD_IDENTFAILED: Msg(level, "socks: ident failed"); return STAT_RETRYLATER; default: Msg1(level, "socks: undefined status %u", replyhead->action); } return STAT_OK; } #endif /* WITH_SOCKS4 || WITH_SOCKS4A */ socat-1.7.3.1/sysutils.h0000644000201000020100000000614412460670272014643 0ustar gerhardgerhard/* source: sysutils.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __sysutils_h_included #define __sysutils_h_included 1 #if WITH_IP6 /* not all OSes provide in6_addr that allows splitting to 16 or 32 bit junks of the host address part of sockaddr_in6; here we help ourselves */ union xioin6_u { uint8_t u6_addr8[16]; uint16_t u6_addr16[8]; uint32_t u6_addr32[4]; } ; #endif /* WITH_IP6 */ #if _WITH_SOCKET union sockaddr_union { struct sockaddr soa; #if WITH_UNIX struct sockaddr_un un; #endif /* WITH_UNIX */ #if _WITH_IP4 struct sockaddr_in ip4; #endif /* _WITH_IP4 */ #if WITH_IP6 struct sockaddr_in6 ip6; #endif /* WITH_IP6 */ #if WITH_INTERFACE struct sockaddr_ll ll; #endif } ; #endif /* _WITH_SOCKET */ #if _WITH_SOCKET struct xiorange { union sockaddr_union netaddr; union sockaddr_union netmask; } ; #endif /* _WITH_SOCKET */ extern ssize_t writefull(int fd, const void *buff, size_t bytes); #if _WITH_SOCKET extern socklen_t socket_init(int af, union sockaddr_union *sa); #endif #if WITH_UNIX extern void socket_un_init(struct sockaddr_un *sa); #endif /* WITH_UNIX */ #if _WITH_IP4 extern void socket_in_init(struct sockaddr_in *sa); #endif /* _WITH_IP4 */ #if _WITH_IP6 extern void socket_in6_init(struct sockaddr_in6 *sa); #endif /* _WITH_IP4 */ #if _WITH_SOCKET extern char *sockaddr_info(const struct sockaddr *sa, socklen_t salen, char *buff, size_t blen); #endif #if WITH_UNIX extern char *sockaddr_unix_info(const struct sockaddr_un *sa, socklen_t salen, char *buff, size_t blen); #endif /* WITH_UNIX */ #if WITH_IP4 extern char *inet4addr_info(uint32_t addr, char *buff, size_t blen); extern char *sockaddr_inet4_info(const struct sockaddr_in *sa, char *buff, size_t blen); #endif /* WITH_IP4 */ #if WITH_IP6 extern char *sockaddr_inet6_info(const struct sockaddr_in6 *sa, char *buff, size_t blen); #endif /* WITH_IP6 */ #if !HAVE_INET_NTOP extern const char *inet_ntop(int pf, const void *binaddr, char *addrtext, socklen_t textlen); #endif #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT) extern int getusergroups(const char *user, gid_t *list, int *ngroups); #endif #if !HAVE_HSTRERROR extern const char *hstrerror(int err); #endif extern int xiopoll(struct pollfd fds[], unsigned long nfds, struct timeval *timeout); extern int parseport(const char *portname, int proto); extern int ifindexbyname(const char *ifname, int anysock); extern int ifindex(const char *ifname, unsigned int *ifindex, int anysock); extern int xiosetenv(const char *varname, const char *value, int overwrite, const char *sep); extern int xiosetenv2(const char *varname, const char *varname2, const char *value, int overwrite, const char *sep); extern int xiosetenv3(const char *varname, const char *varname2, const char *varname3, const char *value, int overwrite, const char *sep); extern int xiosetenvulong(const char *varname, unsigned long value, int overwrite); extern int xiosetenvushort(const char *varname, unsigned short value, int overwrite); #endif /* !defined(__sysutils_h_included) */ socat-1.7.3.1/xio-termios.h0000644000201000020100000001315512460670272015223 0ustar gerhardgerhard/* source: xio-termios.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_termios_h_included #define __xio_termios_h_included 1 extern const struct optdesc opt_tiocsctty; extern const struct optdesc opt_brkint; extern const struct optdesc opt_icrnl; extern const struct optdesc opt_ignbrk; extern const struct optdesc opt_igncr; extern const struct optdesc opt_ignpar; extern const struct optdesc opt_imaxbel; extern const struct optdesc opt_inlcr; extern const struct optdesc opt_inpck; extern const struct optdesc opt_istrip; extern const struct optdesc opt_iuclc; extern const struct optdesc opt_ixany; extern const struct optdesc opt_ixoff; extern const struct optdesc opt_ixon; extern const struct optdesc opt_parmrk; extern const struct optdesc opt_cr0; extern const struct optdesc opt_cr1; extern const struct optdesc opt_cr2; extern const struct optdesc opt_cr3; extern const struct optdesc opt_crdly; extern const struct optdesc opt_nl0; extern const struct optdesc opt_nl1; extern const struct optdesc opt_nldly; extern const struct optdesc opt_ocrnl; extern const struct optdesc opt_ofdel; extern const struct optdesc opt_ofill; extern const struct optdesc opt_opost; extern const struct optdesc opt_olcuc; extern const struct optdesc opt_onlcr; extern const struct optdesc opt_onlret; extern const struct optdesc opt_onocr; extern const struct optdesc opt_tab0; extern const struct optdesc opt_tab1; extern const struct optdesc opt_tab2; extern const struct optdesc opt_tab3; extern const struct optdesc opt_xtabs; extern const struct optdesc opt_tabdly; extern const struct optdesc opt_bs0; extern const struct optdesc opt_bs1; extern const struct optdesc opt_bsdly; extern const struct optdesc opt_vt0; extern const struct optdesc opt_vt1; extern const struct optdesc opt_vtdly; extern const struct optdesc opt_ff0; extern const struct optdesc opt_ff1; extern const struct optdesc opt_ffdly; extern const struct optdesc opt_b0; extern const struct optdesc opt_b50; extern const struct optdesc opt_b75; extern const struct optdesc opt_b110; extern const struct optdesc opt_b134; extern const struct optdesc opt_b150; extern const struct optdesc opt_b200; extern const struct optdesc opt_b300; extern const struct optdesc opt_b600; extern const struct optdesc opt_b900; extern const struct optdesc opt_b1200; extern const struct optdesc opt_b1800; extern const struct optdesc opt_b2400; extern const struct optdesc opt_b3600; extern const struct optdesc opt_b4800; extern const struct optdesc opt_b7200; extern const struct optdesc opt_b9600; extern const struct optdesc opt_b19200; extern const struct optdesc opt_b38400; extern const struct optdesc opt_b57600; extern const struct optdesc opt_b115200; extern const struct optdesc opt_b230400; extern const struct optdesc opt_b460800; extern const struct optdesc opt_b500000; extern const struct optdesc opt_b576000; extern const struct optdesc opt_b921600; extern const struct optdesc opt_b1000000; extern const struct optdesc opt_b1152000; extern const struct optdesc opt_b1500000; extern const struct optdesc opt_b2000000; extern const struct optdesc opt_b2500000; extern const struct optdesc opt_b3000000; extern const struct optdesc opt_b3500000; extern const struct optdesc opt_b4000000; extern const struct optdesc opt_cs5; extern const struct optdesc opt_cs6; extern const struct optdesc opt_cs7; extern const struct optdesc opt_cs8; extern const struct optdesc opt_csize; extern const struct optdesc opt_cstopb; extern const struct optdesc opt_cread; extern const struct optdesc opt_parenb; extern const struct optdesc opt_parodd; extern const struct optdesc opt_hupcl; extern const struct optdesc opt_clocal; /*extern const struct optdesc opt_cibaud*/ extern const struct optdesc opt_crtscts; extern const struct optdesc opt_isig; extern const struct optdesc opt_icanon; extern const struct optdesc opt_xcase; extern const struct optdesc opt_echo; extern const struct optdesc opt_echoe; extern const struct optdesc opt_echok; extern const struct optdesc opt_echonl; extern const struct optdesc opt_echoctl; extern const struct optdesc opt_echoprt; extern const struct optdesc opt_echoke; extern const struct optdesc opt_flusho; extern const struct optdesc opt_noflsh; extern const struct optdesc opt_tostop; extern const struct optdesc opt_pendin; extern const struct optdesc opt_iexten; extern const struct optdesc opt_vintr; extern const struct optdesc opt_vquit; extern const struct optdesc opt_verase; extern const struct optdesc opt_vkill; extern const struct optdesc opt_veof; extern const struct optdesc opt_vtime; extern const struct optdesc opt_vmin; extern const struct optdesc opt_vswtc; extern const struct optdesc opt_vstart; extern const struct optdesc opt_vstop; extern const struct optdesc opt_vsusp; extern const struct optdesc opt_vdsusp; extern const struct optdesc opt_veol; extern const struct optdesc opt_vreprint; extern const struct optdesc opt_vdiscard; extern const struct optdesc opt_vwerase; extern const struct optdesc opt_vlnext; extern const struct optdesc opt_veol2; extern const struct optdesc opt_raw; extern const struct optdesc opt_sane; extern const struct optdesc opt_ispeed; extern const struct optdesc opt_ospeed; extern const struct optdesc opt_termios_rawer; extern const struct optdesc opt_termios_cfmakeraw; #if _WITH_TERMIOS /* otherwise tcflag_t might be reported undefined */ extern int xiotermios_setflag(int fd, int word, tcflag_t mask); extern int xiotermios_clrflag(int fd, int word, tcflag_t mask); extern int xiotermiosflag_applyopt(int fd, struct opt *opt); #endif /* _WITH_TERMIOS */ #endif /* !defined(__xio_termios_h_included) */ socat-1.7.3.1/error.h0000644000201000020100000002476112460670272014102 0ustar gerhardgerhard/* source: error.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __error_h_included #define __error_h_included 1 /* these must be defines because they are used by cpp! */ #define E_DEBUG 0 /* all, including trace */ #define E_INFO 1 /* all status changes etc. */ #define E_NOTICE 2 /* all interesting, e.g. for firewall relay */ #define E_WARN 3 /* all unusual */ #define E_ERROR 4 /* errors */ #define E_FATAL 5 /* emergency abort */ #define F_strerror "%m" /* a pseudo format, replaced by strerror(errno) */ /* here are the macros for diag invocation; use WITH_MSGLEVEL to specify the lowest priority that is compiled into your program */ #ifndef WITH_MSGLEVEL # define WITH_MSGLEVEL E_NOTICE #endif #if WITH_MSGLEVEL <= E_FATAL #define Fatal(m) msg(E_FATAL,"%s",m) #define Fatal1(m,a1) msg(E_FATAL,m,a1) #define Fatal2(m,a1,a2) msg(E_FATAL,m,a1,a2) #define Fatal3(m,a1,a2,a3) msg(E_FATAL,m,a1,a2,a3) #define Fatal4(m,a1,a2,a3,a4) msg(E_FATAL,m,a1,a2,a3,a4) #define Fatal5(m,a1,a2,a3,a4,a5) msg(E_FATAL,m,a1,a2,a3,a4,a5) #define Fatal6(m,a1,a2,a3,a4,a5,a6) msg(E_FATAL,m,a1,a2,a3,a4,a5,a6) #define Fatal7(m,a1,a2,a3,a4,a5,a6,a7) msg(E_FATAL,m,a1,a2,a3,a4,a5,a6,a7) #else /* !(WITH_MSGLEVEL <= E_FATAL) */ #define Fatal(m) #define Fatal1(m,a1) #define Fatal2(m,a1,a2) #define Fatal3(m,a1,a2,a3) #define Fatal4(m,a1,a2,a3,a4) #define Fatal5(m,a1,a2,a3,a4,a5) #define Fatal6(m,a1,a2,a3,a4,a5,a6) #define Fatal7(m,a1,a2,a3,a4,a5,a6,a7) #endif /* !(WITH_MSGLEVEL <= E_FATAL) */ #if WITH_MSGLEVEL <= E_ERROR #define Error(m) msg(E_ERROR,"%s",m) #define Error1(m,a1) msg(E_ERROR,m,a1) #define Error2(m,a1,a2) msg(E_ERROR,m,a1,a2) #define Error3(m,a1,a2,a3) msg(E_ERROR,m,a1,a2,a3) #define Error4(m,a1,a2,a3,a4) msg(E_ERROR,m,a1,a2,a3,a4) #define Error5(m,a1,a2,a3,a4,a5) msg(E_ERROR,m,a1,a2,a3,a4,a5) #define Error6(m,a1,a2,a3,a4,a5,a6) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6) #define Error7(m,a1,a2,a3,a4,a5,a6,a7) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7) #define Error8(m,a1,a2,a3,a4,a5,a6,a7,a8) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8) #define Error9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8,a9) #define Error10(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) #define Error11(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) #else /* !(WITH_MSGLEVEL >= E_ERROR) */ #define Error(m) #define Error1(m,a1) #define Error2(m,a1,a2) #define Error3(m,a1,a2,a3) #define Error4(m,a1,a2,a3,a4) #define Error5(m,a1,a2,a3,a4,a5) #define Error6(m,a1,a2,a3,a4,a5,a6) #define Error7(m,a1,a2,a3,a4,a5,a6,a7) #define Error8(m,a1,a2,a3,a4,a5,a6,a7,a8) #define Error9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9) #define Error10(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) #define Error11(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) #endif /* !(WITH_MSGLEVEL <= E_ERROR) */ #if WITH_MSGLEVEL <= E_WARN #define Warn(m) msg(E_WARN,"%s",m) #define Warn1(m,a1) msg(E_WARN,m,a1) #define Warn2(m,a1,a2) msg(E_WARN,m,a1,a2) #define Warn3(m,a1,a2,a3) msg(E_WARN,m,a1,a2,a3) #define Warn4(m,a1,a2,a3,a4) msg(E_WARN,m,a1,a2,a3,a4) #define Warn5(m,a1,a2,a3,a4,a5) msg(E_WARN,m,a1,a2,a3,a4,a5) #define Warn6(m,a1,a2,a3,a4,a5,a6) msg(E_WARN,m,a1,a2,a3,a4,a5,a6) #define Warn7(m,a1,a2,a3,a4,a5,a6,a7) msg(E_WARN,m,a1,a2,a3,a4,a5,a6,a7) #else /* !(WITH_MSGLEVEL <= E_WARN) */ #define Warn(m) #define Warn1(m,a1) #define Warn2(m,a1,a2) #define Warn3(m,a1,a2,a3) #define Warn4(m,a1,a2,a3,a4) #define Warn5(m,a1,a2,a3,a4,a5) #define Warn6(m,a1,a2,a3,a4,a5,a6) #define Warn7(m,a1,a2,a3,a4,a5,a6,a7) #endif /* !(WITH_MSGLEVEL <= E_WARN) */ #if WITH_MSGLEVEL <= E_NOTICE #define Notice(m) msg(E_NOTICE,"%s",m) #define Notice1(m,a1) msg(E_NOTICE,m,a1) #define Notice2(m,a1,a2) msg(E_NOTICE,m,a1,a2) #define Notice3(m,a1,a2,a3) msg(E_NOTICE,m,a1,a2,a3) #define Notice4(m,a1,a2,a3,a4) msg(E_NOTICE,m,a1,a2,a3,a4) #define Notice5(m,a1,a2,a3,a4,a5) msg(E_NOTICE,m,a1,a2,a3,a4,a5) #define Notice6(m,a1,a2,a3,a4,a5,a6) msg(E_NOTICE,m,a1,a2,a3,a4,a5,a6) #define Notice7(m,a1,a2,a3,a4,a5,a6,a7) msg(E_NOTICE,m,a1,a2,a3,a4,a5,a6,a7) #define Notice8(m,a1,a2,a3,a4,a5,a6,a7,a8) msg(E_NOTICE,m,a1,a2,a3,a4,a5,a6,a7,a8) #define Notice9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9) msg(E_NOTICE,m,a1,a2,a3,a4,a5,a6,a7,a8,a9) #else /* !(WITH_MSGLEVEL <= E_NOTICE) */ #define Notice(m) #define Notice1(m,a1) #define Notice2(m,a1,a2) #define Notice3(m,a1,a2,a3) #define Notice4(m,a1,a2,a3,a4) #define Notice5(m,a1,a2,a3,a4,a5) #define Notice6(m,a1,a2,a3,a4,a5,a6) #define Notice7(m,a1,a2,a3,a4,a5,a6,a7) #define Notice8(m,a1,a2,a3,a4,a5,a6,a7,a8) #define Notice9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9) #endif /* !(WITH_MSGLEVEL <= E_NOTICE) */ #if WITH_MSGLEVEL <= E_INFO #define Info(m) msg(E_INFO,"%s",m) #define Info1(m,a1) msg(E_INFO,m,a1) #define Info2(m,a1,a2) msg(E_INFO,m,a1,a2) #define Info3(m,a1,a2,a3) msg(E_INFO,m,a1,a2,a3) #define Info4(m,a1,a2,a3,a4) msg(E_INFO,m,a1,a2,a3,a4) #define Info5(m,a1,a2,a3,a4,a5) msg(E_INFO,m,a1,a2,a3,a4,a5) #define Info6(m,a1,a2,a3,a4,a5,a6) msg(E_INFO,m,a1,a2,a3,a4,a5,a6) #define Info7(m,a1,a2,a3,a4,a5,a6,a7) msg(E_INFO,m,a1,a2,a3,a4,a5,a6,a7) #define Info8(m,a1,a2,a3,a4,a5,a6,a7,a8) msg(E_INFO,m,a1,a2,a3,a4,a5,a6,a7,a8) #define Info9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9) msg(E_INFO,m,a1,a2,a3,a4,a5,a6,a7,a8,a9) #define Info10(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) msg(E_INFO,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) #define Info11(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) msg(E_INFO,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) #else /* !(WITH_MSGLEVEL <= E_INFO) */ #define Info(m) #define Info1(m,a1) #define Info2(m,a1,a2) #define Info3(m,a1,a2,a3) #define Info4(m,a1,a2,a3,a4) #define Info5(m,a1,a2,a3,a4,a5) #define Info6(m,a1,a2,a3,a4,a5,a6) #define Info7(m,a1,a2,a3,a4,a5,a6,a7) #define Info8(m,a1,a2,a3,a4,a5,a6,a7,a8) #define Info9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9) #define Info10(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) #define Info11(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) #endif /* !(WITH_MSGLEVEL <= E_INFO) */ #if WITH_MSGLEVEL <= E_DEBUG #define Debug(m) msg(E_DEBUG,"%s",m) #define Debug1(m,a1) msg(E_DEBUG,m,a1) #define Debug2(m,a1,a2) msg(E_DEBUG,m,a1,a2) #define Debug3(m,a1,a2,a3) msg(E_DEBUG,m,a1,a2,a3) #define Debug4(m,a1,a2,a3,a4) msg(E_DEBUG,m,a1,a2,a3,a4) #define Debug5(m,a1,a2,a3,a4,a5) msg(E_DEBUG,m,a1,a2,a3,a4,a5) #define Debug6(m,a1,a2,a3,a4,a5,a6) msg(E_DEBUG,m,a1,a2,a3,a4,a5,a6) #define Debug7(m,a1,a2,a3,a4,a5,a6,a7) msg(E_DEBUG,m,a1,a2,a3,a4,a5,a6,a7) #define Debug8(m,a1,a2,a3,a4,a5,a6,a7,a8) msg(E_DEBUG,m,a1,a2,a3,a4,a5,a6,a7,a8) #define Debug9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9) msg(E_DEBUG,m,a1,a2,a3,a4,a5,a6,a7,a8,a9) #define Debug10(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) msg(E_DEBUG,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) #define Debug11(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) msg(E_DEBUG,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) #define Debug12(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) msg(E_DEBUG,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) #define Debug13(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13) msg(E_DEBUG,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13) #define Debug14(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14) msg(E_DEBUG,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14) #define Debug15(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) msg(E_DEBUG,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) #define Debug16(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16) msg(E_DEBUG,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16) #define Debug17(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17) msg(E_DEBUG,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17) #define Debug18(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18) msg(E_DEBUG,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18) #else /* !(WITH_MSGLEVEL <= E_DEBUG) */ #define Debug(m) #define Debug1(m,a1) #define Debug2(m,a1,a2) #define Debug3(m,a1,a2,a3) #define Debug4(m,a1,a2,a3,a4) #define Debug5(m,a1,a2,a3,a4,a5) #define Debug6(m,a1,a2,a3,a4,a5,a6) #define Debug7(m,a1,a2,a3,a4,a5,a6,a7) #define Debug8(m,a1,a2,a3,a4,a5,a6,a7,a8) #define Debug9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9) #define Debug10(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) #define Debug11(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) #define Debug12(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) #define Debug13(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13) #define Debug14(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14) #define Debug15(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) #define Debug16(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16) #define Debug17(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17) #define Debug18(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18) #endif /* !(WITH_MSGLEVEL <= E_DEBUG) */ /* message with software controlled serverity */ #if WITH_MSGLEVEL <= E_FATAL #define Msg(l,m) msg(l,"%s",m) #define Msg1(l,m,a1) msg(l,m,a1) #define Msg2(l,m,a1,a2) msg(l,m,a1,a2) #define Msg3(l,m,a1,a2,a3) msg(l,m,a1,a2,a3) #define Msg4(l,m,a1,a2,a3,a4) msg(l,m,a1,a2,a3,a4) #define Msg5(l,m,a1,a2,a3,a4,a5) msg(l,m,a1,a2,a3,a4,a5) #define Msg6(l,m,a1,a2,a3,a4,a5,a6) msg(l,m,a1,a2,a3,a4,a5,a6) #define Msg7(l,m,a1,a2,a3,a4,a5,a6,a7) msg(l,m,a1,a2,a3,a4,a5,a6,a7) #else /* !(WITH_MSGLEVEL >= E_FATAL) */ #define Msg(l,m) #define Msg1(l,m,a1) #define Msg2(l,m,a1,a2) #define Msg3(l,m,a1,a2,a3) #define Msg4(l,m,a1,a2,a3,a4) #define Msg5(l,m,a1,a2,a3,a4,a5) #define Msg6(l,m,a1,a2,a3,a4,a5,a6) #define Msg7(l,m,a1,a2,a3,a4,a5,a6,a7) #endif /* !(WITH_MSGLEVEL <= E_FATAL) */ enum diag_op { DIAG_OP_MSG, /* a diagnostic message */ DIAG_OP_EXIT, /* exit the program */ } ; /* datagram for communication between outer msg() call from signal handler to inner msg() call in normal flow */ # define TEXTLEN 480 struct diag_dgram { enum diag_op op; #if HAVE_CLOCK_GETTIME struct timespec now; #elif HAVE_GETTIMEOFDAY struct timeval now; #else time_t now; #endif int level; /* E_FATAL, ... E_DEBUG */ int _errno; /* for glibc %m format */ int exitcode; /* if exiting take this num */ char text[TEXTLEN]; } ; extern sig_atomic_t diag_in_handler; extern int diag_immediate_msg; extern int diag_immediate_exit; extern void diag_set(char what, const char *arg); extern void diag_set_int(char what, int arg); extern int diag_get_int(char what); extern const char *diag_get_string(char what); extern int diag_dup(void); extern int diag_dup2(int newfd); extern void msg(int level, const char *format, ...); extern void diag_flush(void); extern void diag_exit(int status); extern int diag_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); #endif /* !defined(__error_h_included) */ socat-1.7.3.1/filan.c0000644000201000020100000006054012455415361014030 0ustar gerhardgerhard/* source: filan.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* the subroutine filan makes a "FILe descriptor ANalysis". It checks the type of file descriptor and tries to retrieve as much info about it as possible without modifying its state. NOTE: it works on UNIX (kernel) file descriptors, not on libc files! */ #include "config.h" #include "xioconfig.h" /* what features are enabled */ #include "sysincludes.h" #include "mytypes.h" #include "compat.h" #include "error.h" #include "sycls.h" #include "sysutils.h" #include "filan.h" struct sockopt { int so; char *name; }; static int filan_streams_analyze(int fd, FILE *outfile); /* dirty workaround so we dont get an error on AIX when being linked with libwrap */ int allow_severity, deny_severity; /* global variables for configuring filan */ bool filan_followsymlinks; bool filan_rawoutput; int sockoptan(int fd, const struct sockopt *optname, int socklay, FILE *outfile); int tcpan(int fd, FILE *outfile); const char *getfiletypestring(int st_mode); static int printtime(FILE *outfile, time_t time); static int headprinted; /* analyse a file system entry, referred by file name */ int filan_file(const char *filename, FILE *outfile) { int fd = -1; int result; #if HAVE_STAT64 struct stat64 buf = {0}; #else struct stat buf = {0}; #endif /* !HAVE_STAT64 */ if (filan_followsymlinks) { #if HAVE_STAT64 result = Stat64(filename, &buf); #else result = Stat(filename, &buf); #endif /* !HAVE_STAT64 */ if (result < 0) { Warn3("stat(\"%s\", %p): %s", filename, &buf, strerror(errno)); } } else { #if HAVE_STAT64 result = Lstat64(filename, &buf); #else result = Lstat(filename, &buf); #endif /* !HAVE_STAT64 */ if (result < 0) { Warn3("lstat(\"%s\", %p): %s", filename, &buf, strerror(errno)); } } switch (buf.st_mode&S_IFMT) { #ifdef S_IFSOCK case S_IFSOCK: /* probably, it's useless to make a socket and describe it */ break; #endif /* S_IFSOCK */ default: if ((fd = Open(filename, O_RDONLY|O_NOCTTY|O_NONBLOCK #ifdef O_LARGEFILE |O_LARGEFILE #endif , 0700)) < 0) { Warn2("open(\"%s\", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE, 0700): %s", filename, strerror(errno)); } } result = filan_stat(&buf, fd, -1, outfile); fputc('\n', outfile); return result; } /* analyze a file descriptor */ int filan_fd(int fd, FILE *outfile) { #if HAVE_STAT64 struct stat64 buf = {0}; #else struct stat buf = {0}; #endif /* !HAVE_STAT64 */ int result; Debug1("checking file descriptor %u", fd); #if HAVE_STAT64 result = Fstat64(fd, &buf); #else result = Fstat(fd, &buf); #endif /* !HAVE_STAT64 */ if (result < 0) { if (errno == EBADF) { Debug2("fstat(%d): %s", fd, strerror(errno)); } else { Warn2("fstat(%d): %s", fd, strerror(errno)); } return -1; } Debug2("fd %d is a %s", fd, getfiletypestring(buf.st_mode)); result = filan_stat(&buf, fd, fd, outfile); if (result >= 0) { /* even more dynamic info */ { /* see if data is available */ struct pollfd ufds; ufds.fd = fd; ufds.events = POLLIN|POLLPRI|POLLOUT #ifdef POLLRDNORM |POLLRDNORM #endif #ifdef POLLRDBAND |POLLRDBAND #endif |POLLWRNORM #ifdef POLLWRBAND |POLLWRBAND #endif #ifdef POLLMSG |POLLMSG #endif ; if (Poll(&ufds, 1, 0) < 0) { Warn4("poll({%d, %hd, %hd}, 1, 0): %s", ufds.fd, ufds.events, ufds.revents, strerror(errno)); } else { fputs("poll: ", outfile); if (ufds.revents & POLLIN) fputs("IN,", outfile); if (ufds.revents & POLLPRI) fputs("PRI,", outfile); if (ufds.revents & POLLOUT) fputs("OUT,", outfile); if (ufds.revents & POLLERR) fputs("ERR,", outfile); if (ufds.revents & POLLNVAL) fputs("NVAL,", outfile); #ifdef FIONREAD if (ufds.revents & POLLIN) { size_t sizet; if ((result = Ioctl(fd, FIONREAD, &sizet) >= 0)) { fprintf (outfile, "; FIONREAD="F_Zu, sizet); } } #endif /* defined(FIONREAD) */ #if _WITH_SOCKET && defined(MSG_DONTWAIT) if ((ufds.revents & POLLIN) && isasocket(fd)) { char _peername[SOCKADDR_MAX]; struct sockaddr *pa = (struct sockaddr *)_peername; struct msghdr msgh = {0}; char peekbuff[1]; /* [0] fails with some compilers */ #if HAVE_STRUCT_IOVEC struct iovec iovec; #endif char ctrlbuff[5120]; ssize_t bytes; fputs("; ", outfile); msgh.msg_name = pa; msgh.msg_namelen = sizeof(*pa); #if HAVE_STRUCT_IOVEC iovec.iov_base = peekbuff; iovec.iov_len = sizeof(peekbuff); msgh.msg_iov = &iovec; msgh.msg_iovlen = 1; #endif #if HAVE_STRUCT_MSGHDR_MSGCONTROL msgh.msg_control = ctrlbuff; #endif #if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN msgh.msg_controllen = sizeof(ctrlbuff); #endif #if HAVE_STRUCT_MSGHDR_MSGFLAGS msgh.msg_flags = 0; #endif if ((bytes = Recvmsg(fd, &msgh, MSG_PEEK|MSG_DONTWAIT)) < 0) { Warn1("recvmsg(): %s", strerror(errno)); } else { fprintf(outfile, "recvmsg="F_Zd", ", bytes); } } #endif /* _WITH_SOCKET && defined(MSG_DONTWAIT) */ } } } fputc('\n', outfile); return 0; } int filan_stat( #if HAVE_STAT64 struct stat64 *buf #else struct stat *buf #endif /* !HAVE_STAT64 */ , int statfd, int dynfd, FILE *outfile) { char stdevstr[8]; /* print header */ if (!headprinted) { if (filan_rawoutput) { fputs(" FD type\tdevice\tinode\tmode\tlinks\tuid\tgid" #if HAVE_ST_RDEV "\trdev" #endif "\tsize" #if HAVE_ST_BLKSIZE "\tblksize" #endif #if HAVE_ST_BLOCKS "\tblocks" #endif "\tatime\t\tmtime\t\tctime\t\tcloexec\tflags" #if defined(F_GETOWN) "\tsigown" #endif , outfile); } else /* !rawoutput */ { fputs(" FD type\tdevice\tinode\tmode\tlinks\tuid\tgid" #if HAVE_ST_RDEV "\trdev" #endif "\tsize" #if HAVE_ST_BLKSIZE "\tblksize" #endif #if HAVE_ST_BLOCKS "\tblocks" #endif "\tatime\t\t\t\tmtime\t\t\t\tctime\t\t\t\tcloexec\tflags" #if defined(F_GETOWN) "\tsigown" #endif , outfile); } /* endif !rawoutput */ #if defined(F_GETSIG) fputs("\tsigio", outfile); #endif /* defined(F_GETSIG) */ fputc('\n', outfile); headprinted = 1; } if (filan_rawoutput) { snprintf(stdevstr, 8, F_dev, buf->st_dev); } else { snprintf(stdevstr, 8, "%hu,%hu", (unsigned short)(buf->st_dev>>8), (unsigned short)(buf->st_dev&0xff)); } fprintf(outfile, "%4d: %s\t%s\t" #if HAVE_STAT64 F_st64_ino #else F_st_ino #endif /* HAVE_STAT64 */ "\t"F_mode"\t"F_st_nlink"\t"F_uid"\t"F_gid #if HAVE_ST_RDEV "\t%hu,%hu" #endif "\t" #if HAVE_STAT64 F_st64_size #else F_st_size #endif /* HAVE_STAT64 */ #if HAVE_ST_BLKSIZE "\t"F_st_blksize #endif #if HAVE_ST_BLOCKS #if HAVE_STAT64 "\t"F_st64_blocks #else "\t"F_st_blocks #endif /* HAVE_STAT64 */ #endif , (dynfd>=0?dynfd:statfd), getfiletypestring(buf->st_mode), stdevstr, buf->st_ino, buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid, #if HAVE_ST_RDEV (unsigned short)(buf->st_rdev>>8), (unsigned short)(buf->st_rdev&0xff), #endif buf->st_size #if HAVE_ST_BLKSIZE , buf->st_blksize #endif #if HAVE_ST_BLOCKS , buf->st_blocks /* on Linux, this applies to stat and stat64 */ #endif ); printtime(outfile, buf->st_atime); printtime(outfile, buf->st_mtime); printtime(outfile, buf->st_ctime); #if 0 { fputc('\t', outfile); time = asctime(localtime(&buf->st_mtime)); if (strchr(time, '\n')) *strchr(time, '\n') = '\0'; fputs(time, outfile); fputc('\t', outfile); time = asctime(localtime(&buf->st_ctime)); if (strchr(time, '\n')) *strchr(time, '\n') = '\0'; fputs(time, outfile); } #endif /* here comes dynamic info - it is only meaningful with preexisting FDs */ if (dynfd >= 0) { /*!indent */ int cloexec, flags; #if defined(F_GETOWN) int sigown; #endif #if defined(F_GETSIG) int sigio; #endif /* defined(F_GETSIG) */ cloexec = Fcntl(dynfd, F_GETFD); flags = Fcntl(dynfd, F_GETFL); #if defined(F_GETOWN) sigown = Fcntl(dynfd, F_GETOWN); #endif #if defined(F_GETSIG) sigio = Fcntl(dynfd, F_GETSIG); #endif /* defined(F_GETSIG) */ fprintf(outfile, "\t%d\tx%06x", cloexec, flags); #if defined(F_GETOWN) fprintf(outfile, "\t%d", sigown); #endif #if defined(F_GETSIG) fprintf(outfile, "\t%d", sigio); #endif /* defined(F_GETSIG) */ } else { fputs("\t\t" #if defined(F_GETOWN) "\t" #endif #if defined(F_GETSIG) "\t" #endif /* defined(F_GETSIG) */ , outfile); } /* ever heard of POSIX streams? here we handle these */ filan_streams_analyze(statfd, outfile); /* now see for type specific infos */ if (statfd >= 0) { /*!indent */ switch (buf->st_mode&S_IFMT) { case (S_IFIFO): /* 1, FIFO */ break; case (S_IFCHR): /* 2, character device */ cdevan(statfd, outfile); break; case (S_IFDIR): /* 4, directory */ break; case (S_IFBLK): /* 6, block device */ break; case (S_IFREG): /* 8, regular file */ break; case (S_IFLNK): /* 10, symbolic link */ break; #ifdef S_IFSOCK case (S_IFSOCK): /* 12, socket */ #if _WITH_SOCKET sockan(statfd, outfile); #else Warn("SOCKET support not compiled in"); return -1; #endif /* !_WITH_SOCKET */ break; #endif /* S_IFSOCK */ } } /* ioctl() */ return 0; } #if LATER int fdinfo(int fd) { int result; result = Fcntl(fd, F_GETFD); fcntl(fd, F_GETFL, ); fcntl(fd, F_GETLK, ); #ifdef F_GETOWN fcntl(fd, F_GETOWN, ); #endif #ifdef F_GETSIG fcntl(fd, F_GETSIG, ); #endif } int devinfo(int fd) { ioctl(); } #endif /* returns 0 on success (not a stream descriptor, or no module) returns <0 on failure */ static int filan_streams_analyze(int fd, FILE *outfile) { #ifdef I_LIST # define SL_NMODS 8 /* max number of module names we can store */ struct str_list modnames; int i; if (!isastream(fd)) { fprintf(outfile, "\t(no STREAMS modules)"); return 0; } #if 0 /* uncomment for debugging */ fprintf(outfile, "\tfind=%d", ioctl(fd, I_FIND, "ldterm")); #endif modnames.sl_nmods = ioctl(fd, I_LIST, 0); if (modnames.sl_nmods < 0) { fprintf(stderr, "ioctl(%d, I_LIST, 0): %s\n", fd, strerror(errno)); return -1; } modnames.sl_modlist = Malloc(modnames.sl_nmods*(sizeof(struct str_mlist))); if (modnames.sl_modlist == NULL) { fprintf(stderr, "out of memory\n"); return -1; } if (ioctl(fd, I_LIST, &modnames) < 0) { fprintf(stderr, "ioctl(%d, I_LIST, %p): %s\n", fd, &modnames, strerror(errno)); free(modnames.sl_modlist); return -1; } fprintf(outfile, "\tSTREAMS: "); for (i = 0; i < modnames.sl_nmods; ++i) { fprintf(outfile, "\"%s\"", modnames.sl_modlist[i].l_name); if (i+1 < modnames.sl_nmods) fputc(',', outfile); } free(modnames.sl_modlist); #endif /* defined(I_LIST) */ return 0; } /* character device analysis */ int cdevan(int fd, FILE *outfile) { int ret; #if _WITH_TERMIOS if ((ret = Isatty(fd)) < 0) { Warn2("isatty(%d): %s", fd, strerror(errno)); return -1; } if (ret > 0) { struct termios termarg; char *name; int i; if ((name = Ttyname(fd)) == NULL) { /*Warn2("ttyname(%d): %s", fd, strerror(errno));*/ fputs("\tNULL", outfile); } else { fprintf(outfile, "\t%s", name); } if (Tcgetattr(fd, &termarg) < 0) { Warn3("tcgetattr(%d, %p): %s", fd, &termarg, strerror(errno)); return -1; } fprintf(outfile, " \tIFLAGS=%08x OFLAGS=%08x CFLAGS=%08x LFLAGS=%08x", (unsigned int)termarg.c_iflag, (unsigned int)termarg.c_oflag, (unsigned int)termarg.c_cflag, (unsigned int)termarg.c_lflag); /* and the control characters */ if (filan_rawoutput) { for (i=0; i>4)>=10?(ch>>4)-10+'A':(ch>>4)+'0'; s[2] = (ch&0x0f)>=10?(ch&0x0f)-10+'A':(ch&0x0f)+'0'; s[3] = '\0'; } fprintf(outfile, " cc[%d]=%s", i, s); } } } #endif /* _WITH_TERMIOS */ return 0; } #if _WITH_SOCKET int sockan(int fd, FILE *outfile) { #define FILAN_OPTLEN 256 #define FILAN_NAMELEN 256 socklen_t optlen; int result /*0, i*/; static const char *socktypes[] = { "undef", "STREAM", "DGRAM", "RAW", "RDM", "SEQPACKET", "undef", "undef", "undef", "undef", "PACKET", "undef" } ; char nambuff[FILAN_NAMELEN]; /* in Linux these optcodes are 'enum', but on AIX they are bits! */ static const struct sockopt sockopts[] = { {SO_DEBUG, "DEBUG"}, {SO_REUSEADDR, "REUSEADDR"}, {SO_TYPE, "TYPE"}, {SO_ERROR, "ERROR"}, #ifdef SO_PROTOTYPE {SO_PROTOTYPE, "PROTOTYPE"}, #endif {SO_DONTROUTE, "DONTROUTE"}, {SO_BROADCAST, "BROADCAST"}, {SO_SNDBUF, "SNDBUF"}, {SO_RCVBUF, "RCVBUF"}, {SO_KEEPALIVE, "KEEPALIVE"}, {SO_OOBINLINE, "OOBINLINE"}, #ifdef SO_NO_CHECK {SO_NO_CHECK, "NO_CHECK"}, #endif #ifdef SO_PRIORITY {SO_PRIORITY, "PRIORITY"}, #endif {SO_LINGER, "LINGER"}, #ifdef SO_BSDCOMPAT {SO_BSDCOMPAT, "BSDCOMPAT"}, #endif #ifdef SO_REUSEPORT {SO_REUSEPORT, "REUSEPORT"}, #endif /* defined(SO_REUSEPORT) */ #ifdef SO_PASSCRED {SO_PASSCRED, "PASSCRED"}, #endif #ifdef SO_PEERCRED {SO_PEERCRED, "PEERCRED"}, #endif #ifdef SO_RCVLOWAT {SO_RCVLOWAT, "RCVLOWAT"}, #endif #ifdef SO_SNDLOWAT {SO_SNDLOWAT, "SNDLOWAT"}, #endif #ifdef SO_RCVTIMEO {SO_RCVTIMEO, "RCVTIMEO"}, #endif #ifdef SO_SNDTIMEO {SO_SNDTIMEO, "SNDTIMEO"}, #endif #ifdef SO_SECURITY_AUTHENTICATION {SO_SECURITY_AUTHENTICATION, "SECURITY_AUTHENTICATION"}, #endif #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT {SO_SECURITY_ENCRYPTION_TRANSPORT, "SECURITY_ENCRYPTION_TRANSPORT"}, #endif #ifdef SO_SECURITY_ENCRYPTION_NETWORK {SO_SECURITY_ENCRYPTION_NETWORK, "SECURITY_ENCRYPTION_NETWORK"}, #endif #ifdef SO_BINDTODEVICE {SO_BINDTODEVICE, "BINDTODEVICE"}, #endif #ifdef SO_ATTACH_FILTER {SO_ATTACH_FILTER, "ATTACH_FILTER"}, #endif #ifdef SO_DETACH_FILTER {SO_DETACH_FILTER, "DETACH_FILTER"}, #endif {0, NULL} } ; union { char c[FILAN_OPTLEN]; int i[FILAN_OPTLEN/sizeof(int)]; } optval; const struct sockopt *optname; union sockaddr_union sockname, peername; /* the longest I know of */ socklen_t namelen; #if 0 && defined(SIOCGIFNAME) /*Linux struct ifreq ifc = {{{ 0 }}};*/ struct ifreq ifc = {{ 0 }}; #endif optlen = FILAN_OPTLEN; result = Getsockopt(fd, SOL_SOCKET, SO_TYPE, optval.c, &optlen); if (result < 0) { Debug4("getsockopt(%d, SOL_SOCKET, SO_TYPE, %p, {"F_socklen"}): %s", fd, optval.c, optlen, strerror(errno)); } else { Debug3("fd %d: socket of type %d (\"%s\")", fd, *optval.i, socktypes[*optval.i]); } optname = sockopts; while (optname->so) { optlen = FILAN_OPTLEN; result = Getsockopt(fd, SOL_SOCKET, optname->so, (void *)optval.c, &optlen); if (result < 0) { Debug5("getsockopt(%d, SOL_SOCKET, %d, %p, {"F_socklen"}): %s", fd, optname->so, optval.c, optlen, strerror(errno)); fputc('\t', outfile); } else if (optlen == sizeof(int)) { Debug2("getsockopt(,,, {%d}, %d)", *optval.i, optlen); /*Info2("%s: %d", optname->name, optval.i);*/ fprintf(outfile, "%s=%d\t", optname->name, *optval.i); } else { Debug3("getsockopt(,,, {%d,%d}, %d)", optval.i[0], optval.i[1], optlen); fprintf(outfile, "%s={%d,%d}\t", optname->name, optval.i[0], optval.i[1]); } ++optname; } namelen = sizeof(sockname); result = Getsockname(fd, (struct sockaddr *)&sockname, &namelen); if (result < 0) { putc('\n', outfile); Warn2("getsockname(%d): %s", fd, strerror(errno)); return -1; } fputc('\t', outfile); fputs(sockaddr_info((struct sockaddr *)&sockname, namelen, nambuff, sizeof(nambuff)), outfile); namelen = sizeof(peername); result = Getpeername(fd, (struct sockaddr *)&peername, &namelen); if (result < 0) { putc('\n', outfile); Warn2("getpeername(%d): %s", fd, strerror(errno)); } else { /* only valid if getpeername() succeeded */ fputs(" <-> ", outfile); fprintf(outfile, "%s\t", sockaddr_info((struct sockaddr *)&peername, namelen, nambuff, sizeof(nambuff))); } #if 0 && defined(SIOCGIFNAME) if ((result = Ioctl(fd, SIOCGIFNAME, &ifc)) < 0) { Warn3("ioctl(%d, SIOCGIFNAME, %p): %s", fd, &ifc, strerror(errno)); } else { fprintf(outfile, "IFNAME=\"%s\"\t", ifc.ifr_name); } #endif /* SIOCGIFNAME */ switch (((struct sockaddr *)&sockname)->sa_family) { #if WITH_UNIX case AF_UNIX: /* no options for unix domain sockets known yet -> no unixan() */ result = 0; break; #endif #if WITH_IP4 case AF_INET: result = ipan(fd, outfile); break; #endif #if WITH_IP6 case AF_INET6: result = ipan(fd, outfile); result |= ip6an(fd, outfile); break; #endif default: fputs("**** NO FURTHER ANALYSIS FOR THIS SOCKET TYPE IMPLEMENTED", outfile); result = 0; } return result; #undef FILAN_OPTLEN #undef FILAN_NAMELEN } #endif /* _WITH_SOCKET */ #if WITH_IP4 || WITH_IP6 /* prints the option values for the IP protocol and the IP based protocols */ /* no distinction between IP4 and IP6 yet */ int ipan(int fd, FILE *outfile) { /* in Linux these optcodes are 'enum', but on AIX they are bits! */ static const struct sockopt ipopts[] = { {IP_TOS, "IP_TOS"}, {IP_TTL, "IP_TTL"}, #ifdef IP_HDRINCL {IP_HDRINCL, "IP_HDRINCL"}, #endif #ifdef IP_OPTIONS {IP_OPTIONS, "IP_OPTIONS"}, #endif #ifdef IP_ROUTER_ALERT {IP_ROUTER_ALERT, "IP_ROUTER_ALERT"}, #endif #ifdef IP_RECVOPTS {IP_RECVOPTS, "IP_RECVOPTS"}, #endif #ifdef IP_RETOPTS {IP_RETOPTS, "IP_RETOPTS"}, #endif #ifdef IP_PKTINFO {IP_PKTINFO, "IP_PKTINFO"}, #endif #ifdef IP_PKTOPTIONS {IP_PKTOPTIONS, "IP_PKTOPTIONS"}, #endif #ifdef IP_MTU_DISCOVER {IP_MTU_DISCOVER, "IP_MTU_DISCOVER"}, #endif #ifdef IP_RECVERR {IP_RECVERR, "IP_RECVERR"}, #endif #ifdef IP_RECVTTL {IP_RECVTTL, "IP_RECVTTL"}, #endif #ifdef IP_RECVTOS {IP_RECVTOS, "IP_RECVTOS"}, #endif #ifdef IP_MTU {IP_MTU, "IP_MTU"}, #endif #ifdef IP_FREEBIND {IP_FREEBIND, "IP_FREEBIND"}, #endif #ifdef IP_MULTICAST_TTL {IP_MULTICAST_TTL, "IP_MULTICAST_TTL"}, #endif #ifdef IP_MULTICAST_LOOP {IP_MULTICAST_LOOP, "IP_MULTICAST_LOOP"}, #endif {0, NULL} } ; const struct sockopt *optname; int opttype; socklen_t optlen = sizeof(opttype); optname = ipopts; while (optname->so) { sockoptan(fd, optname, SOL_IP, outfile); ++optname; } /* want to pass the fd to the next layer protocol. dont know how to get the protocol number from the fd? use TYPE to identify TCP. */ if (Getsockopt(fd, SOL_SOCKET, SO_TYPE, &opttype, &optlen) >= 0) { switch (opttype) { #if WITH_TCP case SOCK_STREAM: tcpan(fd, outfile); break; #endif } } return 0; } #endif /* WITH_IP */ #if WITH_IP6 /* prints the option values for the IPv6 protocol */ int ip6an(int fd, FILE *outfile) { static const struct sockopt ip6opts[] = { #ifdef IPV6_V6ONLY {IPV6_V6ONLY, "IPV6_V6ONLY"}, #endif {0, NULL} } ; const struct sockopt *optname; optname = ip6opts; while (optname->so) { sockoptan(fd, optname, SOL_IPV6, outfile); ++optname; } return 0; } #endif /* WITH_IP6 */ #if WITH_TCP int tcpan(int fd, FILE *outfile) { static const struct sockopt tcpopts[] = { #ifdef TCP_NODELAY { TCP_NODELAY, "TCP_NODELAY" }, #endif #ifdef TCP_MAXSEG { TCP_MAXSEG, "TCP_MAXSEG" }, #endif #ifdef TCP_STDURG { TCP_STDURG, "TCP_STDURG" }, #endif #ifdef TCP_RFC1323 { TCP_RFC1323, "TCP_RFC1323" }, #endif #ifdef TCP_CORK { TCP_CORK, "TCP_CORK" }, #endif #ifdef TCP_KEEPIDLE { TCP_KEEPIDLE, "TCP_KEEPIDLE" }, #endif #ifdef TCP_KEEPINTVL { TCP_KEEPINTVL, "TCP_KEEPINTVL" }, #endif #ifdef TCP_KEEPCNT { TCP_KEEPCNT, "TCP_KEEPCNT" }, #endif #ifdef TCP_SYNCNT { TCP_SYNCNT, "TCP_SYNCNT" }, #endif #ifdef TCP_LINGER2 { TCP_LINGER2, "TCP_LINGER2" }, #endif #ifdef TCP_DEFER_ACCEPT { TCP_DEFER_ACCEPT, "TCP_ACCEPT" }, #endif #ifdef TCP_WINDOW_CLAMP { TCP_WINDOW_CLAMP, "TCP_WINDOW_CLAMP" }, #endif #ifdef TCP_INFO { TCP_INFO, "TCP_INFO" }, #endif #ifdef TCP_QUICKACK { TCP_QUICKACK, "TCP_QUICKACK" }, #endif #ifdef TCP_MD5SIG { TCP_MD5SIG, "TCP_MD5SIG" }, #endif #ifdef TCP_NOOPT { TCP_NOOPT, "TCP_NOOPT" }, #endif #ifdef TCP_NOPUSH { TCP_NOPUSH, "TCP_NOPUSH" }, #endif #ifdef TCP_SACK_DISABLE { TCP_SACK_DISABLE, "TCP_SACK_DISABLE" }, #endif #ifdef TCP_SIGNATURE_ENABLE { TCP_SIGNATURE_ENABLE, "TCP_SIGNATURE_ENABLE" }, #endif #ifdef TCP_ABORT_THRESHOLD { TCP_ABORT_THRESHOLD, "TCP_ABORT_THRESHOLD" }, #endif #ifdef TCP_CONN_ABORT_THRESHOLD { TCP_CONN_ABORT_THRESHOLD, "TCP_CONN_ABORT_THRESHOLD" }, #endif #ifdef TCP_KEEPINIT { TCP_KEEPINIT, "TCP_KEEPINIT" }, #endif #ifdef TCP_PAWS { TCP_PAWS, "TCP_PAWS" }, #endif #ifdef TCP_SACKENA { TCP_SACKENA, "TCP_SACKENA" }, #endif #ifdef TCP_TSOPTENA { TCP_TSOPTENA, "TCP_TSOPTENA" }, #endif {0, NULL} } ; const struct sockopt *optname; optname = tcpopts; while (optname->so) { sockoptan(fd, optname, SOL_TCP, outfile); ++optname; } return 0; } #endif /* WITH_TCP */ #if _WITH_SOCKET int sockoptan(int fd, const struct sockopt *optname, int socklay, FILE *outfile) { #define FILAN_OPTLEN 256 union { char c[FILAN_OPTLEN]; int i[FILAN_OPTLEN/sizeof(int)]; } optval; socklen_t optlen; int result; optlen = FILAN_OPTLEN; result = Getsockopt(fd, socklay, optname->so, (void *)optval.c, &optlen); if (result < 0) { Debug6("getsockopt(%d, %d, %d, %p, {"F_socklen"}): %s", fd, socklay, optname->so, optval.c, optlen, strerror(errno)); fputc('\t', outfile); return -1; } else if (optlen == 0) { Debug1("getsockopt(,,, {}, %d)", optlen); fprintf(outfile, "%s=\"\"\t", optname->name); } else if (optlen == sizeof(int)) { Debug2("getsockopt(,,, {%d}, %d)", *optval.i, optlen); fprintf(outfile, "%s=%d\t", optname->name, *optval.i); } else { char outbuf[FILAN_OPTLEN*9+128], *cp = outbuf; int i; for (i = 0; i < optlen/sizeof(unsigned int); ++i) { cp += sprintf(cp, "%08x ", (unsigned int)optval.i[i]); } *--cp = '\0'; /* delete trailing space */ Debug2("getsockopt(,,, {%s}, %d)", outbuf, optlen); fflush(outfile); fprintf(outfile, "%s={%s}\t", optname->name, outbuf); } return 0; #undef FILAN_OPTLEN } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int isasocket(int fd) { int retval; #if HAVE_STAT64 struct stat64 props; #else struct stat props; #endif /* HAVE_STAT64 */ retval = #if HAVE_STAT64 Fstat64(fd, &props); #else Fstat(fd, &props); #endif if (retval < 0) { Info3("fstat(%d, %p): %s", fd, &props, strerror(errno)); return 0; } /* note: when S_ISSOCK was undefined, it always gives 0 */ return S_ISSOCK(props.st_mode); } #endif /* _WITH_SOCKET */ const char *getfiletypestring(int st_mode) { const char *s; switch (st_mode&S_IFMT) { case S_IFIFO: s = "pipe"; break; case S_IFCHR: s = "chrdev"; break; case S_IFDIR: s = "dir"; break; case S_IFBLK: s = "blkdev"; break; case S_IFREG: s = "file"; break; case S_IFLNK: s = "symlink"; break; case S_IFSOCK: s = "socket"; break; /*! AIX: MT? */ default: s = "undef"; break; } return s; } static int printtime(FILE *outfile, time_t time) { const char *s; if (filan_rawoutput) { fprintf(outfile, "\t"F_time, time); } else { fputc('\t', outfile); s = asctime(localtime(&time)); if (strchr(s, '\n')) *strchr(s, '\n') = '\0'; fputs(s, outfile); } return 0; } socat-1.7.3.1/xio-progcall.c0000644000201000020100000004527712460670272015351 0ustar gerhardgerhard/* source: xio-progcall.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains common code dealing with program calls (exec, system) */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-process.h" #include "xio-progcall.h" #include "xio-socket.h" /* these options are used by address pty too */ #if HAVE_OPENPTY const struct optdesc opt_openpty = { "openpty", NULL, OPT_OPENPTY, GROUP_PTY, PH_BIGEN, TYPE_BOOL, OFUNC_SPEC }; #endif /* HAVE_OPENPTY */ #if HAVE_DEV_PTMX || HAVE_DEV_PTC const struct optdesc opt_ptmx = { "ptmx", NULL, OPT_PTMX, GROUP_PTY, PH_BIGEN, TYPE_BOOL, OFUNC_SPEC }; #endif #if WITH_EXEC || WITH_SYSTEM #define MAXPTYNAMELEN 64 const struct optdesc opt_fdin = { "fdin", NULL, OPT_FDIN, GROUP_FORK, PH_PASTBIGEN, TYPE_USHORT, OFUNC_SPEC }; const struct optdesc opt_fdout = { "fdout", NULL, OPT_FDOUT, GROUP_FORK, PH_PASTBIGEN, TYPE_USHORT, OFUNC_SPEC }; const struct optdesc opt_path = { "path", NULL, OPT_PATH, GROUP_EXEC, PH_PREEXEC, TYPE_STRING, OFUNC_SPEC }; const struct optdesc opt_pipes = { "pipes", NULL, OPT_PIPES, GROUP_FORK, PH_BIGEN, TYPE_BOOL, OFUNC_SPEC }; #if HAVE_PTY const struct optdesc opt_pty = { "pty", NULL, OPT_PTY, GROUP_FORK, PH_BIGEN, TYPE_BOOL, OFUNC_SPEC }; #endif const struct optdesc opt_stderr = { "stderr", NULL, OPT_STDERR, GROUP_FORK, PH_PASTFORK, TYPE_BOOL, OFUNC_SPEC }; const struct optdesc opt_nofork = { "nofork", NULL, OPT_NOFORK, GROUP_FORK, PH_BIGEN, TYPE_BOOL, OFUNC_SPEC }; const struct optdesc opt_sighup = { "sighup", NULL, OPT_SIGHUP, GROUP_PARENT, PH_LATE, TYPE_CONST, OFUNC_SIGNAL, SIGHUP }; const struct optdesc opt_sigint = { "sigint", NULL, OPT_SIGINT, GROUP_PARENT, PH_LATE, TYPE_CONST, OFUNC_SIGNAL, SIGINT }; const struct optdesc opt_sigquit = { "sigquit", NULL, OPT_SIGQUIT, GROUP_PARENT, PH_LATE, TYPE_CONST, OFUNC_SIGNAL, SIGQUIT }; /* fork for exec/system, but return before exec'ing. return=0: is child process return>0: is parent process return<0: error occurred, assume parent process and no child exists !!! */ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ struct single *fd, unsigned groups, struct opt **copts, /* in: opts; out: opts for child */ int *duptostderr /* out: redirect stderr to output fd */ ) { struct opt *popts; /* parent process options */ int numleft; int d, sv[2], rdpip[2], wrpip[2]; int rw = (xioflags & XIO_ACCMODE); bool usepipes = false; #if HAVE_PTY int ptyfd = -1, ttyfd = -1; bool usebestpty = false; /* use the best available way to open pty */ #if defined(HAVE_DEV_PTMX) || defined(HAVE_DEV_PTC) bool useptmx = false; /* use /dev/ptmx or equivalent */ #endif #if HAVE_OPENPTY bool useopenpty = false; /* try only openpty */ #endif /* HAVE_OPENPTY */ bool usepty = false; /* any of the pty options is selected */ char ptyname[MAXPTYNAMELEN]; #endif /* HAVE_PTY */ pid_t pid = 0; /* mostly int */ short fdi = 0, fdo = 1; short result; bool withstderr = false; bool nofork = false; bool withfork; popts = moveopts(*copts, GROUP_ALL); if (applyopts_single(fd, popts, PH_INIT) < 0) return -1; applyopts2(-1, popts, PH_INIT, PH_EARLY); retropt_bool(popts, OPT_NOFORK, &nofork); withfork = !nofork; retropt_bool(popts, OPT_PIPES, &usepipes); #if HAVE_PTY retropt_bool(popts, OPT_PTY, &usebestpty); #if HAVE_OPENPTY retropt_bool(popts, OPT_OPENPTY, &useopenpty); #endif #if defined(HAVE_DEV_PTMX) || defined(HAVE_DEV_PTC) retropt_bool(popts, OPT_PTMX, &useptmx); #endif usepty = (usebestpty #if HAVE_OPENPTY || useopenpty #endif #if defined(HAVE_DEV_PTMX) || defined(HAVE_DEV_PTC) || useptmx #endif ); if (usepipes && usepty) { Warn("_xioopen_foxec(): options \"pipes\" and \"pty\" must not be specified together; ignoring \"pipes\""); usepipes = false; } #endif /* HAVE_PTY */ if (retropt_ushort(popts, OPT_FDIN, (unsigned short *)&fdi) >= 0) { if ((xioflags&XIO_ACCMODE) == XIO_RDONLY) { Error("_xioopen_foxec(): option fdin is useless in read-only mode"); } } if (retropt_ushort(popts, OPT_FDOUT, (unsigned short *)&fdo) >= 0) { if ((xioflags&XIO_ACCMODE) == XIO_WRONLY) { Error("_xioopen_foxec(): option fdout is useless in write-only mode"); } } if (withfork) { if (!(xioflags&XIO_MAYCHILD)) { Error("cannot fork off child process here"); /*!! free something */ return -1; } fd->flags |= XIO_DOESCHILD; #if HAVE_PTY Notice2("forking off child, using %s for %s", &("socket\0\0pipes\0\0\0pty\0\0\0\0\0"[(usepipes<<3)|(usepty<<4)]), ddirection[rw]); #else Notice2("forking off child, using %s for %s", &("socket\0\0pipes\0\0\0"[(usepipes<<3)]), ddirection[rw]); #endif /* HAVE_PTY */ } applyopts(-1, popts, PH_PREBIGEN); if (!withfork) { /*0 struct single *stream1, *stream2;*/ if (!(xioflags & XIO_MAYEXEC /* means exec+nofork */)) { Error("option nofork is not allowed here"); /*!! free something */ return -1; } fd->flags |= XIO_DOESEXEC; free(*copts); *copts = moveopts(popts, GROUP_ALL); #if 0 /*!! */ if (sock1->tag == XIO_TAG_DUAL) { stream1 = &sock1->dual.stream[0]->stream; stream2 = &sock1->dual.stream[1]->stream; } else { stream1 = &sock1->stream; stream2 = &sock1->stream; } if (stream1->dtype == DATA_READLINE || stream2->dtype == DATA_READLINE || stream1->dtype == DATA_OPENSSL || stream2->dtype == DATA_OPENSSL ) { Error("with option nofork, openssl and readline in address1 do not work"); } if (stream1->lineterm != LINETERM_RAW || stream2->lineterm != LINETERM_RAW || stream1->ignoreeof || stream2->ignoreeof) { Warn("due to option nofork, address1 options for lineterm and igoreeof do not apply"); } #endif /*! problem: when fdi==WRFD(sock[0]) or fdo==RDFD(sock[0]) */ if (rw != XIO_WRONLY) { if (XIO_GETRDFD(sock[0]/*!!*/) == fdi) { if (Fcntl_l(fdi, F_SETFD, 0) < 0) { Warn2("fcntl(%d, F_SETFD, 0): %s", fdi, strerror(errno)); } if (Dup2(XIO_GETRDFD(sock[0]), fdi) < 0) { Error3("dup2(%d, %d): %s", XIO_GETRDFD(sock[0]), fdi, strerror(errno)); } /*0 Info2("dup2(%d, %d)", XIO_GETRDFD(sock[0]), fdi);*/ } else { if (Dup2(XIO_GETRDFD(sock[0]), fdi) < 0) { Error3("dup2(%d, %d): %s", XIO_GETRDFD(sock[0]), fdi, strerror(errno)); } /*0 Info2("dup2(%d, %d)", XIO_GETRDFD(sock[0]), fdi);*/ } } if (rw != XIO_RDONLY) { if (XIO_GETWRFD(sock[0]) == fdo) { if (Fcntl_l(fdo, F_SETFD, 0) < 0) { Warn2("fcntl(%d, F_SETFD, 0): %s", fdo, strerror(errno)); } if (Dup2(XIO_GETWRFD(sock[0]), fdo) < 0) { Error3("dup2(%d, %d): %s)", XIO_GETWRFD(sock[0]), fdo, strerror(errno)); } /*0 Info2("dup2(%d, %d)", XIO_GETWRFD(sock[0]), fdo);*/ } else { if (Dup2(XIO_GETWRFD(sock[0]), fdo) < 0) { Error3("dup2(%d, %d): %s)", XIO_GETWRFD(sock[0]), fdo, strerror(errno)); } /*0 Info2("dup2(%d, %d)", XIO_GETWRFD(sock[0]), fdo);*/ } } } else #if HAVE_PTY if (usepty) { #if defined(HAVE_DEV_PTMX) # define PTMX "/dev/ptmx" /* Linux */ #elif HAVE_DEV_PTC # define PTMX "/dev/ptc" /* AIX 4.3.3 */ #endif fd->dtype = XIODATA_PTY; #if HAVE_DEV_PTMX || HAVE_DEV_PTC if (usebestpty || useptmx) { if ((ptyfd = Open(PTMX, O_RDWR|O_NOCTTY, 0620)) < 0) { Warn1("open(\""PTMX"\", O_RDWR|O_NOCTTY, 0620): %s", strerror(errno)); /*!*/ } else { /*0 Info2("open(\"%s\", O_RDWR|O_NOCTTY, 0620) -> %d", PTMX, ptyfd);*/ } if (ptyfd >= 0 && ttyfd < 0) { char *tn = NULL; /* we used PTMX before forking */ extern char *ptsname(int); #if HAVE_GRANTPT /* AIX, not Linux */ if (Grantpt(ptyfd)/*!*/ < 0) { Warn2("grantpt(%d): %s", ptyfd, strerror(errno)); } #endif /* HAVE_GRANTPT */ #if HAVE_UNLOCKPT if (Unlockpt(ptyfd)/*!*/ < 0) { Warn2("unlockpt(%d): %s", ptyfd, strerror(errno)); } #endif /* HAVE_UNLOCKPT */ #if HAVE_PROTOTYPE_LIB_ptsname /* AIX, not Linux */ if ((tn = Ptsname(ptyfd)) == NULL) { Warn2("ptsname(%d): %s", ptyfd, strerror(errno)); } #endif /* HAVE_PROTOTYPE_LIB_ptsname */ if (tn == NULL) { if ((tn = Ttyname(ptyfd)) == NULL) { Error2("ttyname(%d): %s", ptyfd, strerror(errno)); } } ptyname[0] = '\0'; strncat(ptyname, tn, MAXPTYNAMELEN-1); if ((ttyfd = Open(tn, O_RDWR|O_NOCTTY, 0620)) < 0) { Warn2("open(\"%s\", O_RDWR|O_NOCTTY, 0620): %s", tn, strerror(errno)); } else { /*0 Info2("open(\"%s\", O_RDWR|O_NOCTTY, 0620) -> %d", tn, ttyfd);*/ } #ifdef I_PUSH /* Linux: I_PUSH def'd; pty: ioctl(, I_FIND, ...) -> -1 EINVAL */ /* AIX: I_PUSH def'd; pty: ioctl(, I_FIND, ...) -> 1 */ /* SunOS: I_PUSH def'd; pty: ioctl(, I_FIND, ...) -> 0 */ /* HP-UX: I_PUSH def'd; pty: ioctl(, I_FIND, ...) -> 0 */ if (Ioctl(ttyfd, I_FIND, "ldterm") == 0) { Ioctl(ttyfd, I_PUSH, "ptem"); /* 0 */ Ioctl(ttyfd, I_PUSH, "ldterm"); /* 0 */ Ioctl(ttyfd, I_PUSH, "ttcompat"); /* HP-UX: -1 */ } #endif #if 0 /* the following block need not work */ if (ttyfd >= 0 && ((tn = Ttyname(ttyfd)) == NULL)) { Warn2("ttyname(%d): %s", ttyfd, strerror(errno)); } if (tn == NULL) { Error("could not open pty"); return -1; } #endif Info1("opened pseudo terminal %s", tn); } } #endif /* HAVE_DEV_PTMX || HAVE_DEV_PTC */ #if HAVE_OPENPTY if (ptyfd < 0) { int result; if ((result = Openpty(&ptyfd, &ttyfd, ptyname, NULL, NULL)) < 0) { Error4("openpty(%p, %p, %p, NULL, NULL): %s", &ptyfd, &ttyfd, ptyname, strerror(errno)); return -1; } } #endif /* HAVE_OPENPTY */ free(*copts); if ((*copts = moveopts(popts, GROUP_TERMIOS|GROUP_FORK|GROUP_EXEC|GROUP_PROCESS)) == NULL) { return -1; } applyopts_cloexec(ptyfd, popts);/*!*/ /* exec:...,pty did not kill child process under some circumstances */ if (fd->howtoend == END_UNSPEC) { fd->howtoend = END_CLOSE_KILL; } /* this for parent, was after fork */ applyopts(ptyfd, popts, PH_FD); applyopts(ptyfd, popts, PH_LATE); if (applyopts_single(fd, popts, PH_LATE) < 0) return -1; fd->fd = ptyfd; /* this for child, was after fork */ applyopts(ttyfd, *copts, PH_FD); } else #endif /* HAVE_PTY */ if (usepipes) { struct opt *popts2, *copts2; if (rw == XIO_RDWR) fd->dtype = XIODATA_2PIPE; if (rw != XIO_WRONLY) { if (Pipe(rdpip) < 0) { Error2("pipe(%p): %s", rdpip, strerror(errno)); return -1; } } /*0 Info2("pipe({%d,%d})", rdpip[0], rdpip[1]);*/ /* rdpip[0]: read by socat; rdpip[1]: write by child */ free(*copts); if ((*copts = moveopts(popts, GROUP_FORK|GROUP_EXEC|GROUP_PROCESS)) == NULL) { return -1; } popts2 = copyopts(popts, GROUP_ALL); copts2 = copyopts(*copts, GROUP_ALL); if (rw != XIO_WRONLY) { applyopts_cloexec(rdpip[0], popts); applyopts(rdpip[0], popts, PH_FD); applyopts(rdpip[1], *copts, PH_FD); } if (rw != XIO_RDONLY) { if (Pipe(wrpip) < 0) { Error2("pipe(%p): %s", wrpip, strerror(errno)); return -1; } } /*0 Info2("pipe({%d,%d})", wrpip[0], wrpip[1]);*/ /* wrpip[1]: write by socat; wrpip[0]: read by child */ if (rw != XIO_RDONLY) { applyopts_cloexec(wrpip[1], popts2); applyopts(wrpip[1], popts2, PH_FD); applyopts(wrpip[0], copts2, PH_FD); } if (fd->howtoend == END_UNSPEC) { fd->howtoend = END_CLOSE_KILL; } /* this for parent, was after fork */ switch (rw) { case XIO_RDONLY: fd->fd = rdpip[0]; break; case XIO_WRONLY: fd->fd = wrpip[1]; break; case XIO_RDWR: fd->fd = rdpip[0]; fd->para.exec.fdout = wrpip[1]; break; } applyopts(fd->fd, popts, PH_FD); applyopts(fd->fd, popts, PH_LATE); if (applyopts_single(fd, popts, PH_LATE) < 0) return -1; } else { d = AF_UNIX; retropt_int(popts, OPT_PROTOCOL_FAMILY, &d); result = xiosocketpair(popts, d, SOCK_STREAM, 0, sv); if (result < 0) { return -1; } /*0 Info5("socketpair(%d, %d, %d, {%d,%d})", d, type, protocol, sv[0], sv[1]);*/ free(*copts); if ((*copts = moveopts(popts, GROUP_FORK|GROUP_EXEC|GROUP_PROCESS)) == NULL) { return -1; } applyopts(sv[0], *copts, PH_PASTSOCKET); applyopts(sv[1], popts, PH_PASTSOCKET); applyopts_cloexec(sv[0], *copts); applyopts(sv[0], *copts, PH_FD); applyopts(sv[1], popts, PH_FD); applyopts(sv[0], *copts, PH_PREBIND); applyopts(sv[0], *copts, PH_BIND); applyopts(sv[0], *copts, PH_PASTBIND); applyopts(sv[1], popts, PH_PREBIND); applyopts(sv[1], popts, PH_BIND); applyopts(sv[1], popts, PH_PASTBIND); if (fd->howtoend == END_UNSPEC) { fd->howtoend = END_SHUTDOWN_KILL; } /* this for parent, was after fork */ fd->fd = sv[0]; applyopts(fd->fd, popts, PH_FD); applyopts(fd->fd, popts, PH_LATE); if (applyopts_single(fd, popts, PH_LATE) < 0) return -1; } /*0 if ((optpr = copyopts(*copts, GROUP_PROCESS)) == NULL) return -1;*/ retropt_bool(*copts, OPT_STDERR, &withstderr); xiosetchilddied(); /* set SIGCHLD handler */ if (withfork) { pid = xio_fork(true, E_ERROR); if (pid < 0) { return -1; } } if (!withfork || pid == 0) { /* child */ uid_t user; gid_t group; if (withfork) { /* The child should have default handling for SIGCHLD. */ /* In particular, it's not defined whether ignoring SIGCHLD is inheritable. */ if (Signal(SIGCHLD, SIG_DFL) == SIG_ERR) { Warn1("signal(SIGCHLD, SIG_DFL): %s", strerror(errno)); } #if HAVE_PTY if (usepty) { Close(ptyfd); if (rw != XIO_RDONLY && fdi != ttyfd) { if (Dup2(ttyfd, fdi) < 0) { Error3("dup2(%d, %d): %s", ttyfd, fdi, strerror(errno)); return -1; } /*0 Info2("dup2(%d, %d)", ttyfd, fdi);*/ } if (rw != XIO_WRONLY && fdo != ttyfd) { if (Dup2(ttyfd, fdo) < 0) { Error3("dup2(%d, %d): %s", ttyfd, fdo, strerror(errno)); return -1; } /*0 Info2("dup2(%d, %d)", ttyfd, fdo);*/ } if ((rw == XIO_RDONLY || fdi != ttyfd) && (rw == XIO_WRONLY || fdo != ttyfd)) { applyopts_cloexec(ttyfd, *copts); } applyopts(ttyfd, *copts, PH_LATE); applyopts(ttyfd, *copts, PH_LATE2); } else #endif /* HAVE_PTY */ if (usepipes) { /* we might have a temporary conflict between what FDs are currently allocated, and which are to be used. We try to find a graceful solution via temporary descriptors */ int tmpi, tmpo; if (rw != XIO_WRONLY) Close(rdpip[0]); if (rw != XIO_RDONLY) Close(wrpip[1]); if (fdi == rdpip[1]) { /* a conflict here */ if ((tmpi = Dup(wrpip[0])) < 0) { Error2("dup(%d): %s", wrpip[0], strerror(errno)); return -1; } /*0 Info2("dup(%d) -> %d", wrpip[0], tmpi);*/ rdpip[1] = tmpi; } if (fdo == wrpip[0]) { /* a conflict here */ if ((tmpo = Dup(rdpip[1])) < 0) { Error2("dup(%d): %s", rdpip[1], strerror(errno)); return -1; } /*0 Info2("dup(%d) -> %d", rdpip[1], tmpo);*/ wrpip[0] = tmpo; } if (rw != XIO_WRONLY && rdpip[1] != fdo) { if (Dup2(rdpip[1], fdo) < 0) { Error3("dup2(%d, %d): %s", rdpip[1], fdo, strerror(errno)); return -1; } Close(rdpip[1]); /*0 Info2("dup2(%d, %d)", rdpip[1], fdo);*/ /*0 applyopts_cloexec(fdo, *copts);*/ } if (rw != XIO_RDONLY && wrpip[0] != fdi) { if (Dup2(wrpip[0], fdi) < 0) { Error3("dup2(%d, %d): %s", wrpip[0], fdi, strerror(errno)); return -1; } Close(wrpip[0]); /*0 Info2("dup2(%d, %d)", wrpip[0], fdi);*/ /*0 applyopts_cloexec(wrpip[0], *copts);*/ /* option is already consumed! */ /* applyopts_cloexec(fdi, *copts);*/ /* option is already consumed! */ } applyopts(fdi, *copts, PH_LATE); applyopts(fdo, *copts, PH_LATE); applyopts(fdi, *copts, PH_LATE2); applyopts(fdo, *copts, PH_LATE2); } else { /* socketpair */ Close(sv[0]); if (rw != XIO_RDONLY && fdi != sv[1]) { if (Dup2(sv[1], fdi) < 0) { Error3("dup2(%d, %d): %s", sv[1], fdi, strerror(errno)); return -1; } /*0 Info2("dup2(%d, %d)", sv[1], fdi);*/ } if (rw != XIO_WRONLY && fdo != sv[1]) { if (Dup2(sv[1], fdo) < 0) { Error3("dup2(%d, %d): %s", sv[1], fdo, strerror(errno)); return -1; } /*0 Info2("dup2(%d, %d)", sv[1], fdo);*/ } if (fdi != sv[1] && fdo != sv[1]) { applyopts_cloexec(sv[1], *copts); Close(sv[1]); } applyopts(fdi, *copts, PH_LATE); applyopts(fdi, *copts, PH_LATE2); } } /* withfork */ else { applyopts(-1, *copts, PH_LATE); applyopts(-1, *copts, PH_LATE2); } _xioopen_setdelayeduser(); /* set group before user - maybe you are not permitted afterwards */ if (retropt_gidt(*copts, OPT_SETGID, &group) >= 0) { Setgid(group); } if (retropt_uidt(*copts, OPT_SETUID, &user) >= 0) { Setuid(user); } if (withstderr) { *duptostderr = fdo; } else { *duptostderr = -1; } return 0; /* indicate child process */ } /* for parent (this is our socat process) */ Notice1("forked off child process "F_pid, pid); #if 0 if ((popts = copyopts(*copts, GROUP_FD|GROUP_TERMIOS|GROUP_FORK|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_FIFO)) == NULL) return STAT_RETRYLATER; #endif #if HAVE_PTY if (usepty) { if (Close(ttyfd) < 0) { Info2("close(%d): %s", ttyfd, strerror(errno)); } } else #endif /* HAVE_PTY */ if (usepipes) { if (rw == XIO_RDONLY) Close(rdpip[1]); if (rw == XIO_WRONLY) Close(wrpip[0]); } else { Close(sv[1]); } fd->para.exec.pid = pid; if (applyopts_single(fd, popts, PH_LATE) < 0) return -1; applyopts_signal(fd, popts); if ((numleft = leftopts(popts)) > 0) { Error1("%d option(s) could not be used", numleft); showleft(popts); return STAT_NORETRY; } return pid; /* indicate parent (main) process */ } #endif /* WITH_EXEC || WITH_SYSTEM */ int setopt_path(struct opt *opts, char **path) { if (retropt_string(opts, OPT_PATH, path) >= 0) { if (setenv("PATH", *path, 1) < 0) { Error1("setenv(\"PATH\", \"%s\", 1): insufficient space", *path); return -1; } } return 0; } socat-1.7.3.1/xio-creat.h0000644000201000020100000000044311453022152014620 0ustar gerhardgerhard/* source: xio-creat.h */ /* Copyright Gerhard Rieger 2001 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_creat_h_included #define __xio_creat_h_included 1 extern const struct addrdesc addr_creat; #endif /* !defined(__xio_creat_h_included) */ socat-1.7.3.1/xio-readline.c0000644000201000020100000001747712455415362015333 0ustar gerhardgerhard/* source: xio-readline.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening the readline address */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-termios.h" #include "xio-readline.h" #if WITH_READLINE /* options: history file prompt mode=vi? inputrc=? 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, unsigned groups, int dummy1, int dummy2, int dummy3); const struct addrdesc addr_readline = { "readline", 3, xioopen_readline, GROUP_FD|GROUP_TERMIOS|GROUP_READLINE, 0, 0, 0 HELP(NULL) }; const struct optdesc opt_history_file = { "history-file", "history", OPT_HISTORY_FILE, GROUP_READLINE, PH_LATE, TYPE_STRING, OFUNC_OFFSET, XIO_OFFSETOF(para.readline.history_file) }; const struct optdesc opt_prompt = { "prompt", NULL, OPT_PROMPT, GROUP_READLINE, PH_LATE, TYPE_STRING, OFUNC_OFFSET, XIO_OFFSETOF(para.readline.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, unsigned groups, int dummy1, int dummy2, int dummy3) { int rw = (xioflags & XIO_ACCMODE); char msgbuf[256], *cp = msgbuf; bool noprompt = false; char *noecho = NULL; if (argc != 1) { Error1("%s: 0 parameters required", argv[0]); return STAT_NORETRY; } if (!(xioflags & XIO_MAYCONVERT)) { Error("address with data processing not allowed here"); return STAT_NORETRY; } xfd->common.flags |= XIO_DOESCONVERT; strcpy(cp, "using "); cp = strchr(cp, '\0'); if ((rw+1)&1) { strcpy(cp, "readline on stdin for reading"); cp = strchr(cp, '\0'); if ((rw+1)&2) strcpy(cp, " and "); cp = strchr(cp, '\0'); } if ((rw+1)&2) { strcpy(cp, "stdio for writing"); cp = strchr(cp, '\0'); } Notice(msgbuf); xfd->stream.fd = 0; /* stdin */ xfd->stream.howtoend = END_NONE; xfd->stream.dtype = XIODATA_READLINE; #if WITH_TERMIOS if (Isatty(xfd->stream.fd)) { if (Tcgetattr(xfd->stream.fd, &xfd->stream.savetty) < 0) { Warn2("cannot query current terminal settings on fd %d. %s", xfd->stream.fd, strerror(errno)); } else { xfd->stream.ttyvalid = true; } } #endif /* WITH_TERMIOS */ if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); applyopts2(xfd->stream.fd, opts, PH_INIT, PH_FD); Using_history(); applyopts_offset(&xfd->stream, opts); retropt_bool(opts, OPT_NOPROMPT, &noprompt); if (!noprompt && !xfd->stream.para.readline.prompt) { xfd->stream.para.readline.dynbytes = READLINE_MAXPROMPT; xfd->stream.para.readline.dynprompt = Malloc(xfd->stream.para.readline.dynbytes+1); xfd->stream.para.readline.dynend = xfd->stream.para.readline.dynprompt; } #if HAVE_REGEX_H retropt_string(opts, OPT_NOECHO, &noecho); if (noecho) { int errcode; char errbuf[128]; if ((errcode = regcomp(&xfd->stream.para.readline.noecho, noecho, REG_EXTENDED|REG_NOSUB)) != 0) { regerror(errcode, &xfd->stream.para.readline.noecho, errbuf, sizeof(errbuf)); Error3("regcomp(%p, \"%s\", REG_EXTENDED|REG_NOSUB): %s", &xfd->stream.para.readline.noecho, noecho, errbuf); return -1; } xfd->stream.para.readline.hasnoecho = true; } #endif /* HAVE_REGEX_H */ if (xfd->stream.para.readline.history_file) { Read_history(xfd->stream.para.readline.history_file); } #if _WITH_TERMIOS xiotermios_clrflag(xfd->stream.fd, 3, ICANON); xiotermios_clrflag(xfd->stream.fd, 3, ECHO); #endif /* _WITH_TERMIOS */ return _xio_openlate(&xfd->stream, opts); } ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) { /*! indent */ ssize_t bytes; char *line; int _errno; #if HAVE_REGEX_H if (pipe->para.readline.dynprompt && pipe->para.readline.hasnoecho && !regexec(&pipe->para.readline.noecho, pipe->para.readline.dynprompt, 0, NULL, 0)) { #if _WITH_TERMIOS /* under these conditions, we do not echo input, thus we circumvent readline */ struct termios saveterm, setterm; *pipe->para.readline.dynend = '\0'; Tcgetattr(pipe->fd, &saveterm); /*! error */ setterm = saveterm; setterm.c_lflag |= ICANON; Tcsetattr(pipe->fd, TCSANOW, &setterm); /*!*/ #endif /* _WITH_TERMIOS */ do { bytes = Read(pipe->fd, buff, bufsiz); } while (bytes < 0 && errno == EINTR); if (bytes < 0) { _errno = errno; Error4("read(%d, %p, "F_Zu"): %s", pipe->fd, buff, bufsiz, strerror(_errno)); errno = _errno; return -1; } #if _WITH_TERMIOS setterm.c_lflag &= ~ICANON; Tcgetattr(pipe->fd, &setterm); /*! error */ Tcsetattr(pipe->fd, TCSANOW, &saveterm); /*!*/ #endif /* _WITH_TERMIOS */ pipe->para.readline.dynend = pipe->para.readline.dynprompt; /*Write(pipe->fd, "\n", 1);*/ /*!*/ return bytes; } #endif /* HAVE_REGEX_H */ #if _WITH_TERMIOS xiotermios_setflag(pipe->fd, 3, ECHO); #endif /* _WITH_TERMIOS */ if (pipe->para.readline.prompt || pipe->para.readline.dynprompt) { /* we must carriage return, because readline will first print the prompt */ ssize_t writt; writt = writefull(pipe->fd, "\r", 1); if (writt < 0) { Warn2("write(%d, \"\\r\", 1): %s", pipe->fd, strerror(errno)); } else if (writt < 1) { Warn1("write() only wrote "F_Zu" of 1 byte", writt); } } if (pipe->para.readline.dynprompt) { *pipe->para.readline.dynend = '\0'; line = Readline(pipe->para.readline.dynprompt); pipe->para.readline.dynend = pipe->para.readline.dynprompt; } else { line = Readline(pipe->para.readline.prompt); } /* GNU readline defines no error return */ if (line == NULL) { return 0; /* EOF */ } #if _WITH_TERMIOS xiotermios_clrflag(pipe->fd, 3, ECHO); #endif /* _WITH_TERMIOS */ Add_history(line); bytes = strlen(line); ((char *)buff)[0] = '\0'; strncat(buff, line, bufsiz-1); free(line); if ((size_t)bytes < bufsiz) { strcat(buff, "\n"); ++bytes; } return bytes; } void xioscan_readline(struct single *pipe, const void *buff, size_t bytes) { if (pipe->dtype == XIODATA_READLINE && pipe->para.readline.dynprompt) { /* we save the last part of the output as possible prompt */ const void *ptr = buff; const void *pcr; const void *plf; size_t len; if (bytes > pipe->para.readline.dynbytes) { ptr = (const char *)buff + bytes - pipe->para.readline.dynbytes; len = pipe->para.readline.dynbytes; } else { len = bytes; } pcr = memrchr(ptr, '\r', len); plf = memrchr(ptr, '\n', len); if (pcr != NULL || plf != NULL) { const void *peol = Max(pcr, plf); /* forget old prompt */ pipe->para.readline.dynend = pipe->para.readline.dynprompt; len -= (peol+1 - ptr); /* new prompt starts here */ ptr = (const char *)peol+1; } if (pipe->para.readline.dynend - pipe->para.readline.dynprompt + len > pipe->para.readline.dynbytes) { memmove(pipe->para.readline.dynprompt, pipe->para.readline.dynend - (pipe->para.readline.dynbytes - len), pipe->para.readline.dynbytes - len); pipe->para.readline.dynend = pipe->para.readline.dynprompt + pipe->para.readline.dynbytes - len; } memcpy(pipe->para.readline.dynend, ptr, len); pipe->para.readline.dynend = pipe->para.readline.dynend + len; } return; } #endif /* WITH_READLINE */ socat-1.7.3.1/xio-ascii.h0000644000201000020100000000145311453022152014614 0ustar gerhardgerhard/* source: xio-ascii.h */ /* Copyright Gerhard Rieger 2002-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ascii_h_included #define __xio_ascii_h_included 1 extern char * xiob64encodeline(const char *data, /* input data */ size_t bytes, /* length of input data, >=0 */ char *coded /* output buffer, must be long enough */ ); extern char *xiosanitize(const char *data, /* input data */ size_t bytes, /* length of input data, >=0 */ char *coded /* output buffer, must be long enough */ ); extern char * xiohexdump(const unsigned char *data, size_t bytes, char *coded); extern char * xiodump(const unsigned char *data, size_t bytes, char *coded, size_t codlen, int coding); #endif /* !defined(__xio_ascii_h_included) */ socat-1.7.3.1/DEVELOPMENT0000644000201000020100000002045012460670272014274 0ustar gerhardgerhard This file should help you to add new address types and address options to socat. NOTE: socat will in future releases be split into a library "libxio" containing all the address stuff, useful also for many other purposes, and the socat main() and data shuffler. If you intend to perform major changes to the xio part and to publish them, please contact me before! ADDING A NEW ADDRESS TYPE: * Create new files xio-newaddr.c and xio-newaddr.h * Create a new record of struct addrdesc in xio-newaddr.c, with declaration in xio-newaddr.h. * Make a new entry to addressnames[] in xioopen.c with the addresses main name and maybe with alias names. Keep this array ASCII sorted, without uppercase chars. * config.h.in: #undef WITH_NEWADDR * configure.in: Copy the disable part of, e.g., WITH_SOCKS4 and adapt it to NEWADDR * In socat.c, add to socat_version * Write a function xioopen_newaddr() in xio-newaddr.c, declaration in xio-newaddr.h Do not forget the following option processing calls: All groups: _xio_openlate() Group FD: applyopts_cloexec() Group NAMED: applyopts_file() for phases PREOPEN, OPEN, and FD * Describe a tested example in file EXAMPLES, and maybe in the socat manpage source. * Try to define a test for this address type in test.sh * Update file CHANGES ADDING A NEW ADDRESS OPTION: xioopen.c: * If this option depends on a #define that is probably not available on all platforms, make all new code for this option dependent on the existence of this C header define: #ifdef PREFIX_NEWOPTION ... #endif * Add an OPT_NEWOPTION to enum e_optcode in xioopts.h, preferably keeping alphabetic order * Add a struct optdesc opt_newoption record in xio-newaddr.c and its declaration in xio-newaddr.h. The complete structure definition must be in one line without breaks for automatic docu extraction. Build the record from the following components: . A canonical default name (e.g. "newoption") . A short, preferable name (e.g. "newopt") or NULL . OPT_NEWOPTION (from enum e_optcode, see above) . A group membership that restricts appliance of the new option to matching address types (e.g., one of GROUP_ANY, GROUP_IP_TCP, GROUP_EXEC) . A phase specification that positions this option within address processing. Note that the function code can override this value. . A representation type for option arguments (e.g., TYPE_INT, TYPE_STRING etc.; use TYPE_BOOL if this option just triggers an action) . A function or action definition for applying this option. If it does not use one of the standard functions (open(), ioctl(), setsockopt()...), then use OFUNC_SPEC (specific). * For the canonical name and all its aliases and abbreviations, add entries to the array optionnames in xioopts.c. KEEP STRICT ALPHABETIC (ASCII) ORDER! The entries must be embedded in an IF_... macro of their group for conditional compiling. * For options using some predefined action (see OFUNC above), this might be enough - test the option and document it in xio.help! For OFUNC_SPEC, it might suffice to add another "case" to the OFUNC_SPEC branch in applyopts() in xioopts.c. If you need more special handling, you should try to understand the address specific functions and add your code there. * If you use system or low level C library calls or library calls that might hang or induce problems, please invoke them with capitalized name; if no such name is defined, add an appropriate debug function to sycls.c, and a header entry and a wrapper "define" to sycls.h * Update file CHANGES INFO ABOUT ADDRESS PHASES: Each option entry has a field specifying a default phase for its application. Of course, the code that analyses and applies an address may override this default phase. Depending on the type of address there are several major phase sequences: OPEN addresses: PH_INIT retrieving info from original state PH_EARLY before any other processing PH_PREOPEN before file creation/opening (not UNIX sockets) PH_OPEN during file creation/opening (not UNIX sockets) PH_PASTOPEN past file creation/opening (not UNIX sockets) PH_FD soon after FD creation or identification PH_LATE FD is ready, before start of data loop PH_LATE2 FD is ready, dropping privileges SOCKET addresses: PH_INIT retrieving info from original state PH_EARLY before any other processing PH_PRESOCKET before socket call PH_SOCKET for socket call PH_PASTSOCKET after socket call PH_FD soon after FD creation or identification PH_PREBIND before socket bind() PH_BIND during socket bind() PH_PASTBIND past socket bind() PH_PRECONNECT before connect() PH_CONNECT during connect() PH_PASTCONNECT after connect() PH_CONNECTED phase common with listen PH_LATE FD is ready, before start of data loop PH_LATE2 FD is ready, dropping privileges SOCKET with LISTEN and ACCEPT: PH_INIT retrieving info from original state PH_EARLY before any other processing PH_PRESOCKET before socket call PH_SOCKET for socket call PH_PREBIND before socket bind() PH_BIND during socket bind() PH_PASTBIND past socket bind() PH_PRELISTEN before listen() PH_LISTEN during listen() PH_PASTLISTEN after listen() PH_PREACCEPT before accept() PH_ACCEPT during accept() PH_PASTACCEPT after accept() # and the following on the new FD: PH_FD soon after FD creation or identification PH_PASTSOCKET after socket call PH_CONNECTED phase common with connect PH_PREFORK before forking PH_FORK during fork() PH_PASTFORK after fork() PH_LATE FD is ready, before start of data loop PH_LATE2 FD is ready, dropping privileges FD addresses: PH_INIT retrieving info from original state PH_EARLY before any other processing PH_FD soon after FD identification PH_LATE FD is ready, before start of data loop PH_LATE2 FD is ready, dropping privileges EXEC addresses: PH_INIT retrieving info from original state PH_EARLY before any other processing PH_PREBIGEN before socketpair() pipe() openpty() PH_BIGEN during socketpair() pipe() openpty() PH_PASTBIGEN past socketpair() pipe() openpty() PH_PASTSOCKET for socketpair() PH_FD soon after FD creation or identification PH_PREFORK before forking PH_FORK during fork() PH_PASTFORK after fork() PH_LATE FD is ready, before start of data loop PH_LATE2 FD is ready, dropping privileges PH_PREEXEC before exec() or system() PH_EXEC during exec() or system() There are lots of semantic relations between group, phase, and func fields of an option. There exists something like an overall phase sequence: PH_INIT # su-d.1 PH_EARLY # chroot-early PH_PREOPEN, PH_OPEN, PH_PASTOPEN # (chroot before/after?) PH_PRESOCKET, PH_SOCKET, PH_PASTSOCKET # (su after (root for raw)?) PH_PREBIGEN, PH_BIGEN, PH_PASTBIGEN # (chroot before/after (/dev..)?) PH_FD PH_PREBIND, PH_BIND, PH_PASTBIND # (su after(before?)) PH_PRELISTEN, PH_LISTEN, PH_PASTLISTEN PH_PRECONNECT, PH_CONNECT, PH_PASTCONNECT # (chroot before/after (AF_UNIX)?) PH_PREACCEPT, PH_ACCEPT, PH_PASTACCEPT PH_CONNECTED PH_PREFORK, PH_FORK, PH_PASTFORK # (all before/after?) PH_LATE # chroot PH_LATE2 # su, su-d.2 PH_PREEXEC, PH_EXEC # (all before) =============================================================================== // Up to 1.7.2.4 socat used non async signal safe system and library calls in signal handlers, mostly for logging purposes. This problem was fixed in release 1.7.3.0 with the following concepts: Signal handlers set on entry and unset on return the diag_in_handler global variable. The logging system, when this variable is set, queues the text message together with errno and exit info in a UNIX datagram socket. When invoked with unset diag_in_handler it first checks if there are messages in that queue and prints them first. A async signal safe but minimal version of vsnprintf, named vsnprintf_r, was written so no value arguments need to be queued. Because strerror is not async signal safe a new function snprinterr was written that replaces the (glibc compatible) %m format with strerror output. The original errno is passed in the message queue, snprinterr is called when dequeuing messages outside of signal handler. // List of signal handlers in socat socat.c:socat_signal (generic, just logs and maybe exits) xioshutdown.c:signal_kill_pid (SIGALRM, kill child process) xiosigchld.c:childdied (SIGCHLD: get info, log; possibly close channel) xiosignal.c:socatsignalpass: cascades signal to channel child processes; w/ options sighup,sigint,sigquit xio-socket.c:xiosigaction_hasread: SIGUSR1,SIGCHLD, tells parent that datagram has been consumed socat-1.7.3.1/socks4a-echo.sh0000755000201000020100000000465311453022152015405 0ustar gerhardgerhard#! /bin/bash # source: socks4a-echo.sh #set -vx # Copyright Gerhard Rieger 2004 # Published under the GNU General Public License V.2, see file COPYING # perform primitive simulation of a socks4a server with echo function via stdio. # accepts and answers correct SOCKS4a requests, but then just echoes data. # it is required for test.sh # for TCP, use this script as: # socat tcp-l:1080,reuseaddr,crlf system:"socks4a-echo.sh" # older bash and ksh do not have -n option to read command; we try dd then if echo a |read -n 1 null >/dev/null 2>&1; then HAVE_READ_N=1 else HAVE_READ_N= fi if type socat >/dev/null 2>&1; then SOCAT=socat else SOCAT=./socat fi case `uname` in HP-UX|OSF1) CAT="$SOCAT -u stdin stdout" ;; *) CAT=cat ;; esac if [ $(echo "x\c") = "x" ]; then E="" elif [ $(echo -e "x\c") = "x" ]; then E="-e" else echo "cannot suppress trailing newline on echo" >&2 exit 1 fi ECHO="echo $E" if [ $($ECHO "\0101") = "A" ]; then SOCKSREPLY_FAILED="\0\0133\0\0\0\0\0\0\c" SOCKSREPLY_OK="\0\0132\0\0\0\0\0\0\c" else SOCKSREPLY_FAILED="\0\133\0\0\0\0\0\0\c" SOCKSREPLY_OK="\0\132\0\0\0\0\0\0\c" fi # read and parse SOCKS4a header if [ "$HAVE_READ_N" ]; then read -r -n 1 vn # bash 2.0.3 does not support -n else vn=$(dd bs=1 count=1 2>/dev/null) fi if [ "$vn" != $($ECHO "\04") ]; then $ECHO "$SOCKSREPLY_FAILED" echo "invalid socks version requested" >&2 exit fi if [ "$HAVE_READ_N" ]; then read -r -n 1 cd else cd=$(dd bs=1 count=1 2>/dev/null) fi if [ "$cd" != $($ECHO "\01") ]; then $ECHO "$SOCKSREPLY_FAILED" echo "invalid socks operation requested" >&2 exit fi a=$(dd bs=1 count=6 2>/dev/null) #echo a a a >/dev/tty #echo "$a" |od -c >/dev/tty #$ECHO "$a" |od -c >/dev/tty #echo>/dev/tty #echo a a a >/dev/tty if [ "$a" != "$($ECHO "}m\0\0\0\01")" ]; then sleep 1 $ECHO "$SOCKSREPLY_FAILED" echo "wrong socks address or port requested" >&2 exit fi if [ "$HAVE_READ_N" ]; then read -r -n 7 u else u=$(dd bs=1 count=7 2>/dev/null) fi if [ "$u" != "nobody" ]; then $ECHO "$SOCKSREPLY_FAILED" echo "wrong socks user requested" >&2 exit fi if [ "$HAVE_READ_N" ]; then read -r -n 10 h else h=$(dd bs=1 count=10 2>/dev/null) fi if [ "$h" != "localhost" ]; then $ECHO "$SOCKSREPLY_FAILED" echo "wrong socks address requested" >&2 exit fi # send ok status $ECHO "$SOCKSREPLY_OK" # perform echo function $CAT socat-1.7.3.1/xio-stdio.c0000644000201000020100000001402111453022152014634 0ustar gerhardgerhard/* source: xio-stdio.c */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses stdio type */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-fdnum.h" #include "xio-stdio.h" #if WITH_STDIO static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int fd, int dummy2, int dummy3); /* we specify all option groups that we can imagine for a FD, becasue the changed parsing mechanism does not allow us to check the type of FD before applying the options */ const struct addrdesc addr_stdio = { "stdio", 3, xioopen_stdio, 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(NULL) }; const struct addrdesc addr_stdin = { "stdin", 1, xioopen_stdfd, 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(NULL) }; const struct addrdesc addr_stdout = { "stdout", 2, xioopen_stdfd, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_FILE|GROUP_SOCKET|GROUP_TERMIOS|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP, 1, 0, 0 HELP(NULL) }; const struct addrdesc addr_stderr = { "stderr", 2, xioopen_stdfd, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_FILE|GROUP_SOCKET|GROUP_TERMIOS|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP, 2, 0, 0 HELP(NULL) }; /* process a bidirectional "stdio" or "-" argument with options. generate a dual address. */ int xioopen_stdio_bi(xiofile_t *sock) { struct opt *optspr; unsigned int groups1 = addr_stdio.groups; int result; if (xioopen_makedual(sock) < 0) { return -1; } sock->dual.stream[0]->tag = XIO_TAG_RDONLY; sock->dual.stream[0]->fd = 0 /*stdin*/; sock->dual.stream[1]->tag = XIO_TAG_WRONLY; sock->dual.stream[1]->fd = 1 /*stdout*/; sock->dual.stream[0]->howtoend = sock->dual.stream[1]->howtoend = END_NONE; #if WITH_TERMIOS if (Isatty(sock->dual.stream[0]->fd)) { if (Tcgetattr(sock->dual.stream[0]->fd, &sock->dual.stream[0]->savetty) < 0) { Warn2("cannot query current terminal settings on fd %d: %s", sock->dual.stream[0]->fd, strerror(errno)); } else { sock->dual.stream[0]->ttyvalid = true; } } if (Isatty(sock->dual.stream[1]->fd)) { if (Tcgetattr(sock->dual.stream[1]->fd, &sock->dual.stream[1]->savetty) < 0) { Warn2("cannot query current terminal settings on fd %d: %s", sock->dual.stream[1]->fd, strerror(errno)); } else { sock->dual.stream[1]->ttyvalid = true; } } #endif /* WITH_TERMIOS */ /* options here are one-time and one-direction, no second use */ retropt_bool(sock->stream.opts, OPT_IGNOREEOF, &sock->dual.stream[0]->ignoreeof); /* extract opts that should be applied only once */ if ((optspr = copyopts(sock->stream.opts, GROUP_PROCESS)) == NULL) { return -1; } /* here we copy opts, because most have to be applied twice! */ if ((sock->dual.stream[1]->opts = copyopts(sock->stream.opts, GROUP_FD|GROUP_APPL|(groups1&~GROUP_PROCESS))) == NULL) { return -1; } sock->dual.stream[0]->opts = sock->stream.opts; sock->stream.opts = NULL; if (applyopts_single(sock->dual.stream[0], sock->dual.stream[0]->opts, PH_INIT) < 0) return -1; if (applyopts_single(sock->dual.stream[1], sock->dual.stream[1]->opts, PH_INIT) < 0) return -1; applyopts(-1, sock->dual.stream[0]->opts, PH_INIT); applyopts(-1, sock->dual.stream[1]->opts, PH_INIT); if ((result = applyopts(-1, optspr, PH_EARLY)) < 0) return result; if ((result = applyopts(-1, optspr, PH_PREOPEN)) < 0) return result; /* apply options to first FD */ if ((result = applyopts(sock->dual.stream[0]->fd, sock->dual.stream[0]->opts, PH_ALL)) < 0) { return result; } if ((result = _xio_openlate(sock->dual.stream[0], sock->dual.stream[0]->opts)) < 0) { return result; } #if 0 /* ignore this opt */ retropt_bool(sock->dual.stream[0]->opts, OPT_COOL_WRITE); #endif /* apply options to second FD */ if ((result = applyopts(sock->dual.stream[1]->fd, sock->dual.stream[1]->opts, PH_ALL)) < 0) { return result; } if ((result = _xio_openlate(sock->dual.stream[1], sock->dual.stream[1]->opts)) < 0) { return result; } #if 0 if ((result = _xio_openlate(sock->dual.stream[1], optspr)) < 0) { return result; } #endif Notice("reading from and writing to stdio"); return 0; } /* 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, unsigned groups, int dummy1, int dummy2, int dummy3) { int rw = (xioflags&XIO_ACCMODE); if (argc != 1) { Error2("%s: wrong number of parameters (%d instead of 0)", argv[0], argc-1); } if (rw == XIO_RDWR) { return xioopen_stdio_bi(fd); } Notice2("using %s for %s", &("stdin\0\0\0stdout"[rw<<3]), ddirection[rw]); return xioopen_fd(opts, rw, &fd->stream, rw, dummy2, dummy3); } /* 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, unsigned groups, int fd, int dummy2, int dummy3) { int rw = (xioflags&XIO_ACCMODE); if (argc != 1) { Error2("%s: wrong number of parameters (%d instead of 0)", argv[0], argc-1); } 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); } #endif /* WITH_STDIO */ socat-1.7.3.1/xio-named.h0000644000201000020100000000173711453022152014615 0ustar gerhardgerhard/* source: xio-named.h */ /* Copyright Gerhard Rieger 2001-2006 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_named_h_included #define __xio_named_h_included 1 extern const struct optdesc opt_group_early; extern const struct optdesc opt_perm_early; extern const struct optdesc opt_user_early; /*0 extern const struct optdesc opt_cleanup; */ /*0 extern const struct optdesc opt_force; */ extern const struct optdesc opt_unlink; extern const struct optdesc opt_unlink_early; extern const struct optdesc opt_unlink_late; extern const struct optdesc opt_unlink_close; 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, int groups, bool *exists, struct opt *opts); extern int _xioopen_open(const char *path, int rw, struct opt *opts); #endif /* !defined(__xio_named_h_included) */ socat-1.7.3.1/xio-socket.h0000644000201000020100000001155112161506654015027 0ustar gerhardgerhard/* source: xio-socket.h */ /* Copyright Gerhard Rieger 2001-2009 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_socket_h_included #define __xio_socket_h_included 1 /* SO_PROTOTYPE is OS defined on Solaris, HP-UX; we lend this for a more general purpose */ #ifndef SO_PROTOTYPE #define SO_PROTOTYPE 0x9999 #endif extern const struct addrdesc xioaddr_socket_connect; extern const struct addrdesc xioaddr_socket_listen; extern const struct addrdesc xioaddr_socket_sendto; extern const struct addrdesc xioaddr_socket_datagram; extern const struct addrdesc xioaddr_socket_recvfrom; extern const struct addrdesc xioaddr_socket_recv; extern const struct optdesc opt_connect_timeout; extern const struct optdesc opt_so_debug; extern const struct optdesc opt_so_acceptconn; extern const struct optdesc opt_so_broadcast; extern const struct optdesc opt_so_reuseaddr; extern const struct optdesc opt_so_keepalive; extern const struct optdesc opt_so_linger; extern const struct optdesc opt_so_linger; extern const struct optdesc opt_so_oobinline; extern const struct optdesc opt_so_sndbuf; extern const struct optdesc opt_so_sndbuf_late; extern const struct optdesc opt_so_rcvbuf; extern const struct optdesc opt_so_rcvbuf_late; extern const struct optdesc opt_so_error; extern const struct optdesc opt_so_type; extern const struct optdesc opt_so_dontroute; extern const struct optdesc opt_so_rcvlowat; extern const struct optdesc opt_so_rcvtimeo; extern const struct optdesc opt_so_sndlowat; extern const struct optdesc opt_so_sndtimeo; extern const struct optdesc opt_so_audit; extern const struct optdesc opt_so_attach_filter; extern const struct optdesc opt_so_detach_filter; extern const struct optdesc opt_so_bindtodevice; extern const struct optdesc opt_so_bsdcompat; extern const struct optdesc opt_so_cksumrecv; extern const struct optdesc opt_so_timestamp; extern const struct optdesc opt_so_kernaccept; extern const struct optdesc opt_so_no_check; extern const struct optdesc opt_so_noreuseaddr; extern const struct optdesc opt_so_passcred; extern const struct optdesc opt_so_peercred; extern const struct optdesc opt_so_priority; extern const struct optdesc opt_so_reuseport; extern const struct optdesc opt_so_security_authentication; extern const struct optdesc opt_so_security_encryption_network; extern const struct optdesc opt_so_security_encryption_transport; extern const struct optdesc opt_so_use_ifbufs; extern const struct optdesc opt_so_useloopback; extern const struct optdesc opt_so_dgram_errind; extern const struct optdesc opt_so_dontlinger; extern const struct optdesc opt_so_prototype; extern const struct optdesc opt_fiosetown; extern const struct optdesc opt_siocspgrp; extern const struct optdesc opt_bind; extern const struct optdesc opt_protocol_family; extern const struct optdesc opt_setsockopt_int; extern const struct optdesc opt_setsockopt_bin; extern const struct optdesc opt_setsockopt_string; extern const struct optdesc opt_null_eof; extern char *xiogetifname(int ind, char *val, int ins); extern int retropt_socket_pf(struct opt *opts, int *pf); extern int xioopen_connect(struct single *fd, struct sockaddr *us, size_t uslen, struct sockaddr *them, size_t themlen, struct opt *opts, int pf, int socktype, int protocol, bool alt); extern int _xioopen_connect(struct single *fd, struct sockaddr *us, size_t uslen, struct sockaddr *them, size_t themlen, struct opt *opts, int pf, int socktype, int protocol, bool alt, int level); /* common to xioopen_udp_sendto, ..unix_sendto, ..rawip */ extern int _xioopen_dgram_sendto(/* them is already in xfd->peersa */ union sockaddr_union *us, socklen_t uslen, struct opt *opts, int xioflags, xiosingle_t *xfd, unsigned groups, int pf, int socktype, int ipproto); extern int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, int pf, int socktype, int proto, int level); extern int _xioopen_dgram_recv(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, int pf, int socktype, int proto, int level); extern int xiodopacketinfo(struct msghdr *msgh, bool withlog, bool withenv); extern int xiogetpacketsrc(int fd, struct msghdr *msgh); extern int xiocheckpeer(xiosingle_t *xfd, union sockaddr_union *pa, union sockaddr_union *la); extern int xiosetsockaddrenv(const char *lr, union sockaddr_union *sau, socklen_t salen, int proto); extern int xioparsenetwork(const char *rangename, int pf, struct xiorange *range); extern int xioparserange(const char *rangename, int pf, struct xiorange *range); extern int xiosocket(struct opt *opts, int pf, int socktype, int proto, int level); extern int xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]); #endif /* !defined(__xio_socket_h_included) */ socat-1.7.3.1/xio-openssl.h0000644000201000020100000000377512460670272015233 0ustar gerhardgerhard/* source: xio-openssl.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_openssl_included #define __xio_openssl_included 1 #if WITH_OPENSSL /* make this address configure dependend */ #define SSLIO_BASE 0x53530000 /* "SSxx" */ #define SSLIO_MASK 0xffff0000 extern const struct addrdesc addr_openssl; extern const struct addrdesc addr_openssl_listen; extern const struct optdesc opt_openssl_cipherlist; extern const struct optdesc opt_openssl_method; extern const struct optdesc opt_openssl_verify; extern const struct optdesc opt_openssl_certificate; extern const struct optdesc opt_openssl_key; extern const struct optdesc opt_openssl_dhparam; extern const struct optdesc opt_openssl_cafile; extern const struct optdesc opt_openssl_capath; extern const struct optdesc opt_openssl_egd; extern const struct optdesc opt_openssl_pseudo; #if OPENSSL_VERSION_NUMBER >= 0x00908000L extern const struct optdesc opt_openssl_compress; #endif #if WITH_FIPS extern const struct optdesc opt_openssl_fips; #endif extern const struct optdesc opt_openssl_commonname; extern int _xioopen_openssl_prepare(struct opt *opts, struct single *xfd, bool server, bool *opt_ver, const char *opt_cert, SSL_CTX **ctx); extern int _xioopen_openssl_connect(struct single *xfd, bool opt_ver, const char *opt_commonname, SSL_CTX *ctx, int level); extern int _xioopen_openssl_listen(struct single *xfd, bool opt_ver, const char *opt_commonname, SSL_CTX *ctx, int level); extern int xioclose_openssl(xiofile_t *xfd); extern int xioshutdown_openssl(xiofile_t *xfd, int how); extern ssize_t xioread_openssl(struct single *file, void *buff, size_t bufsiz); extern ssize_t xiopending_openssl(struct single *pipe); extern ssize_t xiowrite_openssl(struct single *file, const void *buff, size_t bufsiz); #if WITH_FIPS extern int xio_reset_fips_mode(void); #endif /* WITH_FIPS */ #endif /* WITH_OPENSSL */ #endif /* !defined(__xio_openssl_included) */ socat-1.7.3.1/gatherinfo.sh0000755000201000020100000001000111453022152015230 0ustar gerhardgerhard#! /bin/sh # source: gatherinfo.sh # Copyright Gerhard Rieger 2001, 2002 # Published under the GNU General Public License V.2, see file COPYING #set -vx # use this script after successful porting # provide the platform name as argument with no dots, e.g. HPUX-11-0 # it generates the files: # Config/Makefile.PLATFORM # Config/config.PLATFORM.h # Config/socat.PLATFORM.out # # Config/config.PLATFORM.log # Config/compile.PLATFORM.log # Config/test.PLATFORM.log VERBOSE= LOGGING= INTERACTIVE= CONFOPTS= PLATFORM= OUTPUT='>/dev/null' # how to echo special characters? if [ `echo "x\c"` = "x" ]; then E="" elif [ `echo -e "x\c"` = "x" ]; then E="-e" fi while [ -n "$1" ]; do case "$1" in -v) VERBOSE=1; shift;; # tell about progress -d) LOGGING=1; shift;; # show complete output -i) INTERACTIVE=1; shift;; # diff and ask before overriding old files -*) CONFOPTS="$CONFOPTS $1"; shift;; *) PLATFORM="$1"; break;; esac done #if [ -z "$PLATFORM" ]; then # echo "please specify a configuration name, e.g. `uname -s`-`uname -r|tr '.' '-'`!" >&2; exit 1; #fi if [ $# -eq 0 ]; then echo $E "usage: $0 [-v] [-i] [configure options ...] platform" >&2 echo $E "\t-v\t\tverbose (print actual command)" >&2 echo $E "\t-d\t\tdump command outputs" >&2 echo $E "\t-i\t\tinteractive (ask before overwriting something)" >&2 echo $E "\tconfigure options\toptions for configure script, e.g. --disable-ip6" >&2 echo $E "\tplatform\tdescribe your OS, e.g. `uname -s`-`uname -r|tr '.' '-'`" >&2 exit 1 fi case "$PLATFORM" in *.*) echo "platform name must not contain '.'" >&2; exit 1;; esac # now, lets begin! if [ -f Makefile ]; then COMMAND="make distclean" [ "$VERBOSE" ] && echo "$COMMAND" $COMMAND >/dev/null 2>&1 || echo "*** failed: $COMMAND" 1>&2 fi # implicitly generates Makefile, config.h, config.log COMMAND="./configure $CONFOPTS" LOGFILE="compile.log" [ "$VERBOSE" ] && echo "$COMMAND" if [ "$LOGGING" ]; then { $COMMAND; echo "$?" >socat.rc; } 2>&1 |tee $LOGFILE; if [ `cat socat.rc` -ne 0 ]; then echo "*** failed: $COMMAND" 1>&2; exit 1; fi else $COMMAND >$LOGFILE 2>&1 || { echo "*** failed: $COMMAND" 1>&2; exit 1; } fi COMMAND="make -k" LOGFILE="compile.log" [ "$VERBOSE" ] && echo "$COMMAND" if [ "$LOGGING" ]; then { $COMMAND; echo "$?" >socat.rc; } 2>&1 |tee -a $LOGFILE; if [ `cat socat.rc` -ne 0 ]; then echo "*** failed: $COMMAND" 1>&2; exit 1; fi else $COMMAND >>$LOGFILE 2>&1 || { echo "*** failed: $COMMAND" 1>&2; exit 1; } fi # generates socat.out COMMAND="make info" [ "$VERBOSE" ] && echo "$COMMAND" $COMMAND >/dev/null || echo "*** failed: $COMMAND" 1>&2 COMMAND="./test.sh" LOGFILE="test.log" [ "$VERBOSE" ] && echo "$COMMAND" if [ "$LOGGING" ]; then { $COMMAND; echo "$?" >socat.rc; } 2>&1 |tee $LOGFILE; if [ `cat socat.rc` -ne 0 ]; then echo "*** failed: $COMMAND" 1>&2 if [ `cat socat.rc` -ge 128 ]; then exit 1 fi fi else $COMMAND >$LOGFILE 2>&1 || echo "*** failed: $COMMAND" 1>&2 fi FILES= b=Makefile; e=; f=$b; p=Config/$b.$PLATFORM if [ "$INTERACTIVE" -a -f $p ]; then if ! diff $p $f; then cp -pi $f $p fi else cp -p $f $p fi FILES="$p" b=config; e=h; f=$b.$e; p=Config/$b.$PLATFORM.$e if [ "$INTERACTIVE" -a -f $p ]; then if ! diff $p $f; then cp -pi $f $p fi else cp -p $f $p fi FILES="$FILES $p" b=socat; e=out; f=$b.$e; p=Config/$b.$PLATFORM.$e if [ "$INTERACTIVE" -a -f $p ]; then if ! diff $p $f; then cp -pi $f $p fi else cp -p $f $p fi FILES="$FILES $p" b=config; e=log; f=$b.$e; p=Config/$b.$PLATFORM.$e if [ "$INTERACTIVE" -a -f $p ]; then if ! diff $p $f; then cp -pi $f $p fi else cp -p $f $p fi FILES="$FILES $p" b=compile; e=log; f=$b.$e; p=Config/$b.$PLATFORM.$e if [ "$INTERACTIVE" -a -f $p ]; then if ! diff $p $f; then cp -pi $f $p fi else cp -p $f $p fi FILES="$FILES $p" b=test; e=log; f=$b.$e; p=Config/$b.$PLATFORM.$e if [ "$INTERACTIVE" -a -f $p ]; then if ! diff $p $f; then cp -pi $f $p fi else cp -p $f $p fi FILES="$FILES $p" echo "output files:" echo "$FILES" socat-1.7.3.1/xioopen.c0000644000201000020100000003722411453022152014410 0ustar gerhardgerhard/* source: xioopen.c */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source file of the extended open function */ #include "xiosysincludes.h" #include "xioopen.h" #include "xiomodes.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); const struct addrname addressnames[] = { #if 1 #if WITH_STDIO { "-", &addr_stdio }, #endif #if defined(WITH_UNIX) && defined(WITH_ABSTRACT_UNIXSOCKET) { "abstract", &xioaddr_abstract_client }, { "abstract-client", &xioaddr_abstract_client }, { "abstract-connect", &xioaddr_abstract_connect }, #if WITH_LISTEN { "abstract-listen", &xioaddr_abstract_listen }, #endif { "abstract-recv", &xioaddr_abstract_recv }, { "abstract-recvfrom", &xioaddr_abstract_recvfrom }, { "abstract-sendto", &xioaddr_abstract_sendto }, #endif /* defined(WITH_UNIX) && defined(WITH_ABSTRACT_UNIXSOCKET) */ #if WITH_CREAT { "creat", &addr_creat }, { "create", &addr_creat }, #endif #if WITH_GENERICSOCKET { "datagram", &xioaddr_socket_datagram }, { "dgram", &xioaddr_socket_datagram }, #endif #if WITH_PIPE { "echo", &addr_pipe }, #endif #if WITH_EXEC { "exec", &addr_exec }, #endif #if WITH_FDNUM { "fd", &addr_fd }, #endif #if WITH_PIPE { "fifo", &addr_pipe }, #endif #if WITH_FILE { "file", &addr_open }, #endif #if WITH_GOPEN { "gopen", &addr_gopen }, #endif #if WITH_INTERFACE { "if", &xioaddr_interface }, #endif #if (WITH_IP4 || WITH_IP6) && WITH_TCP { "inet", &addr_tcp_connect }, #endif #if (WITH_IP4 || WITH_IP6) && WITH_TCP && WITH_LISTEN { "inet-l", &addr_tcp_listen }, { "inet-listen", &addr_tcp_listen }, #endif #if WITH_IP4 && WITH_TCP { "inet4", &addr_tcp4_connect }, #endif #if WITH_IP4 && WITH_TCP && WITH_LISTEN { "inet4-l", &addr_tcp4_listen }, { "inet4-listen", &addr_tcp4_listen }, #endif #if WITH_IP6 && WITH_TCP { "inet6", &addr_tcp6_connect }, #endif #if WITH_IP6 && WITH_TCP && WITH_LISTEN { "inet6-l", &addr_tcp6_listen }, { "inet6-listen", &addr_tcp6_listen }, #endif #if WITH_INTERFACE { "interface", &xioaddr_interface }, #endif #if WITH_RAWIP #if (WITH_IP4 || WITH_IP6) { "ip", &addr_rawip_sendto }, { "ip-datagram", &addr_rawip_datagram }, { "ip-dgram", &addr_rawip_datagram }, { "ip-recv", &addr_rawip_recv }, { "ip-recvfrom", &addr_rawip_recvfrom }, { "ip-send", &addr_rawip_sendto }, { "ip-sendto", &addr_rawip_sendto }, #endif #if WITH_IP4 { "ip4", &addr_rawip4_sendto }, { "ip4-datagram", &addr_rawip4_datagram }, { "ip4-dgram", &addr_rawip4_datagram }, { "ip4-recv", &addr_rawip4_recv }, { "ip4-recvfrom", &addr_rawip4_recvfrom }, { "ip4-send", &addr_rawip4_sendto }, { "ip4-sendto", &addr_rawip4_sendto }, #endif #if WITH_IP6 { "ip6", &addr_rawip6_sendto }, { "ip6-datagram", &addr_rawip6_datagram }, { "ip6-dgram", &addr_rawip6_datagram }, { "ip6-recv", &addr_rawip6_recv }, { "ip6-recvfrom", &addr_rawip6_recvfrom }, { "ip6-send", &addr_rawip6_sendto }, { "ip6-sendto", &addr_rawip6_sendto }, #endif #endif /* WITH_RAWIP */ #if WITH_UNIX { "local", &xioaddr_unix_connect }, #endif #if WITH_FILE { "open", &addr_open }, #endif #if WITH_OPENSSL { "openssl", &addr_openssl }, { "openssl-connect", &addr_openssl }, #if WITH_LISTEN { "openssl-listen", &addr_openssl_listen }, #endif #endif #if WITH_PIPE { "pipe", &addr_pipe }, #endif #if WITH_PROXY { "proxy", &addr_proxy_connect }, { "proxy-connect", &addr_proxy_connect }, #endif #if WITH_PTY { "pty", &addr_pty }, #endif #if WITH_READLINE { "readline", &addr_readline }, #endif #if (WITH_IP4 || WITH_IP6) && WITH_SCTP { "sctp", &addr_sctp_connect }, { "sctp-connect", &addr_sctp_connect }, #if WITH_LISTEN { "sctp-l", &addr_sctp_listen }, { "sctp-listen", &addr_sctp_listen }, #endif #if WITH_IP4 { "sctp4", &addr_sctp4_connect }, { "sctp4-connect", &addr_sctp4_connect }, #if WITH_LISTEN { "sctp4-l", &addr_sctp4_listen }, { "sctp4-listen", &addr_sctp4_listen }, #endif #endif /* WITH_IP4 */ #if WITH_IP6 { "sctp6", &addr_sctp6_connect }, { "sctp6-connect", &addr_sctp6_connect }, #if WITH_LISTEN { "sctp6-l", &addr_sctp6_listen }, { "sctp6-listen", &addr_sctp6_listen }, #endif #endif /* WITH_IP6 */ #endif /* (WITH_IP4 || WITH_IP6) && WITH_SCTP */ #if WITH_GENERICSOCKET { "sendto", &xioaddr_socket_sendto }, #endif #if WITH_GENERICSOCKET { "socket-connect", &xioaddr_socket_connect }, { "socket-datagram", &xioaddr_socket_datagram }, #if WITH_LISTEN { "socket-listen", &xioaddr_socket_listen }, #endif /* WITH_LISTEN */ { "socket-recv", &xioaddr_socket_recv }, { "socket-recvfrom", &xioaddr_socket_recvfrom }, { "socket-sendto", &xioaddr_socket_sendto }, #endif #if WITH_SOCKS4 { "socks", &addr_socks4_connect }, { "socks4", &addr_socks4_connect }, #endif #if WITH_SOCKS4A { "socks4a", &addr_socks4a_connect }, #endif #if WITH_OPENSSL { "ssl", &addr_openssl }, #if WITH_LISTEN { "ssl-l", &addr_openssl_listen }, #endif #endif #if WITH_STDIO { "stderr", &addr_stderr }, { "stdin", &addr_stdin }, { "stdio", &addr_stdio }, { "stdout", &addr_stdout }, #endif #if WITH_SYSTEM { "system", &addr_system }, #endif #if (WITH_IP4 || WITH_IP6) && WITH_TCP { "tcp", &addr_tcp_connect }, { "tcp-connect", &addr_tcp_connect }, #endif #if (WITH_IP4 || WITH_IP6) && WITH_TCP && WITH_LISTEN { "tcp-l", &addr_tcp_listen }, { "tcp-listen", &addr_tcp_listen }, #endif #if WITH_IP4 && WITH_TCP { "tcp4", &addr_tcp4_connect }, { "tcp4-connect", &addr_tcp4_connect }, #endif #if WITH_IP4 && WITH_TCP && WITH_LISTEN { "tcp4-l", &addr_tcp4_listen }, { "tcp4-listen", &addr_tcp4_listen }, #endif #if WITH_IP6 && WITH_TCP { "tcp6", &addr_tcp6_connect }, { "tcp6-connect", &addr_tcp6_connect }, #endif #if WITH_IP6 && WITH_TCP && WITH_LISTEN { "tcp6-l", &addr_tcp6_listen }, { "tcp6-listen", &addr_tcp6_listen }, #endif #if WITH_TUN { "tun", &xioaddr_tun }, #endif #if (WITH_IP4 || WITH_IP6) && WITH_UDP { "udp", &addr_udp_connect }, #endif #if (WITH_IP4 || WITH_IP6) && WITH_UDP { "udp-connect", &addr_udp_connect }, { "udp-datagram", &addr_udp_datagram }, { "udp-dgram", &addr_udp_datagram }, #endif #if (WITH_IP4 || WITH_IP6) && WITH_UDP && WITH_LISTEN { "udp-l", &addr_udp_listen }, { "udp-listen", &addr_udp_listen }, #endif #if (WITH_IP4 || WITH_IP6) && WITH_UDP { "udp-recv", &addr_udp_recv }, { "udp-recvfrom", &addr_udp_recvfrom }, { "udp-send", &addr_udp_sendto }, { "udp-sendto", &addr_udp_sendto }, #endif #if WITH_IP4 && WITH_UDP { "udp4", &addr_udp4_connect }, { "udp4-connect", &addr_udp4_connect }, { "udp4-datagram", &addr_udp4_datagram }, { "udp4-dgram", &addr_udp4_datagram }, #endif #if WITH_IP4 && WITH_UDP && WITH_LISTEN { "udp4-l", &addr_udp4_listen }, { "udp4-listen", &addr_udp4_listen }, #endif #if WITH_IP4 && WITH_UDP { "udp4-recv", &addr_udp4_recv }, { "udp4-recvfrom", &addr_udp4_recvfrom }, { "udp4-send", &addr_udp4_sendto }, { "udp4-sendto", &addr_udp4_sendto }, #endif #if WITH_IP6 && WITH_UDP { "udp6", &addr_udp6_connect }, { "udp6-connect", &addr_udp6_connect }, { "udp6-datagram", &addr_udp6_datagram }, { "udp6-dgram", &addr_udp6_datagram }, #endif #if WITH_IP6 && WITH_UDP && WITH_LISTEN { "udp6-l", &addr_udp6_listen }, { "udp6-listen", &addr_udp6_listen }, #endif #if WITH_IP6 && WITH_UDP { "udp6-recv", &addr_udp6_recv }, { "udp6-recvfrom", &addr_udp6_recvfrom }, { "udp6-send", &addr_udp6_sendto }, { "udp6-sendto", &addr_udp6_sendto }, #endif #if WITH_UNIX { "unix", &xioaddr_unix_client }, { "unix-client", &xioaddr_unix_client }, { "unix-connect", &xioaddr_unix_connect }, #endif #if WITH_UNIX && WITH_LISTEN { "unix-l", &xioaddr_unix_listen }, { "unix-listen", &xioaddr_unix_listen }, #endif #if WITH_UNIX { "unix-recv", &xioaddr_unix_recv }, { "unix-recvfrom", &xioaddr_unix_recvfrom }, { "unix-send", &xioaddr_unix_sendto }, { "unix-sendto", &xioaddr_unix_sendto }, #endif #else /* !0 */ # if WITH_INTEGRATE # include "xiointegrate.c" # else # include "xioaddrtab.c" # endif #endif /* !0 */ { NULL } /* end marker */ } ; int xioopen_single(xiofile_t *xfd, int xioflags); /* prepares a xiofile_t record for dual address type: sets the tag and allocates memory for the substreams. returns 0 on success, or <0 if an error occurred. */ int xioopen_makedual(xiofile_t *file) { file->tag = XIO_TAG_DUAL; file->common.flags = XIO_RDWR; if ((file->dual.stream[0] = (xiosingle_t *)xioallocfd()) == NULL) return -1; file->dual.stream[0]->flags = XIO_RDONLY; if ((file->dual.stream[1] = (xiosingle_t *)xioallocfd()) == NULL) return -1; file->dual.stream[1]->flags = XIO_WRONLY; return 0; } static xiofile_t *xioallocfd(void) { xiofile_t *fd; if ((fd = Calloc(1, sizeof(xiofile_t))) == NULL) { return NULL; } /* some default values; 0's and NULL's need not be applied (calloc'ed) */ fd->common.tag = XIO_TAG_INVALID; /* fd->common.addr = NULL; */ fd->common.flags = XIO_RDWR; #if WITH_RETRY /* fd->stream.retry = 0; */ /* fd->stream.forever = false; */ fd->stream.intervall.tv_sec = 1; /* fd->stream.intervall.tv_nsec = 0; */ #endif /* WITH_RETRY */ /* fd->common.ignoreeof = false; */ /* fd->common.eof = 0; */ fd->stream.fd = -1; fd->stream.dtype = XIODATA_STREAM; #if _WITH_SOCKET /* fd->stream.salen = 0; */ #endif /* _WITH_SOCKET */ fd->stream.howtoend = END_UNSPEC; /* fd->stream.name = NULL; */ fd->stream.escape = -1; /* fd->stream.para.exec.pid = 0; */ fd->stream.lineterm = LINETERM_RAW; /*!! support n socks */ if (!sock[0]) { sock[0] = fd; } else { sock[1] = fd; } return fd; } /* parse the argument that specifies a two-directional data stream and open the resulting address */ xiofile_t *xioopen(const char *addr, /* address specification */ int xioflags) { xiofile_t *xfd; if (xioinitialize() < 0) { return NULL; } if ((xfd = xioparse_dual(&addr)) == NULL) { return NULL; } if (xioopen_dual(xfd, xioflags) < 0) { /*!!! free something? */ return NULL; } return xfd; } static xiofile_t *xioparse_dual(const char **addr) { xiofile_t *xfd; xiosingle_t *sfd1; /* we parse a single address */ if ((sfd1 = xioparse_single(addr)) == NULL) { return NULL; } /* and now we see if we reached a dual-address separator */ if (!strncmp(*addr, xioopts.pipesep, strlen(xioopts.pipesep))) { /* yes we reached it, so we parse the second single address */ *addr += strlen(xioopts.pipesep); if ((xfd = xioallocfd()) == NULL) { free(sfd1); /*! and maybe have free some if its contents */ return NULL; } xfd->tag = XIO_TAG_DUAL; xfd->dual.stream[0] = sfd1; if ((xfd->dual.stream[1] = xioparse_single(addr)) == NULL) { return NULL; } return xfd; } /* a truly single address */ xfd = (xiofile_t *)sfd1; sfd1 = NULL; return xfd; } static int xioopen_dual(xiofile_t *xfd, int xioflags) { if (xfd->tag == XIO_TAG_DUAL) { /* a really dual address */ if ((xioflags&XIO_ACCMODE) != XIO_RDWR) { Warn("unidirectional open of dual address"); } if (((xioflags&XIO_ACCMODE)+1) & (XIO_RDONLY+1)) { if (xioopen_single((xiofile_t *)xfd->dual.stream[0], XIO_RDONLY|(xioflags&~XIO_ACCMODE&~XIO_MAYEXEC)) < 0) { return -1; } } if (((xioflags&XIO_ACCMODE)+1) & (XIO_WRONLY+1)) { if (xioopen_single((xiofile_t *)xfd->dual.stream[1], XIO_WRONLY|(xioflags&~XIO_ACCMODE&~XIO_MAYEXEC)) < 0) { xioclose((xiofile_t *)xfd->dual.stream[0]); return -1; } } return 0; } return xioopen_single(xfd, xioflags); } static xiosingle_t *xioparse_single(const char **addr) { xiofile_t *xfd; xiosingle_t *sfd; struct addrname *ae; const struct addrdesc *addrdesc = NULL; const char *ends[4+1]; const char *hquotes[] = { "'", NULL } ; const char *squotes[] = { "\"", NULL } ; const char *nests[] = { "'", "'", "(", ")", "[", "]", "{", "}", NULL } ; char token[512], *tokp; size_t len; int i; /* init */ i = 0; /*ends[i++] = xioopts.chainsep;*/ /* default: "|" */ ends[i++] = xioopts.pipesep; /* default: "!!" */ ends[i++] = ","/*xioopts.comma*/; /* default: "," */ ends[i++] = ":"/*xioopts.colon*/; /* default: ":" */ ends[i++] = NULL; if ((xfd = xioallocfd()) == NULL) { return NULL; } sfd = &xfd->stream; sfd->argc = 0; len = sizeof(token); tokp = token; if (nestlex(addr, &tokp, &len, ends, hquotes, squotes, nests, true, true, false) < 0) { Error2("keyword too long, in address \"%s%s\"", token, *addr); } *tokp = '\0'; /*! len? */ ae = (struct addrname *) keyw((struct wordent *)&addressnames, token, sizeof(addressnames)/sizeof(struct addrname)-1); if (ae) { addrdesc = ae->desc; /* keyword */ if ((sfd->argv[sfd->argc++] = strdup(token)) == NULL) { Error1("strdup(\"%s\"): out of memory", token); } } else { if (false) { ; #if WITH_FDNUM } else if (isdigit(token[0]&0xff) && token[1] == '\0') { Info1("interpreting address \"%s\" as file descriptor", token); addrdesc = &addr_fd; if ((sfd->argv[sfd->argc++] = strdup("FD")) == NULL) { Error("strdup(\"FD\"): out of memory"); } if ((sfd->argv[sfd->argc++] = strdup(token)) == NULL) { Error1("strdup(\"%s\"): out of memory", token); } /*! check argc overflow */ #endif /* WITH_FDNUM */ #if WITH_GOPEN } else if (strchr(token, '/')) { Info1("interpreting address \"%s\" as file name", token); addrdesc = &addr_gopen; if ((sfd->argv[sfd->argc++] = strdup("GOPEN")) == NULL) { Error("strdup(\"GOPEN\"): out of memory"); } if ((sfd->argv[sfd->argc++] = strdup(token)) == NULL) { Error1("strdup(\"%s\"): out of memory", token); } /*! check argc overflow */ #endif /* WITH_GOPEN */ } else { Error1("unknown device/address \"%s\"", token); /*!!! free something*/ return NULL; } } sfd->tag = XIO_TAG_RDWR; sfd->addr = addrdesc; while (!strncmp(*addr, xioopts.paramsep, strlen(xioopts.paramsep))) { *addr += strlen(xioopts.paramsep); len = sizeof(token); tokp = token; if (nestlex(addr, &tokp, &len, ends, hquotes, squotes, nests, true, true, false) != 0) { Error2("syntax error in address \"%s%s\"", token, *addr); } *tokp = '\0'; if ((sfd->argv[sfd->argc++] = strdup(token)) == NULL) { Error1("strdup(\"%s\"): out of memory", token); } } if (parseopts(addr, addrdesc->groups, &sfd->opts) < 0) { free(xfd); return NULL; } return sfd; } int xioopen_single(xiofile_t *xfd, int xioflags) { const struct addrdesc *addrdesc; int result; if ((xioflags&XIO_ACCMODE) == XIO_RDONLY) { xfd->tag = XIO_TAG_RDONLY; } else if ((xioflags&XIO_ACCMODE) == XIO_WRONLY) { xfd->tag = XIO_TAG_WRONLY; } else if ((xioflags&XIO_ACCMODE) == XIO_RDWR) { xfd->tag = XIO_TAG_RDWR; } else { Error1("invalid mode for address \"%s\"", xfd->stream.argv[0]); } xfd->stream.flags &= (~XIO_ACCMODE); xfd->stream.flags |= (xioflags & XIO_ACCMODE); addrdesc = xfd->stream.addr; result = (*addrdesc->func)(xfd->stream.argc, xfd->stream.argv, xfd->stream.opts, xioflags, xfd, addrdesc->groups, addrdesc->arg1, addrdesc->arg2, addrdesc->arg3); return result; } socat-1.7.3.1/xioopen.h0000644000201000020100000000473611453022152014417 0ustar gerhardgerhard/* source: xioopen.h */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xioopen_h_included #define __xioopen_h_included 1 #include "compat.h" /* F_pid */ #include "mytypes.h" #include "error.h" #include "utils.h" #include "sysutils.h" #include "sycls.h" #include "sslcls.h" #include "dalan.h" #include "filan.h" #include "xio.h" #include "xioopts.h" #if WITH_HELP #define HELP(x) , x #else #define HELP(x) #endif /* xioinitialize performs asserts on these records */ extern const struct optdesc opt_crdly; extern const struct optdesc opt_tabdly; extern const struct optdesc opt_csize; struct addrname { const char *name; const struct addrdesc *desc; } ; extern const char *ddirection[]; extern const char *filetypenames[]; extern const struct addrname addressnames[]; extern const struct optname optionnames[]; extern int xioopen_makedual(xiofile_t *file); #define retropt_2bytes(o,c,r) retropt_ushort(o,c,r) /* mode_t might be unsigned short or unsigned int or what else? */ #if HAVE_BASIC_MODE_T==1 # define retropt_modet(x,y,z) retropt_short(x,y,z) #elif HAVE_BASIC_MODE_T==2 # define retropt_modet(x,y,z) retropt_ushort(x,y,z) #elif HAVE_BASIC_MODE_T==3 # define retropt_modet(x,y,z) retropt_int(x,y,z) #elif HAVE_BASIC_MODE_T==4 # define retropt_modet(x,y,z) retropt_uint(x,y,z) #elif HAVE_BASIC_MODE_T==5 # define retropt_modet(x,y,z) retropt_long(x,y,z) #elif HAVE_BASIC_MODE_T==6 # define retropt_modet(x,y,z) retropt_ulong(x,y,z) #endif #if HAVE_BASIC_UID_T==1 # define retropt_uidt(x,y,z) retropt_short(x,y,z) #elif HAVE_BASIC_UID_T==2 # define retropt_uidt(x,y,z) retropt_ushort(x,y,z) #elif HAVE_BASIC_UID_T==3 # define retropt_uidt(x,y,z) retropt_int(x,y,z) #elif HAVE_BASIC_UID_T==4 # define retropt_uidt(x,y,z) retropt_uint(x,y,z) #elif HAVE_BASIC_UID_T==5 # define retropt_uidt(x,y,z) retropt_long(x,y,z) #elif HAVE_BASIC_UID_T==6 # define retropt_uidt(x,y,z) retropt_ulong(x,y,z) #endif #if HAVE_BASIC_GID_T==1 # define retropt_gidt(x,y,z) retropt_short(x,y,z) #elif HAVE_BASIC_GID_T==2 # define retropt_gidt(x,y,z) retropt_ushort(x,y,z) #elif HAVE_BASIC_GID_T==3 # define retropt_gidt(x,y,z) retropt_int(x,y,z) #elif HAVE_BASIC_GID_T==4 # define retropt_gidt(x,y,z) retropt_uint(x,y,z) #elif HAVE_BASIC_GID_T==5 # define retropt_gidt(x,y,z) retropt_long(x,y,z) #elif HAVE_BASIC_GID_T==6 # define retropt_gidt(x,y,z) retropt_ulong(x,y,z) #endif #endif /* !defined(__xioopen_h_included) */ socat-1.7.3.1/xio-exec.h0000644000201000020100000000051311453022152014444 0ustar gerhardgerhard/* source: xio-exec.h */ /* Copyright Gerhard Rieger 2001, 2002 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_exec_h_included #define __xio_exec_h_included 1 extern const struct addrdesc addr_exec; extern const struct optdesc opt_dash; #endif /* !defined(__xio_exec_h_included) */ socat-1.7.3.1/xiodiag.h0000644000201000020100000000046711453022152014357 0ustar gerhardgerhard/* source: xiodiag.h */ /* Copyright Gerhard Rieger 2001 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xiodiag_h_included #define __xiodiag_h_included 1 extern const char *ddirection[]; extern const char *filetypenames[]; #endif /* !defined(__xiodiag_h_included) */ socat-1.7.3.1/test.sh0000755000201000020100000135435412652637410014123 0ustar gerhardgerhard#! /bin/bash # source: test.sh # Copyright Gerhard Rieger # Published under the GNU General Public License V.2, see file COPYING # perform lots of tests on socat # this script uses functions; you need a shell that supports them # you can pass general options to socat: export OPTS="-d -d -d -d -lu" # you can eg strace socat with: export TRACE="strace -v -tt -ff -D -x -s 1024 -o /tmp/$USER/socat.strace" #set -vx val_t=0.1 NUMCOND=true #NUMCOND="test \$N -gt 70" while [ "$1" ]; do case "X$1" in X-t?*) val_t="${1#-t}" ;; X-t) shift; val_t="$1" ;; X-n?*) NUMCOND="test \$N -eq ${1#-n}" ;; X-n) shift; NUMCOND="test \$N -eq $1" ;; X-N?*) NUMCOND="test \$N -gt ${1#-N}" ;; X-N) shift; NUMCOND="test \$N -ge $1" ;; *) break; esac shift done opt_t="-t $val_t" #MICROS=100000 case "X$val_t" in X*.???????*) S="${val_t%.*}"; uS="${val_t#*.}"; uS="${uS:0:6}" ;; X*.*) S="${val_t%.*}"; uS="${val_t#*.}"; uS="${uS}000000"; uS="${uS:0:6}" ;; X*) S="${val_t}"; uS="000000" ;; esac MICROS=${S}${uS} MICROS=${MICROS##0000}; MICROS=${MICROS##00}; MICROS=${MICROS##0} # _MICROS=$((MICROS+999999)); SECONDs="${_MICROS%??????}" [ -z "$SECONDs" ] && SECONDs=0 withroot=0 # perform privileged tests even if not run by root #PATH=$PATH:/opt/freeware/bin #PATH=$PATH:/usr/local/ssl/bin case "$0" in */*) PATH="${0%/*}:$PATH" esac #OPENSSL_RAND="-rand /dev/egd-pool" #SOCAT_EGD="egd=/dev/egd-pool" MISCDELAY=1 [ -z "$SOCAT" ] && SOCAT="./socat" if ! [ -x "$SOCAT" ] && ! type $SOCAT >/dev/null 2>&1; then echo "$SOCAT does not exist" >&2; exit 1; fi [ -z "$PROCAN" ] && PROCAN="./procan" [ -z "$FILAN" ] && FILAN="./filan" opts="$opt_t $OPTS" export SOCAT_OPTS="$opts" #debug="1" debug= TESTS="$@"; export TESTS # for some tests we need a network interface if type ip >/dev/null 2>&1; then INTERFACE=$(ip r get 8.8.8.8 |grep ' dev ' |head -n 1 |sed "s/.*dev[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\).*/\1/") else INTERFACE=eth0 fi MCINTERFACE=lo # !!! Linux only #LOCALHOST=192.168.58.1 LOCALHOST=localhost #LOCALHOST=127.0.0.1 LOCALHOST6=[::1] #PROTO=$(awk '{print($2);}' /etc/protocols |sort -n |tail -n 1) #PROTO=$(($PROTO+1)) PROTO=$((144+RANDOM/2048)) PORT=12002 SOURCEPORT=2002 # SSL certificate contents TESTCERT_CONF=testcert.conf TESTCERT6_CONF=testcert6.conf # TESTCERT_COMMONNAME="$LOCALHOST" TESTCERT_COMMONNAME6="$LOCALHOST6" TESTCERT_COUNTRYNAME="XY" TESTCERT_LOCALITYNAME="Lunar Base" TESTCERT_ORGANIZATIONALUNITNAME="socat" TESTCERT_ORGANIZATIONNAME="dest-unreach" TESTCERT_SUBJECT="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME" TESTCERT_ISSUER="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME" cat >$TESTCERT_CONF <$TESTCERT6_CONF </dev/null 2>&1; then usleep () { local n="$1" case "$n" in *???????) S="${n%??????}"; uS="${n:${#n}-6}" ;; *) S=0; uS="00000$n"; uS="${uS:${#uS}-6}" ;; esac $SOCAT -T $S.$uS pipe pipe } fi #USLEEP=usleep F_n="%3d" # format string for test numbers LC_ALL=C # for timestamps format... LANG=C LANGUAGE=C # knoppix UNAME=`uname` case "$UNAME" in HP-UX|OSF1) echo "$SOCAT -u stdin stdout" >cat.sh chmod a+x cat.sh CAT=./cat.sh ;; SunOS) # /usr/bin/tr doesn't handle the a-z range syntax (needs [a-z]), use # /usr/xpg4/bin/tr instead alias tr=/usr/xpg4/bin/tr ;; *) CAT=cat ;; esac case "$UNAME" in #HP-UX) # # on HP-UX, the default options (below) hang some tests (former 14, 15) # PTYOPTS= # PTYOPTS2= # ;; *) PTYOPTS="echo=0,opost=0" #PTYOPTS2="raw,echo=0" PTYOPTS2="cfmakeraw" #PTYOPTS2="rawer" ;; esac # for some tests we need an unprivileged user id to su to if [ "$SUDO_USER" ]; then SUBSTUSER="$SUDO_USER" else SUBSTUSER="$(grep -v '^[^:]*:^[^:]*:0:' /etc/passwd |tail -n 1 |cut -d: -f1)" fi # non-root users might miss ifconfig in their path case "$UNAME" in AIX) IFCONFIG=/usr/sbin/ifconfig ;; FreeBSD) IFCONFIG=/sbin/ifconfig ;; HP-UX) IFCONFIG=/usr/sbin/ifconfig ;; Linux) IFCONFIG=/sbin/ifconfig ;; NetBSD)IFCONFIG=/sbin/ifconfig ;; OpenBSD)IFCONFIG=/sbin/ifconfig ;; OSF1) IFCONFIG=/sbin/ifconfig ;; SunOS) IFCONFIG=/sbin/ifconfig ;; Darwin)IFCONFIG=/sbin/ifconfig ;; DragonFly) IFCONFIG=/sbin/ifconfig ;; *) IFCONFIG=/sbin/ifconfig ;; esac # need output like "644" case "$UNAME" in Linux) fileperms() { stat -L --print "%a\n" "$1" 2>/dev/null; } ;; FreeBSD) fileperms() { stat -L -x "$1" |grep ' Mode:' |sed 's/.* Mode:[[:space:]]*([0-9]\([0-7][0-7][0-7]\).*/\1/'; } ;; *) fileperms() { local p s=0 c p="$(ls -l -L "$1" |awk '{print($1);}')" p="${p:1:9}" while [ "$p" ]; do c=${p:0:1}; p=${p:1}; [ "x$c" == x- ]; let "s=2*s+$?"; done printf "%03o\n" $s; } ;; esac # need user (owner) of filesystem entry case "$UNAME" in Linux) fileuser() { stat -L --print "%U\n" "$tsock" 2>/dev/null; } ;; FreeBSD) fileuser() { ls -l test.sh |awk '{print($3);}'; } ;; *) fileuser() { ls -l test.sh |awk '{print($3);}'; } ;; esac # for some tests we need a second local IPv4 address case "$UNAME" in Linux) BROADCASTIF=$(ip r get 8.8.8.8 |grep ' dev ' |sed 's/.*\&2 exit 1 fi ECHO="echo $E" PRINTF="printf" case "$TERM" in vt100|vt320|linux|xterm|cons25|dtterm|aixterm|sun-color|xterm-color|xterm-256color) # there are different behaviours of printf (and echo) # on some systems, echo behaves different than printf... if [ $($PRINTF "\0101") = "A" ]; then RED="\0033[31m" GREEN="\0033[32m" YELLOW="\0033[33m" # if [ "$UNAME" = SunOS ]; then # NORMAL="\0033[30m" # else NORMAL="\0033[39m" # fi else RED="\033[31m" GREEN="\033[32m" YELLOW="\033[33m" # if [ "$UNAME" = SunOS ]; then # NORMAL="\033[30m" # else NORMAL="\033[39m" # fi fi OK="${GREEN}OK${NORMAL}" FAILED="${RED}FAILED${NORMAL}" NO_RESULT="${YELLOW}NO RESULT${NORMAL}" ;; *) OK="OK" FAILED="FAILED" NO_RESULT="NO RESULT" ;; esac if [ -x /usr/xpg4/bin/id ]; then # SunOS has rather useless tools in its default path PATH="/usr/xpg4/bin:$PATH" fi [ -z "$TESTS" ] && TESTS="consistency functions filan" # use '%' as separation char TESTS="%$(echo "$TESTS" |tr ' ' '%')%" [ -z "$USER" ] && USER="$LOGNAME" # HP-UX if [ -z "$TMPDIR" ]; then if [ -z "$TMP" ]; then TMP=/tmp fi TMPDIR="$TMP" fi TD="$TMPDIR/$USER/$$"; td="$TD" rm -rf "$TD" || (echo "cannot rm $TD" >&2; exit 1) mkdir -p "$TD" #trap "rm -r $TD" 0 3 echo "using temp directory $TD" case "$TESTS" in *%consistency%*) # test if addresses are sorted alphabetically: $ECHO "testing if address array is sorted...\c" TF="$TD/socat-q" IFS="$($ECHO ' \n\t')" $SOCAT -? |sed '1,/address-head:/ d' |egrep 'groups=' |while IFS="$IFS:" read x y; do echo "$x"; done >"$TF" $SOCAT -? |sed '1,/address-head:/ d' |egrep 'groups=' |while IFS="$IFS:" read x y; do echo "$x"; done |LC_ALL=C sort |diff "$TF" - >"$TF-diff" if [ -s "$TF-diff" ]; then $ECHO "\n*** address array is not sorted. Wrong entries:" >&2 cat "$TD/socat-q-diff" >&2 exit 1 else echo " ok" fi #/bin/rm "$TF" #/bin/rm "$TF-diff" esac case "$TESTS" in *%consistency%*) # test if address options array ("optionnames") is sorted alphabetically: $ECHO "testing if address options are sorted...\c" TF="$TD/socat-qq" $SOCAT -??? |sed '1,/opt:/ d' |awk '{print($1);}' >"$TF" LC_ALL=C sort "$TF" |diff "$TF" - >"$TF-diff" if [ -s "$TF-diff" ]; then $ECHO "\n*** option array is not sorted. Wrong entries:" >&2 cat "$TD/socat-qq-diff" >&2 exit 1 else echo " ok" fi /bin/rm "$TF" /bin/rm "$TF-diff" esac #============================================================================== case "$TESTS" in *%options%*) # inquire which options are available OPTS_ANY=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*ANY' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_BLK=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*BLK' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_CHILD=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*CHILD' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_CHR=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*CHR' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_DEVICE=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*DEVICE' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_EXEC=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*EXEC' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_FD=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*FD' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_FIFO=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*FIFO' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_FORK=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*FORK' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_LISTEN=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*LISTEN' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_NAMED=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*NAMED' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_OPEN=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*OPEN[^S]' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_PARENT=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*PARENT' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_READLINE=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*READLINE' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_RETRY=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*RETRY' |awk '{print($1);}' |grep -v forever|xargs echo |tr ' ' ',') OPTS_RANGE=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*RANGE' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_FILE=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*REG' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_UNIX=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*UNIX' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_SOCKET=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*SOCKET' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_TERMIOS=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*TERMIOS' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_IP4=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*IP4' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_IP6=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*IP6' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_TCP=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*TCP' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_UDP=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*UDP' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_SOCKS4=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*SOCKS4' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_PROCESS=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*PROCESS' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_OPENSSL=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*OPENSSL' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_PTY=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*PTY' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_HTTP=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*HTTP' |awk '{print($1);}' |xargs echo |tr ' ' ',') OPTS_APPL=$($SOCAT -?? |sed '1,/opt:/ d' |egrep 'groups=([A-Z]+,)*APPL' |awk '{print($1);}' |xargs echo |tr ' ' ',') # find user ids to setown to; non-root only can setown to itself if [ $(id -u) = 0 ]; then # up to now, it is not a big problem when these do not exist _UID=nobody _GID=staff else _UID=$(id -u) _GID=$(id -g) fi # some options require values; here we try to replace these bare options with # valid forms. filloptionvalues() { local OPTS=",$1," # case "$OPTS" in *,umask,*) OPTS=$(echo "$OPTS" |sed "s/,umask,/,umask=0026,/g");; esac case "$OPTS" in *,user,*) OPTS=$(echo "$OPTS" |sed "s/,user,/,user=$_UID,/g");; esac case "$OPTS" in *,user-early,*) OPTS=$(echo "$OPTS" |sed "s/,user-early,/,user-early=$_UID,/g");; esac case "$OPTS" in *,user-late,*) OPTS=$(echo "$OPTS" |sed "s/,user-late,/,user-late=$_UID,/g");; esac case "$OPTS" in *,owner,*) OPTS=$(echo "$OPTS" |sed "s/,owner,/,owner=$_UID,/g");; esac case "$OPTS" in *,uid,*) OPTS=$(echo "$OPTS" |sed "s/,uid,/,uid=$_UID,/g");; esac case "$OPTS" in *,uid-l,*) OPTS=$(echo "$OPTS" |sed "s/,uid-l,/,uid-l=$_UID,/g");; esac case "$OPTS" in *,setuid,*) OPTS=$(echo "$OPTS" |sed "s/,setuid,/,setuid=$_UID,/g");; esac case "$OPTS" in *,group,*) OPTS=$(echo "$OPTS" |sed "s/,group,/,group=$_GID,/g");; esac case "$OPTS" in *,group-early,*) OPTS=$(echo "$OPTS" |sed "s/,group-early,/,group-early=$_GID,/g");; esac case "$OPTS" in *,group-late,*) OPTS=$(echo "$OPTS" |sed "s/,group-late,/,group-late=$_GID,/g");; esac case "$OPTS" in *,gid,*) OPTS=$(echo "$OPTS" |sed "s/,gid,/,gid=$_GID,/g");; esac case "$OPTS" in *,gid-l,*) OPTS=$(echo "$OPTS" |sed "s/,gid-l,/,gid-l=$_GID,/g");; esac case "$OPTS" in *,setgid,*) OPTS=$(echo "$OPTS" |sed "s/,setgid,/,setgid=$_GID,/g");; esac case "$OPTS" in *,mode,*) OPTS=$(echo "$OPTS" |sed "s/,mode,/,mode=0700,/g");; esac case "$OPTS" in *,perm,*) OPTS=$(echo "$OPTS" |sed "s/,perm,/,perm=0700,/g");; esac case "$OPTS" in *,perm-early,*) OPTS=$(echo "$OPTS" |sed "s/,perm-early,/,perm-early=0700,/g");; esac case "$OPTS" in *,perm-late,*) OPTS=$(echo "$OPTS" |sed "s/,perm-late,/,perm-late=0700,/g");; esac case "$OPTS" in *,path,*) OPTS=$(echo "$OPTS" |sed "s/,path,/,path=.,/g");; esac # SOCKET case "$OPTS" in *,bind,*) OPTS=$(echo "$OPTS" |sed "s/,bind,/,bind=:,/g");; esac case "$OPTS" in *,linger,*) OPTS=$(echo "$OPTS" |sed "s/,linger,/,linger=2,/g");; esac case "$OPTS" in *,rcvtimeo,*) OPTS=$(echo "$OPTS" |sed "s/,rcvtimeo,/,rcvtimeo=1,/g");; esac case "$OPTS" in *,sndtimeo,*) OPTS=$(echo "$OPTS" |sed "s/,sndtimeo,/,sndtimeo=1,/g");; esac case "$OPTS" in *,connect-timeout,*) OPTS=$(echo "$OPTS" |sed "s/,connect-timeout,/,connect-timeout=1,/g");; esac # IP case "$OPTS" in *,ipoptions,*) OPTS=$(echo "$OPTS" |sed "s|,ipoptions,|,ipoptions=x01,|g");; esac case "$OPTS" in *,pf,*) OPTS=$(echo "$OPTS" |sed "s|,pf,|,pf=ip4,|g");; esac case "$OPTS" in *,range,*) OPTS=$(echo "$OPTS" |sed "s|,range,|,range=127.0.0.1/32,|g");; esac case "$OPTS" in *,if,*) OPTS=$(echo "$OPTS" |sed "s/,if,/,if=$INTERFACE,/g");; esac # PTY case "$OPTS" in *,pty-interval,*) OPTS=$(echo "$OPTS" |sed "s/,pty-interval,/,pty-interval=$INTERFACE,/g");; esac # RETRY case "$OPTS" in *,interval,*) OPTS=$(echo "$OPTS" |sed "s/,interval,/,interval=1,/g");; esac # READLINE case "$OPTS" in *,history,*) OPTS=$(echo "$OPTS" |sed "s/,history,/,history=.history,/g");; esac case "$OPTS" in *,noecho,*) OPTS=$(echo "$OPTS" |sed "s/,noecho,/,noecho=password,/g");; esac case "$OPTS" in *,prompt,*) OPTS=$(echo "$OPTS" |sed "s/,prompt,/,prompt=CMD,/g");; esac # IPAPP case "$OPTS" in *,sp,*) OPTS=$(echo "$OPTS" |sed "s/,sp,/,sp=$SOURCEPORT,/g");; esac # OPENSSL case "$OPTS" in *,ciphers,*) OPTS=$(echo "$OPTS" |sed "s/,ciphers,/,ciphers=NULL,/g");; esac case "$OPTS" in *,method,*) OPTS=$(echo "$OPTS" |sed "s/,method,/,method=SSLv3,/g");; esac case "$OPTS" in *,cafile,*) OPTS=$(echo "$OPTS" |sed "s/,cafile,/,cafile=/tmp/hugo,/g");; esac case "$OPTS" in *,capath,*) OPTS=$(echo "$OPTS" |sed "s/,capath,/,capath=/tmp/hugo,/g");; esac case "$OPTS" in *,cert,*) OPTS=$(echo "$OPTS" |sed "s/,cert,/,cert=/tmp/hugo,/g");; esac case "$OPTS" in *,key,*) OPTS=$(echo "$OPTS" |sed "s/,key,/,key=/tmp/hugo,/g");; esac case "$OPTS" in *,dh,*) OPTS=$(echo "$OPTS" |sed "s/,dh,/,dh=/tmp/hugo,/g");; esac case "$OPTS" in *,egd,*) OPTS=$(echo "$OPTS" |sed "s/,egd,/,egd=/tmp/hugo,/g");; esac case "$OPTS" in *,compress,*) OPTS=$(echo "$OPTS" |sed "s/,compress,/,compress=none,/g");; esac # PROXY case "$OPTS" in *,proxyauth,*) OPTS=$(echo "$OPTS" |sed "s/,proxyauth,/,proxyauth=user:pass,/g");; esac case "$OPTS" in *,proxyport,*) OPTS=$(echo "$OPTS" |sed "s/,proxyport,/,proxyport=3128,/g");; esac case "$OPTS" in *,link,*) OPTS=$(echo "$OPTS" |sed "s/,link,/,link=testlink,/g");; esac # TCP-WRAPPERS case "$OPTS" in *,allow-table,*) OPTS=$(echo "$OPTS" |sed "s|,allow-table,|,allow-table=/tmp/hugo,|g");; esac case "$OPTS" in *,deny-table,*) OPTS=$(echo "$OPTS" |sed "s|,deny-table,|,deny-table=/tmp/hugo,|g");; esac case "$OPTS" in *,tcpwrap-dir,*) OPTS=$(echo "$OPTS" |sed "s|,tcpwrap-dir,|,tcpwrap-dir=/tmp,|g");; esac echo $OPTS >&2 expr "$OPTS" : ',\(.*\),' } # OPTS_FIFO: nothing yet # OPTS_CHR: nothing yet # OPTS_BLK: nothing yet # OPTS_REG: nothing yet OPTS_SOCKET=",$OPTS_SOCKET," OPTS_SOCKET=$(expr "$OPTS_SOCKET" : ',\(.*\),') N=1 #------------------------------------------------------------------------------ #method=open #METHOD=$(echo "$method" |tr a-z A-Z) #TEST="$METHOD on file accepts all its options" # echo "### $TEST" #TF=$TD/file$N #DA="test$N $(date) $RANDOM" #OPTGROUPS=$($SOCAT -? |fgrep " $method:" |sed 's/.*=//') #for g in $(echo $OPTGROUPS |tr ',' ' '); do # eval "OPTG=\$OPTS_$(echo $g |tr a-z- A-Z_)"; # OPTS="$OPTS,$OPTG"; #done ##echo $OPTS # #for o in $(filloptionvalues $OPTS|tr ',' ' '); do # echo testing if $METHOD accepts option $o # touch $TF # $SOCAT $opts -!!$method:$TF,$o /dev/null,ignoreof &2 & pid=$! sleep 1 #waittcp4port $PORT for o in $(filloptionvalues $OPTS|tr ',' ' '); do echo "testing if $ADDR accepts option $o" # echo $SOCAT $opts /dev/null $addr:$LOCALHOST:$PORT,$o $SOCAT $opts /dev/null $addr:$LOCALHOST:$PORT,$o done kill $pid done kill $pid 2>/dev/null opts= PORT=$((PORT+1)) fi #------------------------------------------------------------------------------ # test proxy connect #set -vx if true; then #if false; then #opts="-s -d -d -d -d" pid=$! for addr in proxy; do ADDR=$(echo "$addr" |tr a-z A-Z) TEST="$ADDR accepts all its options" echo "### $TEST" OPTGROUPS=$($SOCAT -? |fgrep " $addr:" |sed 's/.*=//') # echo OPTGROUPS=$OPTGROUPS OPTS= for g in $(echo $OPTGROUPS |tr ',' ' '); do eval "OPTG=\$OPTS_$(echo $g |tr a-z A-Z)"; OPTS="$OPTS,$OPTG"; done echo $OPTS # prepare dummy server $SOCAT tcp-l:$PORT,reuseaddr,crlf exec:"/bin/bash proxyecho.sh" || echo "cannot start proxyecho.sh" >&2 & pid=$! sleep 1 for o in $(filloptionvalues $OPTS|tr ',' ' '); do echo "testing if $ADDR accepts option $o" # echo $SOCAT $opts /dev/null $addr:$LOCALHOST:127.0.0.1:$PORT,$o $SOCAT $opts /dev/null $addr:$LOCALHOST:127.0.0.1:$((PORT+1)),proxyport=$PORT,$o done kill $pid 2>/dev/null done kill $pid 2>/dev/null opts= PORT=$((PORT+2)) fi #------------------------------------------------------------------------------ # test tcp4 #set -vx if true; then #if false; then #opts="-s -d -d -d -d" $SOCAT $opts tcp4-listen:$PORT,reuseaddr,fork,$o echo /dev/null opts= PORT=$((PORT+1)) fi #------------------------------------------------------------------------------ # test udp4-connect #set -vx if true; then #if false; then #opts="-s -d -d -d -d" $SOCAT $opts udp4-listen:$PORT,fork,$o echo /dev/null opts= PORT=$((PORT+1)) fi #------------------------------------------------------------------------------ # test tcp4-listen #set -vx if true; then #if false; then #opts="-s -d -d -d -d" for addr in tcp4-listen; do ADDR=$(echo "$addr" |tr a-z A-Z) TEST="$ADDR accepts all its options" echo "### $TEST" OPTGROUPS=$($SOCAT -? |fgrep " $addr:" |sed 's/.*=//') OPTS= for g in $(echo $OPTGROUPS |tr ',' ' '); do eval "OPTG=\$OPTS_$(echo $g |tr a-z A-Z)"; OPTS="$OPTS,$OPTG"; done echo $OPTS for o in $(filloptionvalues $OPTS|tr ',' ' '); do echo "testing if $ADDR accepts option $o" $SOCAT $opts $ADDR:$PORT,reuseaddr,$o echo /dev/null kill $pid 2>/dev/null done done opts= PORT=$((PORT+1)) fi #------------------------------------------------------------------------------ # test udp4-listen #set -vx if true; then #if false; then #opts="-s -d -d -d -d" for addr in udp4-listen; do ADDR=$(echo "$addr" |tr a-z A-Z) TEST="$ADDR accepts all its options" echo "### $TEST" OPTGROUPS=$($SOCAT -? |fgrep " $addr:" |sed 's/.*=//') OPTS= for g in $(echo $OPTGROUPS |tr ',' ' '); do eval "OPTG=\$OPTS_$(echo $g |tr a-z A-Z)"; OPTS="$OPTS,$OPTG"; done echo $OPTS for o in $(filloptionvalues $OPTS|tr ',' ' '); do echo "testing if $ADDR accepts option $o" $SOCAT $opts $ADDR:$PORT,reuseaddr,$o echo /dev/null kill $pid 2>/dev/null done done opts= PORT=$((PORT+1)) fi #------------------------------------------------------------------------------ # test udp4-sendto #set -vx if true; then #if false; then #opts="-s -d -d -d -d" $SOCAT $opts udp4-recv:$PORT,fork,$o echo /dev/null opts= PORT=$((PORT+1)) fi #------------------------------------------------------------------------------ # test udp4-datagram #set -vx if true; then #if false; then #opts="-s -d -d -d -d" #$SOCAT $opts udp4-recvfrom:$PORT,fork,$o echo /dev/null opts= PORT=$((PORT+1)) fi #------------------------------------------------------------------------------ # test udp4-recv #set -vx if true; then #if false; then #opts="-s -d -d -d -d" for addr in udp4-recv; do ADDR=$(echo "$addr" |tr a-z A-Z) TEST="$ADDR accepts all its options" echo "### $TEST" OPTGROUPS=$($SOCAT -? |fgrep " $addr:" |sed 's/.*=//') OPTS= for g in $(echo $OPTGROUPS |tr ',' ' '); do eval "OPTG=\$OPTS_$(echo $g |tr a-z A-Z)"; OPTS="$OPTS,$OPTG"; done echo $OPTS for o in $(filloptionvalues $OPTS|tr ',' ' '); do echo "testing if $ADDR accepts option $o" $SOCAT $opts $ADDR:$PORT,reuseaddr,$o echo /dev/null kill $pid 2>/dev/null done done opts= PORT=$((PORT+1)) fi #------------------------------------------------------------------------------ # test udp4-recvfrom #set -vx if true; then #if false; then #opts="-s -d -d -d -d" for addr in udp4-recvfrom; do ADDR=$(echo "$addr" |tr a-z A-Z) TEST="$ADDR accepts all its options" echo "### $TEST" OPTGROUPS=$($SOCAT -? |fgrep " $addr:" |sed 's/.*=//') OPTS= for g in $(echo $OPTGROUPS |tr ',' ' '); do eval "OPTG=\$OPTS_$(echo $g |tr a-z A-Z)"; OPTS="$OPTS,$OPTG"; done echo $OPTS for o in $(filloptionvalues $OPTS|tr ',' ' '); do echo "testing if $ADDR accepts option $o" $SOCAT $opts $ADDR:$PORT,reuseaddr,$o echo /dev/null kill $pid 2>/dev/null done done opts= PORT=$((PORT+1)) fi #------------------------------------------------------------------------------ # test ip4-sendto #set -vx if true; then #if false; then #opts="-s -d -d -d -d" $SOCAT $opts ip4-recv:$PORT,fork,$o echo /dev/null opts= PORT=$((PORT+1)) fi #------------------------------------------------------------------------------ # test ip4-recv #set -vx if true; then #if false; then #opts="-s -d -d -d -d" for addr in ip4-recv; do ADDR=$(echo "$addr" |tr a-z A-Z) TEST="$ADDR accepts all its options" echo "### $TEST" OPTGROUPS=$($SOCAT -? |fgrep " $addr:" |sed 's/.*=//') OPTS= for g in $(echo $OPTGROUPS |tr ',' ' '); do eval "OPTG=\$OPTS_$(echo $g |tr a-z A-Z)"; OPTS="$OPTS,$OPTG"; done echo $OPTS for o in $(filloptionvalues $OPTS|tr ',' ' '); do echo "testing if $ADDR accepts option $o" $SOCAT $opts $ADDR:$PORT,reuseaddr,$o echo /dev/null kill $pid 2>/dev/null done done opts= PORT=$((PORT+1)) fi #------------------------------------------------------------------------------ # test ip4-recvfrom #set -vx if true; then #if false; then #opts="-s -d -d -d -d" for addr in ip4-recvfrom; do ADDR=$(echo "$addr" |tr a-z A-Z) TEST="$ADDR accepts all its options" echo "### $TEST" OPTGROUPS=$($SOCAT -? |fgrep " $addr:" |sed 's/.*=//') OPTS= for g in $(echo $OPTGROUPS |tr ',' ' '); do eval "OPTG=\$OPTS_$(echo $g |tr a-z A-Z)"; OPTS="$OPTS,$OPTG"; done echo $OPTS for o in $(filloptionvalues $OPTS|tr ',' ' '); do echo "testing if $ADDR accepts option $o" $SOCAT $opts $ADDR:$PORT,reuseaddr,$o echo /dev/null kill $pid 2>/dev/null done done opts= PORT=$((PORT+1)) fi #------------------------------------------------------------------------------ # test READLINE if true; then #if false; then #opts="-s -d -d -d -d" for addr in readline; do ADDR=$(echo "$addr" |tr a-z A-Z) TEST="$ADDR accepts all its options" echo "### $TEST" TS=$TD/script$N OPTGROUPS=$($SOCAT -? |fgrep " $addr " |sed 's/.*=//') OPTS= for g in $(echo $OPTGROUPS |tr ',' ' '); do eval "OPTG=\$OPTS_$(echo $g |tr a-z A-Z)"; OPTS="$OPTS,$OPTG"; done #echo $OPTS for o in $(filloptionvalues $OPTS|tr ',' ' '); do # for o in bs0; do echo "testing if $ADDR accepts option $o" echo "$SOCAT $opts readline,$o /dev/null" >$TS chmod u+x $TS $SOCAT /dev/null,ignoreeof exec:$TS,pty #stty sane done #reset 1>&0 2>&0 done opts= fi #------------------------------------------------------------------------------ # unnamed pipe #if false; then if true; then for addr in pipe; do ADDR=$(echo "$addr" |tr a-z A-Z) TEST="unnamed $ADDR accepts all its options" echo "### $TEST" OPTGROUPS=$($SOCAT -? |egrep " $addr[^:]" |sed 's/.*=//') OPTS= for g in $(echo $OPTGROUPS |tr ',' ' '); do eval "OPTG=\$OPTS_$(echo $g |tr a-z A-Z)"; OPTS="$OPTS,$OPTG"; done #echo $OPTS for o in $(filloptionvalues $OPTS|tr ',' ' '); do echo testing if unnamed $ADDR accepts option $o $SOCAT $opts $addr,$o /dev/null $TF done done fi #------------------------------------------------------------------------------ # test OPEN address #! test it on pipe, device, new file N=1 #if false; then if true; then for addr in open; do ADDR=$(echo "$addr" |tr a-z A-Z) TEST="$ADDR on file accepts all its options" echo "### $TEST" TF=$TD/file$N OPTGROUPS=$($SOCAT -? |fgrep " $addr:" |sed 's/.*=//') OPTS= for g in $(echo $OPTGROUPS |tr ',' ' '); do eval "OPTG=\$OPTS_$(echo $g |tr a-z A-Z)"; OPTS="$OPTS,$OPTG"; done #echo $OPTS for o in $(filloptionvalues $OPTS|tr ',' ' '); do echo testing if $ADDR on file accepts option $o touch $TF $SOCAT $opts -!!$addr:$TF,$o /dev/null,ignoreof /dev/null rm -f $TF done if [ $(id -u) -eq 0 ]; then TEST="$ADDR on existing device accepts all its options" echo "### $TEST" TF=$TD/null OPTGROUPS=$($SOCAT -? |fgrep " $addr:" |sed 's/.*=//') OPTGROUPS=$(echo $OPTGROUPS |sed -e 's/,REG,/,/g' -e 's/,OPEN,/,/g') OPTS= for g in $(echo $OPTGROUPS |tr ',' ' '); do eval "OPTG=\$OPTS_$(echo $g |tr a-z A-Z)"; OPTS="$OPTS,$OPTG"; done #echo $OPTS for o in $(filloptionvalues $OPTS|tr ',' ' '); do echo testing if $ADDR on existing device accepts option $o rm -f $TF; mknod $TF c 1 3 $SOCAT $opts -!!$addr:$TF,$o /dev/null,ignoreof "$tf" 2>"$te" (psleep $T; echo "$da"; psleep $T) |($TRACE $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"; echo $? >"$td/test$N.rc") & export rc1=$! #sleep 5 && kill $rc1 2>/dev/null & # rc2=$! wait $rc1 # kill $rc2 2>/dev/null if [ "$(cat "$td/test$N.rc")" != 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$TRACE $SOCAT $opts $arg1 $arg2" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif echo "$da" |diff - "$tf" >"$tdiff" 2>&1; then $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) else $PRINTF "$FAILED:\n" echo "$TRACE $SOCAT $opts $arg1 $arg2" cat "$te" echo diff: cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND } # test if call to od and throughput of data works - with graceful shutdown and # flush of od buffers testod () { local num="$1" local title="$2" local arg1="$3"; [ -z "$arg1" ] && arg1="-" local arg2="$4"; [ -z "$arg2" ] && arg2="echo" local opts="$5" local T="$6"; [ -z "$T" ] && T=0 local tf="$td/test$N.stdout" local te="$td/test$N.stderr" local tr="$td/test$N.ref" local tdiff="$td/test$N.diff" local dain="$(date) $RANDOM" if ! eval $NUMCOND; then :; else echo "$dain" |$OD_C >"$tr" # local daout="$(echo "$dain" |$OD_C)" $PRINTF "test $F_n %s... " $num "$title" (psleep $T; echo "$dain"; psleep $T) |$TRACE $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te" if [ "$?" != 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$TRACE $SOCAT $opts $arg1 $arg2" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $num" # elif echo "$daout" |diff - "$tf" >"$tdiff" 2>&1; then elif diff "$tr" "$tf" >"$tdiff" 2>&1; then $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) else $PRINTF "$FAILED: diff:\n" echo "$TRACE $SOCAT $opts $arg1 $arg2" cat "$te" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $num" fi fi # NUMCOND } # test if the socat executable has these address types compiled in # print the first missing address type testaddrs () { local a A; for a in $@; do A=$(echo "$a" |tr 'a-z-' 'A-Z_') if $TRACE $SOCAT -V |grep "#define WITH_$A 1\$" >/dev/null; then shift continue fi echo "$a" return 1 done return 0 } # test if the socat executable has these options compiled in # print the first missing option testoptions () { local a A; for a in $@; do A=$(echo "$a" |tr 'a-z' 'A-Z') if $TRACE $SOCAT -??? |grep "[^a-z0-9-]$a[^a-z0-9-]" >/dev/null; then shift continue fi echo "$a" return 1 done return 0 } # check if the given pid exists and has child processes # if yes: prints child process lines to stdout, returns 0 # if not: prints ev.message to stderr, returns 1 childprocess () { local l case "$UNAME" in AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)")" ;; FreeBSD) l="$(ps -faje |grep "^........ ..... $(printf %5u $1)")" ;; HP-UX) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;; Linux) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;; # NetBSD) l="$(ps -aj |grep "^........ ..... $(printf %4u $1)")" ;; NetBSD) l="$(ps -aj |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)")" ;; OpenBSD) l="$(ps -aj |grep "^........ ..... $(printf %5u $1)")" ;; SunOS) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;; DragonFly)l="$(ps -faje |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)")" ;; CYGWIN*) l="$(ps -pafe |grep "^[^ ]*[ ][ ]*[^ ][^ ]*[ ][ ]*$1[ ]")" ;; *) l="$(ps -fade |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]**[ ][ ]*$(printf %5u $1) ")" ;; esac if [ -z "$l" ]; then return 1; fi echo "$l" return 0 } # check if the given process line refers to a defunct (zombie) process # yes: returns 0 # no: returns 1 isdefunct () { local l case "$UNAME" in AIX) l="$(echo "$1" |grep ' $')" ;; FreeBSD) l="$(echo "$1" |grep ' $')" ;; HP-UX) l="$(echo "$1" |grep ' $')" ;; Linux) l="$(echo "$1" |grep ' $')" ;; SunOS) l="$(echo "$1" |grep ' $')" ;; DragonFly)l="$(echo "$1" |grep ' $')" ;; *) l="$(echo "$1" |grep ' $')" ;; esac [ -n "$l" ]; } # check if UNIX socket protocol is available on host runsunix () { return 0; $TRACE $SOCAT /dev/null UNIX-LISTEN:"$td/unix.socket" 2>"$td/unix.stderr" & pid=$! usleep $MICROS kill "$pid" 2>/dev/null test ! -s "$td/unix.stderr" } unset HAVENOT_IP4 # check if an IP4 loopback interface exists runsip4 () { [ -n "$HAVENOT_IP4" ] && return $HAVENOT_IP4 local l case "$UNAME" in AIX) l=$($IFCONFIG lo0 |fgrep 'inet 127.0.0.1 ') ;; FreeBSD) l=$($IFCONFIG lo0 |fgrep 'inet 127.0.0.1 ') ;; HP-UX) l=$($IFCONFIG lo0 |fgrep 'inet 127.0.0.1 ') ;; Linux) l=$($IFCONFIG |egrep 'inet (addr:)?127\.0\.0\.1 ') ;; NetBSD)l=$($IFCONFIG -a |fgrep 'inet 127.0.0.1 ');; OpenBSD)l=$($IFCONFIG -a |fgrep 'inet 127.0.0.1 ');; OSF1) l=$($IFCONFIG -a |grep ' inet ') ;; SunOS) l=$($IFCONFIG -a |grep 'inet ') ;; Darwin)l=$($IFCONFIG lo0 |fgrep 'inet 127.0.0.1 ') ;; DragonFly)l=$($IFCONFIG -a |fgrep 'inet 127.0.0.1 ');; CYGWIN*) l=$(ipconfig |grep IPv4);; *) l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;; esac [ -z "$l" ] && return 1 # existence of interface might not suffice, check for routeability: case "$UNAME" in Darwin) ping -c 1 127.0.0.1; l="$?" ;; Linux) ping -c 1 127.0.0.1; l="$?" ;; *) if [ -n "$l" ]; then l=0; else l=1; fi ;; esac HAVENOT_IP4=$l return $l; } unset HAVENOT_IP6 # check if an IP6 loopback interface exists runsip6 () { [ -n "$HAVENOT_IP6" ] && return $HAVENOT_IP6 local l case "$UNAME" in AIX) l=$($IFCONFIG lo0 |grep 'inet6 ::1/0') ;; HP-UX) l=$($IFCONFIG lo0 |grep ' inet6 ') ;; Linux) l=$($IFCONFIG |egrep 'inet6 (addr: )?::1/?') ;; NetBSD)l=$($IFCONFIG -a |grep 'inet6 ::1 ');; OSF1) l=$($IFCONFIG -a |grep ' inet6 ') ;; SunOS) l=$($IFCONFIG -a |grep 'inet6 ') ;; Darwin)l=$($IFCONFIG lo0 |grep 'inet6 ::1 ') ;; CYGWIN*) l=$(ipconfig |grep IPv6);; *) l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;; esac [ -z "$l" ] && return 1 # existence of interface might not suffice, check for routeability: case "$UNAME" in Darwin) ping6 -c 1 ::1; l="$?" ;; Linux) ping6 -c 1 ::1; l="$?" ;; *) if [ -n "$l" ]; then l=0; else l=1; fi ;; esac HAVENOT_IP6=$l return $l; } # check if TCP on IPv4 is available on host runstcp4 () { return 0; # PORT="$1" $TRACE $SOCAT $opts /dev/null TCP4-LISTEN:$PORT 2>"$td/tcp4.stderr" & pid=$! usleep $MICROS kill "$pid" 2>/dev/null wait usleep $MICROS test ! -s "$td/tcp4.stderr" } # check if TCP on IPv6 is available on host runstcp6 () { return 0; # PORT="$1" $TRACE $SOCAT $opts /dev/null TCP6-LISTEN:$PORT 2>"$td/tcp6.stderr" & pid=$! kill "$pid" 2>/dev/null wait usleep $MICROS test ! -s "$td/tcp6.stderr" } # check if UDP on IPv4 is available on host runsudp4 () { return 0; # PORT="$1" $TRACE $SOCAT $opts /dev/null UDP4-LISTEN:$PORT 2>"$td/udp4.stderr" & pid=$! usleep $MICROS kill "$pid" 2>/dev/null wait usleep $MICROS test ! -s "$td/udp4.stderr" } # check if UDP on IPv6 is available on host runsudp6 () { return 0; # PORT="$1" $TRACE $SOCAT $opts /dev/null UDP6-LISTEN:$PORT 2>"$td/udp6.stderr" & pid=$! usleep $MICROS kill "$pid" 2>/dev/null wait usleep $MICROS test ! -s "$td/udp6.stderr" } # check if SCTP on IPv4 is available on host runssctp4 () { # PORT="$1" $TRACE $SOCAT $opts /dev/null SCTP4-LISTEN:$PORT 2>"$td/sctp4.stderr" & pid=$! usleep $MICROS kill "$pid" 2>/dev/null wait usleep $MICROS test ! -s "$td/sctp4.stderr" } # check if SCTP on IPv6 is available on host runssctp6 () { #PORT="$1" $TRACE $SOCAT $opts /dev/null SCTP6-LISTEN:$PORT 2>"$td/sctp6.stderr" & pid=$! usleep $MICROS kill "$pid" 2>/dev/null wait usleep $MICROS test ! -s "$td/sctp6.stderr" } # wait until an IP4 protocol is ready waitip4proto () { local proto="$1" local logic="$2" # 0..wait until free; 1..wait until listening local timeout="$3" local l [ "$logic" ] || logic=1 [ "$timeout" ] || timeout=5 while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) l=$(netstat -n -w -l |grep '^raw .* .*[0-9*]:'$proto' [ ]*0\.0\.0\.0:\*') ;; # FreeBSD) l=$(netstat -an |egrep '^raw46? .*[0-9*]\.'$proto' .* \*\.\*') ;; # NetBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;; # OpenBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;; # Darwin) case "$(uname -r)" in # [1-5]*) l=$(netstat -an |grep '^raw.* .*[0-9*]\.'$proto' .* \*\.\*') ;; # *) l=$(netstat -an |grep '^raw4.* .*[0-9*]\.'$proto' .* \*\.\* .*') ;; # esac ;; AIX) # does not seem to show raw sockets in netstat sleep 1; return 0 ;; # SunOS) l=$(netstat -an -f inet -P raw |grep '.*[1-9*]\.'$proto' [ ]*Idle') ;; # HP-UX) l=$(netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' .* \*\.\* ') ;; # OSF1) l=$(/usr/sbin/netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' [ ]*\*\.\*') ;; *) #l=$(netstat -an |grep -i 'raw .*[0-9*][:.]'$proto' ') ;; sleep 1; return 0 ;; esac [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0 sleep 1 timeout=$((timeout-1)) done $ECHO "!protocol $proto timed out! \c" >&2 return 1 } # we need this misleading function name for canonical reasons waitip4port () { waitip4proto "$1" "$2" "$3" } # wait until an IP6 protocol is ready waitip6proto () { local proto="$1" local logic="$2" # 0..wait until free; 1..wait until listening local timeout="$3" local l [ "$logic" ] || logic=1 [ "$timeout" ] || timeout=5 while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) l=$(netstat -n -w -l |grep '^raw[6 ] .* .*:[0-9*]*:'$proto' [ ]*:::\*') ;; # FreeBSD) l=$(netstat -an |egrep '^raw46? .*[0-9*]\.'$proto' .* \*\.\*') ;; # NetBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;; # OpenBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;; # Darwin) case "$(uname -r)" in # [1-5]*) l=$(netstat -an |grep '^raw.* .*[0-9*]\.'$proto' .* \*\.\*') ;; # *) l=$(netstat -an |grep '^raw4.* .*[0-9*]\.'$proto' .* \*\.\* .*') ;; # esac ;; AIX) # does not seem to show raw sockets in netstat sleep 1; return 0 ;; # SunOS) l=$(netstat -an -f inet -P raw |grep '.*[1-9*]\.'$proto' [ ]*Idle') ;; # HP-UX) l=$(netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' .* \*\.\* ') ;; # OSF1) l=$(/usr/sbin/netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' [ ]*\*\.\*') ;; *) #l=$(netstat -an |egrep -i 'raw6? .*[0-9*][:.]'$proto' ') ;; sleep 1; return 0 ;; esac [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0 sleep 1 timeout=$((timeout-1)) done $ECHO "!protocol $proto timed out! \c" >&2 return 1 } # we need this misleading function name for canonical reasons waitip6port () { waitip6proto "$1" "$2" "$3" } # check if a TCP4 port is in use # exits with 0 when it is not used checktcp4port () { local port="$1" local l case "$UNAME" in Linux) l=$(netstat -a -n -t |grep '^tcp .* .*[0-9*]:'$port' .* LISTEN') ;; FreeBSD) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; NetBSD) l=$(netstat -an |grep '^tcp .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; Darwin) case "$(uname -r)" in [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; esac ;; AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; SunOS) l=$(netstat -an -f inet -P tcp |grep '.*[1-9*]\.'$port' .*\* 0 .* LISTEN') ;; HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;; OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;; CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;; DragonFly)l=$(netstat -ant |grep '^tcp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; *) l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .* listen') ;; esac [ -z "$l" ] && return 0 return 1 } # wait until a TCP4 listen port is ready waittcp4port () { local port="$1" local logic="$2" # 0..wait until free; 1..wait until listening local timeout="$3" local l local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here [ "$logic" ] || logic=1 [ "$timeout" ] || timeout=5 while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) l=$(netstat -a -n -t -l |grep '^tcp .* .*[0-9*]:'$port' .* LISTEN') ;; FreeBSD) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; NetBSD) l=$(netstat -an |grep '^tcp .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; Darwin) case "$(uname -r)" in [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; esac ;; AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; SunOS) l=$(netstat -an -f inet -P tcp |grep '.*[1-9*]\.'$port' .*\* 0 .* LISTEN') ;; HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;; OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;; CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;; DragonFly) l=$(netstat -ant |grep '^tcp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; *) l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .* listen') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then set ${vx}vx return 0 fi sleep 1 timeout=$((timeout-1)) done $ECHO "!port $port timed out! \c" >&2 set ${vx}vx return 1 } # wait until a UDP4 port is ready waitudp4port () { local port="$1" local logic="$2" # 0..wait until free; 1..wait until listening local timeout="$3" local l local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here [ "$logic" ] || logic=1 [ "$timeout" ] || timeout=5 while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) l=$(netstat -a -n -u -l |grep '^udp .* .*[0-9*]:'$port' [ ]*0\.0\.0\.0:\*') ;; FreeBSD) l=$(netstat -an |egrep '^udp46? .*[0-9*]\.'$port' .* \*\.\*') ;; NetBSD) l=$(netstat -an |grep '^udp .*[0-9*]\.'$port' [ ]* \*\.\*') ;; OpenBSD) l=$(netstat -an |grep '^udp .*[0-9*]\.'$port' [ ]* \*\.\*') ;; Darwin) case "$(uname -r)" in [1-5]*) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\*') ;; *) l=$(netstat -an |grep '^udp4.* .*[0-9*]\.'$port' .* \*\.\* .*') ;; esac ;; AIX) l=$(netstat -an |grep '^udp[4 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;; SunOS) l=$(netstat -an -f inet -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;; HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' .* \*\.\* ') ;; OSF1) l=$(/usr/sbin/netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;; DragonFly) l=$(netstat -an |grep '^udp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;; *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then set ${vx}vx return 0 fi sleep 1 timeout=$((timeout-1)) done $ECHO "!port $port timed out! \c" >&2 set ${vx}vx return 1 } # wait until an SCTP4 listen port is ready waitsctp4port () { local port="$1" local logic="$2" # 0..wait until free; 1..wait until listening local timeout="$3" local l local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here [ "$logic" ] || logic=1 [ "$timeout" ] || timeout=5 while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) l=$(netstat -n -a |grep '^sctp .* .*[0-9*]:'$port' .* LISTEN') ;; # FreeBSD) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; # NetBSD) l=$(netstat -an |grep '^tcp .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; # Darwin) case "$(uname -r)" in # [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; # *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; # esac ;; # AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; SunOS) l=$(netstat -an -f inet -P sctp |grep '.*[1-9*]\.'$port' .*\* 0 .* LISTEN') ;; # HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;; # OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;; # CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;; *) l=$(netstat -an |grep -i 'sctp .*[0-9*][:.]'$port' .* listen') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then set ${vx}vx return 0 fi sleep 1 timeout=$((timeout-1)) done $ECHO "!port $port timed out! \c" >&2 set ${vx}vx return 1 } # wait until a tcp6 listen port is ready waittcp6port () { local port="$1" local logic="$2" # 0..wait until free; 1..wait until listening local timeout="$3" local l local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here [ "$logic" ] || logic=1 [ "$timeout" ] || timeout=5 while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) l=$(netstat -an |grep -E '^tcp6? .* [0-9a-f:%]*:'$port' .* LISTEN') ;; FreeBSD) l=$(netstat -an |egrep -i 'tcp(6|46) .*[0-9*][:.]'$port' .* listen') ;; NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;; Darwin) l=$(netstat -an |egrep '^tcp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+ +LISTEN') ;; AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; SunOS) l=$(netstat -an -f inet6 -P tcp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;; #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;; DragonFly) l=$(netstat -ant |grep '^tcp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; *) l=$(netstat -an |grep -i 'tcp6 .*:'$port' .* listen') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then set ${vx}vx return 0 fi sleep 1 timeout=$((timeout-1)) done $ECHO "!port $port timed out! \c" >&2 #echo set ${vx}vx >&2 set ${vx}vx return 1 } # wait until a UDP6 port is ready waitudp6port () { local port="$1" local logic="$2" # 0..wait until free; 1..wait until listening local timeout="$3" local l local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here [ "$logic" ] || logic=1 [ "$timeout" ] || timeout=5 while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) l=$(netstat -an |grep -E '^udp6? .* .*[0-9*:%]:'$port' [ ]*:::\*') ;; FreeBSD) l=$(netstat -an |egrep '^udp(6|46) .*[0-9*]\.'$port' .* \*\.\*') ;; NetBSD) l=$(netstat -an |grep '^udp6 .* \*\.'$port' [ ]* \*\.\*') ;; OpenBSD) l=$(netstat -an |grep '^udp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; Darwin) l=$(netstat -an |egrep '^udp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+') ;; AIX) l=$(netstat -an |grep '^udp[6 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;; SunOS) l=$(netstat -an -f inet6 -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;; #HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' ') ;; #OSF1) l=$(/usr/sbin/netstat -an |grep '^udp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;; DragonFly) l=$(netstat -ant |grep '^udp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;; *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then set ${vx}vx return 0 fi sleep 1 timeout=$((timeout-1)) done $ECHO "!port $port timed out! \c" >&2 set ${vx}vx return 1 } # wait until a sctp6 listen port is ready # not all (Linux) variants show this in netstat waitsctp6port () { local port="$1" local logic="$2" # 0..wait until free; 1..wait until listening local timeout="$3" local l local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here [ "$logic" ] || logic=1 [ "$timeout" ] || timeout=5 while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) l=$(netstat -an |grep '^sctp[6 ] .* [0-9a-f:]*:'$port' .* LISTEN') ;; # FreeBSD) l=$(netstat -an |grep -i 'tcp[46][6 ] .*[0-9*][:.]'$port' .* listen') ;; # NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; # OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;; # AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; SunOS) l=$(netstat -an -f inet6 -P sctp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;; # #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;; *) l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then set ${vx}vx return 0 fi sleep 1 timeout=$((timeout-1)) done $ECHO "!port $port timed out! \c" >&2 set ${vx}vx return 1 } # we need this misleading function name for canonical reasons waitunixport () { waitfile "$1" "$2" "$3" } # wait until a filesystem entry exists waitfile () { local crit=-e case "X$1" in X-*) crit="$1"; shift ;; esac local file="$1" local logic="$2" # 0..wait until gone; 1..wait until exists (default); # 2..wait until not empty local timeout="$3" local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here [ "$logic" ] || logic=1 [ "$logic" -eq 2 ] && crit=-s [ "$timeout" ] || timeout=5 while [ $timeout -gt 0 ]; do if [ \( \( $logic -ne 0 \) -a $crit "$file" \) -o \ \( \( $logic -eq 0 \) -a ! $crit "$file" \) ]; then set ${vx}vx return 0 fi sleep 1 timeout=$((timeout-1)) done echo "file $file timed out" >&2 set ${vx}vx return 1 } # generate a test certificate and key gentestcert () { local name="$1" if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi openssl genrsa $OPENSSL_RAND -out $name.key 768 >/dev/null 2>&1 openssl req -new -config $TESTCERT_CONF -key $name.key -x509 -out $name.crt -days 3653 >/dev/null 2>&1 cat $name.key $name.crt >$name.pem } # generate a test DSA key and certificate gentestdsacert () { local name="$1" if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi openssl dsaparam -out $name-dsa.pem 1024 >/dev/null 2>&1 openssl dhparam -dsaparam -out $name-dh.pem 1024 >/dev/null 2>&1 openssl req -newkey dsa:$name-dsa.pem -keyout $name.key -nodes -x509 -config $TESTCERT_CONF -out $name.crt -days 3653 >/dev/null 2>&1 cat $name-dsa.pem $name-dh.pem $name.key $name.crt >$name.pem } gentestcert6 () { local name="$1" if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi cat $TESTCERT_CONF | { echo "# automatically generated by $0"; cat; } | sed 's/\(commonName\s*=\s*\).*/\1[::1]/' >$TESTCERT6_CONF openssl genrsa $OPENSSL_RAND -out $name.key 768 >/dev/null 2>&1 openssl req -new -config $TESTCERT6_CONF -key $name.key -x509 -out $name.crt -days 3653 >/dev/null 2>&1 cat $name.key $name.crt >$name.pem } NAME=UNISTDIO case "$TESTS " in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) TEST="$NAME: unidirectional throughput from stdin to stdout" testecho "$N" "$TEST" "stdin" "stdout" "$opts -u" esac N=$((N+1)) NAME=UNPIPESTDIO case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) TEST="$NAME: stdio with simple echo via internal pipe" testecho "$N" "$TEST" "stdio" "pipe" "$opts" esac N=$((N+1)) NAME=UNPIPESHORT case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) TEST="$NAME: short form of stdio ('-') with simple echo via internal pipe" testecho "$N" "$TEST" "-" "pipe" "$opts" esac N=$((N+1)) NAME=DUALSTDIO case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) TEST="$NAME: splitted form of stdio ('stdin!!stdout') with simple echo via internal pipe" testecho "$N" "$TEST" "stdin!!stdout" "pipe" "$opts" esac N=$((N+1)) NAME=DUALSHORTSTDIO case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) TEST="$NAME: short splitted form of stdio ('-!!-') with simple echo via internal pipe" testecho "$N" "$TEST" "-!!-" "pipe" "$opts" esac N=$((N+1)) NAME=DUALFDS case "$TESTS" in *%$N%*|*%functions%*|*%fd%*|*%$NAME%*) TEST="$NAME: file descriptors with simple echo via internal pipe" testecho "$N" "$TEST" "0!!1" "pipe" "$opts" esac N=$((N+1)) NAME=NAMEDPIPE case "$TESTS" in *%$N%*|*%functions%*|*%pipe%*|*%$NAME%*) TEST="$NAME: simple echo via named pipe" # with MacOS, this test hangs if nonblock is not used. Is an OS bug. tp="$td/pipe$N" # note: the nonblock is required by MacOS 10.1(?), otherwise it hangs (OS bug?) testecho "$N" "$TEST" "" "pipe:$tp,nonblock" "$opts" esac N=$((N+1)) NAME=DUALPIPE case "$TESTS" in *%$N%*|*%functions%*|*%pipe%*|*%$NAME%*) TEST="$NAME: simple echo via named pipe, specified twice" tp="$td/pipe$N" testecho "$N" "$TEST" "" "pipe:$tp,nonblock!!pipe:$tp" "$opts" esac N=$((N+1)) NAME=FILE case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%file%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: simple echo via file" tf="$td/file$N" testecho "$N" "$TEST" "" "$tf,ignoreeof!!$tf" "$opts" esac N=$((N+1)) NAME=EXECSOCKET case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with socketpair" testecho "$N" "$TEST" "" "exec:$CAT" "$opts" esac N=$((N+1)) NAME=SYSTEMSOCKET case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with socketpair" testecho "$N" "$TEST" "" "system:$CAT" "$opts" "$val_t" esac N=$((N+1)) NAME=EXECPIPES case "$TESTS" in *%$N%*|*%functions%*|*%pipe%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with pipes" testecho "$N" "$TEST" "" "exec:$CAT,pipes" "$opts" esac N=$((N+1)) NAME=SYSTEMPIPES case "$TESTS" in *%$N%*|*%functions%*|*%pipes%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with pipes" testecho "$N" "$TEST" "" "system:$CAT,pipes" "$opts" esac N=$((N+1)) NAME=EXECPTY case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%pty%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with pseudo terminal" if ! eval $NUMCOND; then :; elif ! testaddrs pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "" "exec:$CAT,pty,$PTYOPTS" "$opts" fi esac N=$((N+1)) NAME=SYSTEMPTY case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%pty%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with pseudo terminal" if ! eval $NUMCOND; then :; elif ! testaddrs pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "" "system:$CAT,pty,$PTYOPTS" "$opts" fi esac N=$((N+1)) NAME=SYSTEMPIPESFDS case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with pipes, non stdio" testecho "$N" "$TEST" "" "system:$CAT>&9 <&8,pipes,fdin=8,fdout=9" "$opts" esac N=$((N+1)) NAME=DUALSYSTEMFDS case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%$NAME%*) TEST="$NAME: echo via dual system() of cat" testecho "$N" "$TEST" "system:$CAT>&6,fdout=6!!system:$CAT<&7,fdin=7" "" "$opts" "$val_t" esac N=$((N+1)) # test: send EOF to exec'ed sub process, let it finish its operation, and # check if the sub process returns its data before terminating. NAME=EXECSOCKETFLUSH # idea: have socat exec'ing od; send data and EOF, and check if the od'ed data # arrives. case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%$NAME%*) TEST="$NAME: call to od via exec with socketpair" testod "$N" "$TEST" "" "exec:$OD_C" "$opts" esac N=$((N+1)) NAME=SYSTEMSOCKETFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%$NAME%*) TEST="$NAME: call to od via system() with socketpair" testod "$N" "$TEST" "" "system:$OD_C" "$opts" $val_t esac N=$((N+1)) NAME=EXECPIPESFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%$NAME%*) TEST="$NAME: call to od via exec with pipes" testod "$N" "$TEST" "" "exec:$OD_C,pipes" "$opts" esac N=$((N+1)) NAME=SYSTEMPIPESFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%$NAME%*) TEST="$NAME: call to od via system() with pipes" testod "$N" "$TEST" "" "system:$OD_C,pipes" "$opts" "$val_t" esac N=$((N+1)) ## LATER: #NAME=EXECPTYFLUSH #case "$TESTS" in #*%$N%*|*%functions%*|*%exec%*|*%pty%*|*%$NAME%*) #TEST="$NAME: call to od via exec with pseudo terminal" #if ! testaddrs pty >/dev/null; then # $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N # numCANT=$((numCANT+1)) #else #testod "$N" "$TEST" "" "exec:$OD_C,pty,$PTYOPTS" "$opts" #fi #esac #N=$((N+1)) ## LATER: #NAME=SYSTEMPTYFLUSH #case "$TESTS" in #*%$N%*|*%functions%*|*%system%*|*%pty%*|*%$NAME%*) #TEST="$NAME: call to od via system() with pseudo terminal" #if ! testaddrs pty >/dev/null; then # $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N # numCANT=$((numCANT+1)) #else #testod "$N" "$TEST" "" "system:$OD_C,pty,$PTYOPTS" "$opts" #fi #esac #N=$((N+1)) NAME=SYSTEMPIPESFDSFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%$NAME%*) TEST="$NAME: call to od via system() with pipes, non stdio" testod "$N" "$TEST" "" "system:$OD_C>&9 <&8,pipes,fdin=8,fdout=9" "$opts" "$val_t" esac N=$((N+1)) NAME=DUALSYSTEMFDSFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%$NAME%*) TEST="$NAME: call to od via dual system()" testod "$N" "$TEST" "system:$OD_C>&6,fdout=6!!system:$CAT<&7,fdin=7" "pipe" "$opts" "$val_t" esac N=$((N+1)) case "$UNAME" in Linux) IPPROTO=254 ;; Darwin) IPPROTO=255 ;; *) IPPROTO=254 ;; # just a guess esac NAME=RAWIP4SELF case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%rawip%*|*%root%*|*%$NAME%*) TEST="$NAME: simple echo via self receiving raw IPv4 protocol" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs rawip) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "" "ip4:127.0.0.1:$IPPROTO" "$opts" fi esac N=$((N+1)) NAME=RAWIPX4SELF case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%rawip%*|*%root%*|*%$NAME%*) TEST="$NAME: simple echo via self receiving raw IP protocol, v4 by target" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs rawip) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "" "ip:127.0.0.1:$IPPROTO" "$opts" fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=RAWIP6SELF case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%rawip%*|*%root%*|*%$NAME%*) TEST="$NAME: simple echo via self receiving raw IPv6 protocol" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "" "ip6:[::1]:$IPPROTO" "$opts" fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=RAWIPX6SELF case "$TESTS" in *%$N%*|*%functions%*|*%ip%*|*%ip6%*|*%rawip%*|*%rawip6%*|*%root%*|*%$NAME%*) TEST="$NAME: simple echo via self receiving raw IP protocol, v6 by target" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "" "ip:[::1]:$IPPROTO" "$opts" fi esac N=$((N+1)) NAME=TCPSELF case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: echo via self connection of TCP IPv4 socket" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N numCANT=$((numCANT+1)) else #ts="127.0.0.1:$tsl" testecho "$N" "$TEST" "" "tcp:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR,reuseaddr" "$opts" fi esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDPSELF if ! eval $NUMCOND; then :; else case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: echo via self connection of UDP IPv4 socket" if [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "" "udp:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR" "$opts" fi esac fi # NUMCOND PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6SELF case "$TESTS" in *%$N%*|*%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%$NAME%*) TEST="$NAME: echo via self connection of UDP IPv6 socket" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs udp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/file$N" testecho "$N" "$TEST" "" "udp6:[::1]:$PORT,sp=$PORT,bind=[::1]" "$opts" fi esac PORT=$((PORT+1)) N=$((N+1)) NAME=DUALUDPSELF if ! eval $NUMCOND; then :; else case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: echo via two unidirectional UDP IPv4 sockets" tf="$td/file$N" p1=$PORT p2=$((PORT+1)) testecho "$N" "$TEST" "" "udp:127.0.0.1:$p2,sp=$p1!!udp:127.0.0.1:$p1,sp=$p2" "$opts" esac fi # NUMCOND PORT=$((PORT+2)) N=$((N+1)) #function testdual { # local #} NAME=UNIXSTREAM if ! eval $NUMCOND; then :; else case "$TESTS" in *%$N%*|*%functions%*|*%unix%*|*%$NAME%*) TEST="$NAME: echo via connection to UNIX domain socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" ts="$td/test$N.socket" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts UNIX-LISTEN:$ts PIPE" CMD2="$TRACE $SOCAT $opts -!!- UNIX-CONNECT:$ts" printf "test $F_n $TEST... " $N $CMD1 $tf 2>"${te}1" & bg=$! # background process id waitfile "$ts" echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $bg 2>/dev/null esac fi # NUMCOND N=$((N+1)) NAME=TCP4 if ! eval $NUMCOND; then :; else case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: echo via connection to TCP V4 socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1=$! waittcp4port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" cat "${te}1" echo "$CMD2" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid1 2>/dev/null wait ;; esac PORT=$((PORT+1)) fi # NUMCOND N=$((N+1)) #et -xv NAME=TCP6 case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: echo via connection to TCP V6 socket" if ! eval $NUMCOND; then :; elif ! testaddrs tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="[::1]:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts TCP6-listen:$tsl,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP6:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid=$! # background process id waittcp6port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null fi esac PORT=$((PORT+1)) N=$((N+1)) #set +vx NAME=TCPX4 case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: echo via connection to TCP socket, v4 by target" if ! eval $NUMCOND; then :; elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts TCP-listen:$tsl,pf=ip4,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid=$! # background process id waittcp4port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null fi esac PORT=$((PORT+1)) N=$((N+1)) NAME=TCPX6 case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: echo via connection to TCP socket, v6 by target" if ! eval $NUMCOND; then :; elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="[::1]:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts TCP-listen:$tsl,pf=ip6,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid=$! # background process id waittcp6port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null fi esac PORT=$((PORT+1)) N=$((N+1)) # TCP6-LISTEN may also listen for IPv4 connections. Test if option # ipv6-v6only=0 shows this behaviour. NAME=IPV6ONLY0 case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: option ipv6-v6only=0 listens on IPv4" # create a listening TCP6 socket and try to connect to the port using TCP4 if ! eval $NUMCOND; then :; elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,ipv6-v6only=0,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid=$! # background process id waittcp6port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null fi esac PORT=$((PORT+1)) N=$((N+1)) #set -vx # TCP6-LISTEN may also listen for IPv4 connections. Test if option # ipv6-v6only=1 turns off this behaviour. NAME=IPV6ONLY1 case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: option ipv6-v6only=1 does not listen on IPv4" if ! eval $NUMCOND; then :; elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts TCP6-listen:$tsl,ipv6-v6only=1,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid=$! # background process id waittcp6port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -eq 0 ]; then $PRINTF "$FAILED:\n" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED:\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" numOK=$((numOK+1)) fi kill $pid; wait wait fi esac PORT=$((PORT+1)) N=$((N+1)) #set +vx NAME=ENV_LISTEN_4 case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv4 preference on listen" if ! eval $NUMCOND; then :; elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts TCP-listen:$tsl,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" & pid=$! # background process id waittcp4port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null; wait fi esac PORT=$((PORT+1)) N=$((N+1)) NAME=ENV_LISTEN_6 case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv6 preference on listen" if ! eval $NUMCOND; then :; elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="[::1]:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts TCP-listen:$tsl,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP6:$ts" printf "test $F_n $TEST... " $N SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" & pid=$! # background process id waittcp6port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null; wait fi esac PORT=$((PORT+1)) N=$((N+1)) NAME=LISTEN_OPTION_4 case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: option -4 for IPv4 preference on listen" if ! eval $NUMCOND; then :; elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -4 TCP-listen:$tsl,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" & pid=$! # background process id waittcp4port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null; wait fi esac PORT=$((PORT+1)) N=$((N+1)) NAME=LISTEN_OPTION_6 case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: option -6 for IPv6 preference on listen" if ! eval $NUMCOND; then :; elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="[::1]:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -6 TCP-listen:$tsl,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP6:$ts" printf "test $F_n $TEST... " $N SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" & pid=$! # background process id waittcp6port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null; wait wait fi # feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=LISTEN_PF_IP4 case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: pf=4 overrides option -6 on listen" if ! eval $NUMCOND; then :; elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -6 TCP-listen:$tsl,pf=ip4,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" & pid=$! # background process id waittcp4port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null; wait fi esac PORT=$((PORT+1)) N=$((N+1)) NAME=LISTEN_PF_IP6 case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: pf=6 overrides option -4 on listen" if ! eval $NUMCOND; then :; elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="[::1]:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -4 TCP-listen:$tsl,pf=ip6,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP6:$ts" printf "test $F_n $TEST... " $N SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" & pid=$! # background process id waittcp6port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null; wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP4STREAM case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%$NAME%*) TEST="$NAME: echo via connection to UDP V4 socket" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="$LOCALHOST:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts UDP4-LISTEN:$tsl,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts - UDP4:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1=$! waitudp4port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD1 &" cat "${te}1" echo "$CMD2" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6STREAM case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%udp%*|*%$NAME%*) TEST="$NAME: echo via connection to UDP V6 socket" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="$LOCALHOST6:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts UDP6-LISTEN:$tsl,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts - UDP6:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1=$! waitudp6port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi fi ;; # ! testaddrs esac PORT=$((PORT+1)) N=$((N+1)) NAME=GOPENFILE case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%gopen%*|*%file%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: file opening with gopen" if ! eval $NUMCOND; then :; else tf1="$td/test$N.1.stdout" tf2="$td/test$N.2.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" echo "$da" >$tf1 CMD="$TRACE $SOCAT $opts $tf1!!/dev/null /dev/null,ignoreeof!!-" printf "test $F_n $TEST... " $N $CMD >"$tf2" 2>"$te" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! diff "$tf1" "$tf2" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi # NUMCOND esac N=$((N+1)) NAME=GOPENPIPE case "$TESTS" in *%$N%*|*%functions%*|*%gopen%*|*%pipe%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: pipe opening with gopen for reading" if ! eval $NUMCOND; then :; else tp="$td/pipe$N" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD="$TRACE $SOCAT $opts $tp!!/dev/null /dev/null,ignoreeof!!$tf" printf "test $F_n $TEST... " $N #mknod $tp p # no mknod p on FreeBSD mkfifo $tp $CMD >$tf 2>"$te" & #($CMD >$tf 2>"$te" || rm -f "$tp") 2>/dev/null & bg=$! # background process id usleep $MICROS if [ ! -p "$tp" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else #echo "$da" >"$tp" # might hang forever echo "$da" >"$tp" & export pid=$!; (sleep 1; kill $pid 2>/dev/null) & # Solaris needs more time: sleep 1 kill "$bg" 2>/dev/null; wait if ! echo "$da" |diff - "$tf" >"$tdiff"; then if [ -s "$te" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" else $PRINTF "$FAILED: diff:\n" cat "$tdiff" fi numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi wait fi # NUMCOND esac N=$((N+1)) NAME=GOPENUNIXSTREAM case "$TESTS" in *%$N%*|*%functions%*|*%gopen%*|*%unix%*|*%listen%*|*%$NAME%*) TEST="$NAME: GOPEN on UNIX stream socket" if ! eval $NUMCOND; then :; else ts="$td/test$N.socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da1="test$N $(date) $RANDOM" #establish a listening unix socket in background SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\" PIPE" #make a connection CMD="$TRACE $SOCAT $opts - $ts" $PRINTF "test $F_n $TEST... " $N eval "$SRV 2>${te}s &" pids=$! waitfile "$ts" echo "$da1" |eval "$CMD" >"${tf}1" 2>"${te}1" if [ $? -ne 0 ]; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" echo "$SRV &" cat "${te}s" echo "$CMD" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" echo "$SRV &" cat "${te}s" echo "$CMD" cat "${te}1" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi # !(rc -ne 0) wait fi # NUMCOND esac N=$((N+1)) NAME=GOPENUNIXDGRAM case "$TESTS" in *%$N%*|*%functions%*|*%gopen%*|*%unix%*|*%dgram%*|*%$NAME%*) TEST="$NAME: GOPEN on UNIX datagram socket" if ! eval $NUMCOND; then :; else ts="$td/test$N.socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da1="test$N $(date) $RANDOM" #establish a receiving unix socket in background SRV="$TRACE $SOCAT $opts -u -lpserver UNIX-RECV:\"$ts\" file:\"$tf\",create" #make a connection CMD="$TRACE $SOCAT $opts -u - $ts" $PRINTF "test $F_n $TEST... " $N eval "$SRV 2>${te}s &" pids=$! waitfile "$ts" echo "$da1" |eval "$CMD" 2>"${te}1" waitfile -s "$tf" if [ $? -ne 0 ]; then $PRINTF "$FAILED:\n" echo "$SRV &" cat "${te}s" echo "$CMD" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da1" |diff - "${tf}" >"$tdiff"; then $PRINTF "$FAILED:\n" echo "$SRV &" cat "${te}s" echo "$CMD" cat "${te}1" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi # !(rc -ne 0) kill "$pids" 2>/dev/null; wait fi ;; # NUMCOND esac N=$((N+1)) NAME=IGNOREEOF case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof on file" if ! eval $NUMCOND; then :; else ti="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD="$TRACE $SOCAT $opts -u file:\"$ti\",ignoreeof -" printf "test $F_n $TEST... " $N touch "$ti" $CMD >"$tf" 2>"$te" & bg=$! usleep 500000 echo "$da" >>"$ti" sleep 1 kill $bg 2>/dev/null; wait if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" listFAIL="$listFAIL $N" numFAIL=$((numFAIL+1)) else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) NAME=IGNOREEOF_REV case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof on file right-to-left" if ! eval $NUMCOND; then :; else ti="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD="$SOCAT $opts -U - file:\"$ti\",ignoreeof" printf "test $F_n $TEST... " $N touch "$ti" $CMD >"$tf" 2>"$te" & bg=$! usleep 500000 echo "$da" >>"$ti" sleep 1 kill $bg 2>/dev/null if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" listFAIL="$listFAIL $N" numFAIL=$((numFAIL+1)) else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi wait fi ;; # NUMCOND esac N=$((N+1)) NAME=EXECIGNOREEOF case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: exec against address with ignoreeof" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" CMD="$TRACE $SOCAT $opts -lf /dev/null EXEC:$TRUE /dev/null,ignoreeof" printf "test $F_n $TEST... " $N $CMD >"$tf" 2>"$te" if [ -s "$te" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) NAME=FAKEPTY case "$TESTS" in *%$N%*|*%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: generation of pty for other processes" if ! eval $NUMCOND; then :; elif ! testaddrs pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tt="$td/pty$N" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts pty,link=$tt pipe" CMD2="$TRACE $SOCAT $opts - $tt,$PTYOPTS2" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & pid=$! # background process id waitfile "$tt" # this hangs on HP-UX, so we use a timeout (echo "$da"; sleep 1) |$CMD2 >$tf 2>"${te}2" & rc2=$! #sleep 5 && kill $rc2 2>/dev/null & wait $rc2 if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" sleep 1 echo "$CMD2" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null; wait fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=O_TRUNC case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: option o-trunc" if ! eval $NUMCOND; then :; else ff="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD="$TRACE $SOCAT -u $opts - open:$ff,append,o-trunc" printf "test $F_n $TEST... " $N rm -f $ff; $ECHO "prefix-\c" >$ff echo "$da" |$CMD >$tf 2>"$te" rc0=$? if ! [ $rc0 = 0 ] || ! echo "$da" |diff - $ff >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) NAME=FTRUNCATE case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: option ftruncate" if ! eval $NUMCOND; then :; else ff="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD="$TRACE $SOCAT -u $opts - open:$ff,append,ftruncate=0" printf "test $F_n $TEST... " $N rm -f $ff; $ECHO "prefix-\c" >$ff if ! echo "$da" |$CMD >$tf 2>"$te" || ! echo "$da" |diff - $ff >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) NAME=RIGHTTOLEFT case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: unidirectional throughput from stdin to stdout, right to left" testecho "$N" "$TEST" "stdout" "stdin" "$opts -U" esac N=$((N+1)) NAME=CHILDDEFAULT case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) if ! eval $NUMCOND; then :; else TEST="$NAME: child process default properties" tf="$td/test$N.stdout" te="$td/test$N.stderr" CMD="$TRACE $SOCAT $opts -u exec:$PROCAN -" printf "test $F_n $TEST... " $N $CMD >$tf 2>$te MYPID=`expr "\`grep "process id =" $tf\`" : '[^0-9]*\([0-9]*\).*'` MYPPID=`expr "\`grep "process parent id =" $tf\`" : '[^0-9]*\([0-9]*\).*'` MYPGID=`expr "\`grep "process group id =" $tf\`" : '[^0-9]*\([0-9]*\).*'` MYSID=`expr "\`grep "process session id =" $tf\`" : '[^0-9]*\([0-9]*\).*'` #echo "PID=$MYPID, PPID=$MYPPID, PGID=$MYPGID, SID=$MYSID" if [ "$MYPID" = "$MYPPID" -o "$MYPID" = "$MYPGID" -o "$MYPID" = "$MYSID" -o \ "$MYPPID" = "$MYPGID" -o "$MYPPID" = "$MYSID" -o "$MYPGID" = "$MYSID" ]; then $PRINTF "$FAILED:\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) NAME=CHILDSETSID case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: child process with setsid" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" CMD="$TRACE $SOCAT $opts -u exec:$PROCAN,setsid -" printf "test $F_n $TEST... " $N $CMD >$tf 2>$te MYPID=`grep "process id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` MYPPID=`grep "process parent id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` MYPGID=`grep "process group id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` MYSID=`grep "process session id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` #$ECHO "\nPID=$MYPID, PPID=$MYPPID, PGID=$MYPGID, SID=$MYSID" # PID, PGID, and SID must be the same if [ "$MYPID" = "$MYPPID" -o \ "$MYPID" != "$MYPGID" -o "$MYPID" != "$MYSID" ]; then $PRINTF "$FAILED\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) NAME=MAINSETSID case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: main process with setsid" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" CMD="$TRACE $SOCAT $opts -U -,setsid exec:$PROCAN" printf "test $F_n $TEST... " $N $CMD >$tf 2>$te MYPID=`grep "process id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` MYPPID=`grep "process parent id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` MYPGID=`grep "process group id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` MYSID=`grep "process session id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` #$ECHO "\nPID=$MYPID, PPID=$MYPPID, PGID=$MYPGID, SID=$MYSID" # PPID, PGID, and SID must be the same if [ "$MYPID" = "$MYPPID" -o \ "$MYPPID" != "$MYPGID" -o "$MYPPID" != "$MYSID" ]; then $PRINTF "$FAILED\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) NAME=OPENSSL_TCP4 case "$TESTS" in *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: openssl connect" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD2="$TRACE $SOCAT $opts exec:'openssl s_server -accept "$PORT" -quiet -cert testsrv.pem' pipe" #! CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT" CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id # this might timeout when openssl opens tcp46 port like " :::$PORT" waittcp4port $PORT echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null; wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSLLISTEN_TCP4 case "$TESTS" in *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: openssl listen" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe" CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id waittcp4port $PORT echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSLLISTEN_TCP6 case "$TESTS" in *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%$NAME%*) TEST="$NAME: openssl listen" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip6,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe" CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST6:$PORT,verify=0,$SOCAT_EGD" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id waittcp6port $PORT echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) while read NAMEKEYW FEAT RUNS TESTTMPL PEERTMPL WAITTMPL; do if [ -z "$NAMEKEYW" ] || [[ "$NAMEKEYW" == \#* ]]; then continue; fi export ts="$td/test$N.socket" WAITTMPL="$(echo "$WAITTMPL" |sed -e 's/\040/ /g')" TESTADDR=$(eval echo $TESTTMPL) PEERADDR=$(eval echo $PEERTMPL) WAITCMD=$(eval echo $WAITTMPL) TESTKEYW=${TESTADDR%%:*} # does our address implementation support halfclose? NAME=${NAMEKEYW}_HALFCLOSE case "$TESTS" in *%$N%*|*%functions%*|*%$FEAT%*|*%socket%*|*%halfclose%*|*%$NAME%*) TEST="$NAME: $TESTKEYW half close" # have a "peer" socat "peer" that executes "$OD_C" and see if EOF on the # connecting socat brings the result of od if ! eval $NUMCOND; then :; elif [ "$FEAT" != ',' ] && ! testaddrs "$FEAT" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! runs$RUNS; then $PRINTF "test $F_n $TEST... ${YELLOW}$RUNS not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD2="$TRACE $SOCAT $opts \"$PEERADDR\" EXEC:'$OD_C'" CMD="$TRACE $SOCAT -T1 $opts - $TESTADDR" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id $WAITCMD echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |$OD_C |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) done <<<" UNIXCONNECT , unix UNIX-CONNECT:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts UNIXCLIENT , unix UNIX-CLIENT:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts GOPEN_UNIXSTREAM , unix GOPEN:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts UNIXLISTEN , unix UNIX-LISTEN:\$ts UNIX-CONNECT:\$ts,retry=3 sleep\040\1 TCP4CONNECT , tcp4 TCP4-CONNECT:\$LOCALHOST:\$PORT TCP4-LISTEN:\$PORT waittcp4port\040\$PORT TCP4LISTEN , tcp4 TCP4-LISTEN:\$PORT TCP4-CONNECT:\$LOCALHOST:\$PORT,retry=3 TCP6CONNECT , tcp6 TCP6-CONNECT:\$LOCALHOST6:\$PORT TCP6-LISTEN:\$PORT waittcp6port\040\$PORT TCP6LISTEN , tcp6 TCP6-LISTEN:\$PORT TCP6-CONNECT:\$LOCALHOST6:\$PORT,retry=3 OPENSSL4CLIENT OPENSSL tcp4 OPENSSL:\$LOCALHOST:\$PORT,verify=0 OPENSSL-LISTEN:\$PORT,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 waittcp4port\040\$PORT OPENSSL4SERVER OPENSSL tcp4 OPENSSL-LISTEN:\$PORT,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 OPENSSL:\$LOCALHOST:\$PORT,verify=0,retry=3 OPENSSL6CLIENT OPENSSL tcp6 OPENSSL:\$LOCALHOST6:\$PORT,pf=ip6,verify=0 OPENSSL-LISTEN:\$PORT,pf=ip6,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 waittcp6port\040\$PORT OPENSSL6SERVER OPENSSL tcp6 OPENSSL-LISTEN:\$PORT,pf=ip6,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 OPENSSL:\$LOCALHOST6:\$PORT,pf=ip6,verify=0,retry=3 " NAME=OPENSSL_SERVERAUTH case "$TESTS" in *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: openssl server authentication" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv gentestcert testcli tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe" CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,verify=1,cafile=testsrv.crt,$SOCAT_EGD" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id waittcp4port $PORT echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSL_CLIENTAUTH case "$TESTS" in *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: openssl client authentication" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv gentestcert testcli tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,verify=1,cert=testsrv.crt,key=testsrv.key,cafile=testcli.crt,$SOCAT_EGD pipe" CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,verify=0,cert=testcli.crt,key=testcli.key,$SOCAT_EGD" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id waittcp4port $PORT echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSL_FIPS_BOTHAUTH case "$TESTS" in *%$N%*|*%functions%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: OpenSSL+FIPS client and server authentication" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testoptions fips >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL/FIPS not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else OPENSSL_FIPS=1 gentestcert testsrvfips OPENSSL_FIPS=1 gentestcert testclifips tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,fips,$SOCAT_EGD,cert=testsrvfips.crt,key=testsrvfips.key,cafile=testclifips.crt pipe" CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,fips,verify=1,cert=testclifips.crt,key=testclifips.key,cafile=testsrvfips.crt,$SOCAT_EGD" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id waittcp4port $PORT echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSL_COMPRESS case "$TESTS" in *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: OpenSSL compression" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testoptions openssl-compress >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL compression option not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv printf "test $F_n $TEST... " $N tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" success=yes for srccompr in '' compress=auto compress=none; do for dstcompr in '' compress=auto compress=none; do CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0,$dstcompr pipe" CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD,$srccompr" eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id waittcp4port $PORT echo "$da" | $CMD >$tf 2>"${te}2" kill $pid 2>/dev/null if ! echo "$da" |diff - "$tf" >"$tdiff"; then success= break fi done done if test -z "$success"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=SOCKS4CONNECT_TCP4 case "$TESTS" in *%$N%*|*%functions%*|*%socks%*|*%socks4%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: socks4 connect over TCP/IPv4" if ! eval $NUMCOND; then :; elif ! testaddrs socks4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" # we have a normal tcp echo listening - so the socks header must appear in answer CMD2="$TRACE $SOCAT $opts tcp4-l:$PORT,reuseaddr exec:\"./socks4echo.sh\"" CMD="$TRACE $SOCAT $opts - socks4:$LOCALHOST:32.98.76.54:32109,pf=ip4,socksport=$PORT",socksuser="nobody" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id waittcp4port $PORT 1 echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=SOCKS4CONNECT_TCP6 case "$TESTS" in *%$N%*|*%functions%*|*%socks%*|*%socks4%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%$NAME%*) TEST="$NAME: socks4 connect over TCP/IPv6" if ! eval $NUMCOND; then :; elif ! testaddrs socks4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" # we have a normal tcp echo listening - so the socks header must appear in answer CMD2="$TRACE $SOCAT $opts tcp6-l:$PORT,reuseaddr exec:\"./socks4echo.sh\"" CMD="$TRACE $SOCAT $opts - socks4:$LOCALHOST6:32.98.76.54:32109,socksport=$PORT",socksuser="nobody" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id waittcp6port $PORT 1 echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=SOCKS4ACONNECT_TCP4 case "$TESTS" in *%$N%*|*%functions%*|*%socks%*|*%socks4a%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: socks4a connect over TCP/IPv4" if ! eval $NUMCOND; then :; elif ! testaddrs socks4a >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" # we have a normal tcp echo listening - so the socks header must appear in answer CMD2="$TRACE $SOCAT $opts tcp4-l:$PORT,reuseaddr exec:\"./socks4a-echo.sh\"" CMD="$TRACE $SOCAT $opts - socks4a:$LOCALHOST:localhost:32109,pf=ip4,socksport=$PORT",socksuser="nobody" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id waittcp4port $PORT 1 echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=SOCKS4ACONNECT_TCP6 case "$TESTS" in *%$N%*|*%functions%*|*%socks%*|*%socks4a%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%$NAME%*) TEST="$NAME: socks4a connect over TCP/IPv6" if ! eval $NUMCOND; then :; elif ! testaddrs socks4a >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" # we have a normal tcp echo listening - so the socks header must appear in answer CMD2="$TRACE $SOCAT $opts tcp6-l:$PORT,reuseaddr exec:\"./socks4a-echo.sh\"" CMD="$TRACE $SOCAT $opts - socks4a:$LOCALHOST6:localhost:32109,socksport=$PORT",socksuser="nobody" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id waittcp6port $PORT 1 echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=PROXYCONNECT_TCP4 case "$TESTS" in *%$N%*|*%functions%*|*%proxyconnect%*|*%proxy%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: proxy connect over TCP/IPv4" if ! eval $NUMCOND; then :; elif ! testaddrs proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ts="$td/test$N.sh" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" #CMD2="$TRACE $SOCAT tcp4-l:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" CMD2="$TRACE $SOCAT $opts tcp4-l:$PORT,reuseaddr,crlf exec:\"/bin/bash proxyecho.sh\"" CMD="$TRACE $SOCAT $opts - proxy:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}2\" &" pid=$! # background process id waittcp4port $PORT 1 echo "$da" |$CMD >"$tf" 2>"${te}1" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=PROXYCONNECT_TCP6 case "$TESTS" in *%$N%*|*%functions%*|*%proxyconnect%*|*%proxy%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%$NAME%*) TEST="$NAME: proxy connect over TCP/IPv6" if ! eval $NUMCOND; then :; elif ! testaddrs proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ts="$td/test$N.sh" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" #CMD2="$TRACE $SOCAT $opts tcp6-l:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" CMD2="$TRACE $SOCAT $opts tcp6-l:$PORT,reuseaddr,crlf exec:\"/bin/bash proxyecho.sh\"" CMD="$TRACE $SOCAT $opts - proxy:$LOCALHOST6:127.0.0.1:1000,proxyport=$PORT" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}2\" &" pid=$! # background process id waittcp6port $PORT 1 echo "$da" |$CMD >"$tf" 2>"${te}1" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=TCP4NOFORK case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: echo via connection to TCP V4 socket with nofork'ed exec" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr exec:$CAT,nofork" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N #$CMD1 >"$tf" 2>"${te}1" & $CMD1 >/dev/null 2>"${te}1" & waittcp4port $tsl #usleep $MICROS echo "$da" |$CMD2 >"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=EXECCATNOFORK case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with nofork" testecho "$N" "$TEST" "" "exec:$CAT,nofork" "$opts" esac N=$((N+1)) NAME=SYSTEMCATNOFORK case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with nofork" testecho "$N" "$TEST" "" "system:$CAT,nofork" "$opts" esac N=$((N+1)) NAME=NOFORKSETSID case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: simple echo via exec() of cat with nofork and setsid" testecho "$N" "$TEST" "" "system:$CAT,nofork,setsid" "$opts" esac N=$((N+1)) #============================================================================== #TEST="$NAME: echo via 'connection' to UDP V4 socket" #if ! eval $NUMCOND; then :; else #tf="$td/file$N" #tsl=65534 #ts="127.0.0.1:$tsl" #da="test$N $(date) $RANDOM" #$TRACE $SOCAT UDP-listen:$tsl PIPE & #sleep 2 #echo "$da" |$TRACE $SOCAT stdin!!stdout UDP:$ts >"$tf" #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then # $ECHO "... test $N succeeded" # numOK=$((numOK+1)) #else # $ECHO "*** test $N $FAILED" # numFAIL=$((numFAIL+1)) # listFAIL="$listFAIL $N" #fi #fi ;; # NUMCOND #N=$((N+1)) #============================================================================== # TEST 4 - simple echo via new file #if ! eval $NUMCOND; then :; else #N=4 #tf="$td/file$N" #tp="$td/pipe$N" #da="test$N $(date) $RANDOM" #rm -f "$tf.tmp" #echo "$da" |$TRACE $SOCAT - FILE:$tf.tmp,ignoreeof >"$tf" #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then # $ECHO "... test $N succeeded" # numOK=$((numOK+1)) #else # $ECHO "*** test $N $FAILED" # numFAIL=$((numFAIL+1)) # listFAIL="$listFAIL $N" #fi #fi ;; # NUMCOND #============================================================================== NAME=TOTALTIMEOUT case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%$NAME%*) TEST="$NAME: socat inactivity timeout" if ! eval $NUMCOND; then :; else #set -vx tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" CMD2="$TRACE $SOCAT $opts -T 1 tcp4-listen:$PORT,reuseaddr pipe" CMD="$TRACE $SOCAT $opts - tcp4-connect:$LOCALHOST:$PORT" printf "test $F_n $TEST... " $N eval "$CMD2 2>${te}1 &" pid=$! # background process id waittcp4port $PORT 1 (echo "$da"; sleep 2; echo X) |$CMD >"$tf" 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait #set +vx fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=IGNOREEOF+TOTALTIMEOUT case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof and inactivity timeout" if ! eval $NUMCOND; then :; else #set -vx ti="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD="$TRACE $SOCAT $opts -T 2 -u file:\"$ti\",ignoreeof -" printf "test $F_n $TEST... " $N touch "$ti" $CMD >"$tf" 2>"$te" & bg=$! # background process id psleep 0.5 echo "$da" >>"$ti" sleep 4 echo X >>"$ti" sleep 1 kill $bg 2>/dev/null if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD &" cat "$te" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi numOK=$((numOK+1)) fi wait fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=PROXY2SPACES case "$TESTS" in *%$N%*|*%functions%*|*%proxy%*|*%$NAME%*) TEST="$NAME: proxy connect accepts status with multiple spaces" if ! eval $NUMCOND; then :; elif ! testaddrs proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ts="$td/test$N.sh" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" #CMD2="$TRACE $SOCAT $opts tcp-l:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" CMD2="$TRACE $SOCAT $opts tcp4-l:$PORT,reuseaddr,crlf exec:\"/bin/bash proxyecho.sh -w 2\"" CMD="$TRACE $SOCAT $opts - proxy:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id waittcp4port $PORT 1 echo "$da" |$CMD >"$tf" 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=BUG-UNISTDIO case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: for bug with address options on both stdin/out in unidirectional mode" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" ff="$td/file$N" printf "test $F_n $TEST... " $N >"$ff" #$TRACE $SOCAT $opts -u /dev/null -,setlk <"$ff" 2>"$te" CMD="$TRACE $SOCAT $opts -u /dev/null -,setlk" $CMD <"$ff" 2>"$te" if [ "$?" -eq 0 ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else if [ "$UNAME" = "Linux" ]; then $PRINTF "$FAILED\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "${YELLOW}failed (don't care)${NORMAL}\n" numCANT=$((numCANT+1)) fi fi fi ;; # NUMCOND esac N=$((N+1)) NAME=SINGLEEXECOUTSOCKETPAIR case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: inheritance of stdout to single exec with socketpair" testecho "$N" "$TEST" "-!!exec:cat" "" "$opts" 1 esac N=$((N+1)) NAME=SINGLEEXECOUTPIPE case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: inheritance of stdout to single exec with pipe" testecho "$N" "$TEST" "-!!exec:cat,pipes" "" "$opts" 1 esac N=$((N+1)) NAME=SINGLEEXECOUTPTY case "$TESTS" in *%$N%*|*%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: inheritance of stdout to single exec with pty" if ! eval $NUMCOND; then :; elif ! testaddrs pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "-!!exec:cat,pty,raw" "" "$opts" 1 fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=SINGLEEXECINSOCKETPAIR case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: inheritance of stdin to single exec with socketpair" testecho "$N" "$TEST" "exec:cat!!-" "" "$opts" esac N=$((N+1)) NAME=SINGLEEXECINPIPE case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: inheritance of stdin to single exec with pipe" testecho "$N" "$TEST" "exec:cat,pipes!!-" "" "$opts" esac N=$((N+1)) NAME=SINGLEEXECINPTYDELAY case "$TESTS" in *%$N%*|*%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: inheritance of stdin to single exec with pty, with delay" if ! eval $NUMCOND; then :; elif ! testaddrs pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" $MISCDELAY fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=SINGLEEXECINPTY case "$TESTS" in *%$N%*|*%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: inheritance of stdin to single exec with pty" if ! eval $NUMCOND; then :; elif ! testaddrs pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=READLINE #set -vx case "$TESTS" in *%$N%*|*%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: readline with password and sigint" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs readline pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else SAVETERM="$TERM"; TERM= # 'cause konsole might print controls even in raw SAVEMICS=$MICROS #MICROS=2000000 ts="$td/test$N.sh" to="$td/test$N.stdout" tpi="$td/test$N.inpipe" tpo="$td/test$N.outpipe" te="$td/test$N.stderr" tr="$td/test$N.ref" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" # the feature that we really want to test is in the readline.sh script: CMD="$TRACE $SOCAT $opts -t1 open:$tpi,nonblock!!open:$tpo exec:\"./readline.sh -nh ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig" #echo "$CMD" >"$ts" #chmod a+x "$ts" printf "test $F_n $TEST... " $N rm -f "$tpi" "$tpo" mkfifo "$tpi" touch "$tpo" # # during development of this test, the following command line succeeded: # (sleep 1; $ECHO "user\n\c"; sleep 1; $ECHO "password\c"; sleep 1; $ECHO "\n\c"; sleep 1; $ECHO "test 1\n\c"; sleep 1; $ECHO "\003\c"; sleep 1; $ECHO "test 2\n\c"; sleep 1; $ECHO "exit\n\c"; sleep 1) |$TRACE $SOCAT -d -d -d -d -lf/tmp/gerhard/debug1 -v -x - exec:'./readline.sh ./readline-test.sh',pty,ctty,setsid,raw,echo=0,isig # PATH=${SOCAT%socat}:$PATH eval "$CMD 2>$te &" pid=$! # background process id usleep $MICROS ( usleep $((3*MICROS)) $ECHO "user\n\c" usleep $MICROS $ECHO "password\c" usleep $MICROS $ECHO "\n\c" usleep $MICROS $ECHO "test 1\n\c" usleep $MICROS $ECHO "\003\c" usleep $MICROS $ECHO "test 2\n\c" usleep $MICROS $ECHO "exit\n\c" usleep $MICROS ) >"$tpi" cat >$tr < test 1 executing test 1 prog> ./readline-test.sh got SIGINT test 2 executing test 2 prog> exit EOF #0 if ! sed 's/.*\r//g' "$tpo" |diff -q "$tr" - >/dev/null 2>&1; then #0 if ! sed 's/.*'"$($ECHO '\r\c')"'//dev/null 2>&1; then wait if ! tr "$($ECHO '\r \c')" "% " <$tpo |sed 's/%$//g' |sed 's/.*%//g' |diff "$tr" - >"$tdiff" 2>&1; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null # necc on OpenBSD wait MICROS=$SAVEMICS TERM="$SAVETERM" fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=GENDERCHANGER case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: TCP4 \"gender changer\"" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" # this is the server in the protected network that we want to reach CMD1="$TRACE $SOCAT -lpserver $opts tcp4-l:$PORT,reuseaddr,bind=$LOCALHOST echo" # this is the double client in the protected network CMD2="$TRACE $SOCAT -lp2client $opts tcp4:$LOCALHOST:$((PORT+1)),retry=10,interval=1 tcp4:$LOCALHOST:$PORT" # this is the double server in the outside network CMD3="$TRACE $SOCAT -lp2server $opts tcp4-l:$((PORT+2)),reuseaddr,bind=$LOCALHOST tcp4-l:$((PORT+1)),reuseaddr,bind=$LOCALHOST" # this is the outside client that wants to use the protected server CMD4="$TRACE $SOCAT -lpclient $opts -t1 - tcp4:$LOCALHOST:$((PORT+2))" printf "test $F_n $TEST... " $N eval "$CMD1 2>${te}1 &" pid1=$! eval "$CMD2 2>${te}2 &" pid2=$! eval "$CMD3 2>${te}3 &" pid3=$! waittcp4port $PORT 1 && waittcp4port $((PORT+2)) 1 sleep 1 echo "$da" |$CMD4 >$tf 2>"${te}4" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2 &" echo "$CMD3 &" echo "$CMD4" cat "${te}1" "${te}2" "${te}3" "${te}4" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4"; fi numOK=$((numOK+1)) fi kill $pid1 $pid2 $pid3 $pid4 2>/dev/null wait fi ;; # NUMCOND esac PORT=$((PORT+3)) N=$((N+1)) #! #PORT=10000 #! NAME=OUTBOUNDIN case "$TESTS" in *%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%$NAME%*) TEST="$NAME: gender changer via SSL through HTTP proxy, oneshot" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs openssl proxy); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv gentestcert testcli tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" # this is the server in the protected network that we want to reach CMD1="$TRACE $SOCAT $opts -lpserver tcp4-l:$PORT,reuseaddr,bind=$LOCALHOST echo" # this is the proxy in the protected network that provides a way out CMD2="$TRACE $SOCAT $opts -lpproxy tcp4-l:$((PORT+1)),reuseaddr,bind=$LOCALHOST,fork exec:./proxy.sh" # this is our proxy connect wrapper in the protected network CMD3="$TRACE $SOCAT $opts -lpwrapper tcp4-l:$((PORT+2)),reuseaddr,bind=$LOCALHOST,fork proxy:$LOCALHOST:$LOCALHOST:$((PORT+3)),pf=ip4,proxyport=$((PORT+1)),resolve" # this is our double client in the protected network using SSL #CMD4="$TRACE $SOCAT $opts -lp2client ssl:$LOCALHOST:$((PORT+2)),pf=ip4,retry=10,interval=1,cert=testcli.pem,cafile=testsrv.crt,$SOCAT_EGD tcp4:$LOCALHOST:$PORT" CMD4="$TRACE $SOCAT $opts -lp2client ssl:$LOCALHOST:$((PORT+2)),pf=ip4,cert=testcli.pem,cafile=testsrv.crt,$SOCAT_EGD tcp4:$LOCALHOST:$PORT" # this is the double server in the outside network CMD5="$TRACE $SOCAT $opts -lp2server -t1 tcp4-l:$((PORT+4)),reuseaddr,bind=$LOCALHOST ssl-l:$((PORT+3)),pf=ip4,reuseaddr,bind=$LOCALHOST,$SOCAT_EGD,cert=testsrv.pem,cafile=testcli.crt" # this is the outside client that wants to use the protected server CMD6="$TRACE $SOCAT $opts -lpclient -t5 - tcp4:$LOCALHOST:$((PORT+4))" printf "test $F_n $TEST... " $N eval "$CMD1 2>${te}1 &" pid1=$! eval "$CMD2 2>${te}2 &" pid2=$! eval "$CMD3 2>${te}3 &" pid3=$! waittcp4port $PORT 1 || $PRINTF "$FAILED: port $PORT\n" >&2 &2 &2 ${te}5 &" pid5=$! waittcp4port $((PORT+4)) 1 || $PRINTF "$FAILED: port $((PORT+4))\n" >&2 $tf 2>"${te}6" & pid6=$! waittcp4port $((PORT+3)) 1 || $PRINTF "$FAILED: port $((PORT+3))\n" >&2 ${te}4 &" pid4=$! wait $pid6 if ! (echo "$da"; sleep 2) |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" cat "${te}1" echo "$CMD2 &" cat "${te}2" echo "$CMD3 &" cat "${te}3" echo "$CMD5 &" cat "${te}5" echo "$CMD6" cat "${te}6" echo "$CMD4 &" cat "${te}4" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" "${te}6"; fi numOK=$((numOK+1)) fi kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+5)) N=$((N+1)) # test the TCP gender changer with almost production requirements: a double # client repeatedly tries to connect to a double server via SSL through an HTTP # proxy. the double servers SSL port becomes active for one connection only # after a (real) client has connected to its TCP port. when the double client # succeeded to establish an SSL connection, it connects with its second client # side to the specified (protected) server. all three consecutive connections # must function for full success of this test. PORT=$((RANDOM+16184)) #! NAME=INTRANETRIPPER case "$TESTS" in *%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%$NAME%*) TEST="$NAME: gender changer via SSL through HTTP proxy, daemons" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs openssl proxy); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv gentestcert testcli tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da1="test$N.1 $(date) $RANDOM" da2="test$N.2 $(date) $RANDOM" da3="test$N.3 $(date) $RANDOM" # this is the server in the protected network that we want to reach CMD1="$TRACE $SOCAT $opts -lpserver -t1 tcp4-l:$PORT,reuseaddr,bind=$LOCALHOST,fork echo" # this is the proxy in the protected network that provides a way out # note: the proxy.sh script starts one or two more socat processes without # setting the program name CMD2="$TRACE $SOCAT $opts -lpproxy -t1 tcp4-l:$((PORT+1)),reuseaddr,bind=$LOCALHOST,fork exec:./proxy.sh" # this is our proxy connect wrapper in the protected network CMD3="$TRACE $SOCAT $opts -lpwrapper -t3 tcp4-l:$((PORT+2)),reuseaddr,bind=$LOCALHOST,fork proxy:$LOCALHOST:$LOCALHOST:$((PORT+3)),pf=ip4,proxyport=$((PORT+1)),resolve" # this is our double client in the protected network using SSL CMD4="$TRACE $SOCAT $opts -lp2client -t3 ssl:$LOCALHOST:$((PORT+2)),retry=10,interval=1,cert=testcli.pem,cafile=testsrv.crt,verify,fork,$SOCAT_EGD tcp4:$LOCALHOST:$PORT,forever,interval=0.1" # this is the double server in the outside network CMD5="$TRACE $SOCAT $opts -lp2server -t4 tcp4-l:$((PORT+4)),reuseaddr,bind=$LOCALHOST,backlog=3,fork ssl-l:$((PORT+3)),pf=ip4,reuseaddr,bind=$LOCALHOST,$SOCAT_EGD,cert=testsrv.pem,cafile=testcli.crt,retry=20,interval=0.5" # this is the outside client that wants to use the protected server CMD6="$TRACE $SOCAT $opts -lpclient -t6 - tcp4:$LOCALHOST:$((PORT+4)),retry=3" printf "test $F_n $TEST... " $N # start the intranet infrastructure eval "$CMD1 2>\"${te}1\" &" pid1=$! eval "$CMD2 2>\"${te}2\" &" pid2=$! waittcp4port $PORT 1 || $PRINTF "$FAILED: port $PORT\n" >&2 &2 \"${te}3\" &" pid3=$! eval "$CMD4 2>\"${te}4\" &" pid4=$! waittcp4port $((PORT+2)) 1 || $PRINTF "$FAILED: port $((PORT+2))\n" >&2 \"${te}5\" &" pid5=$! waittcp4port $((PORT+4)) 1 || $PRINTF "$FAILED: port $((PORT+4))\n" >&2 ${tf}_1 2>"${te}6_1" & pid6_1=$! echo "$da2" |$CMD6 >${tf}_2 2>"${te}6_2" & pid6_2=$! echo "$da3" |$CMD6 >${tf}_3 2>"${te}6_3" & pid6_3=$! wait $pid6_1 $pid6_2 $pid6_3 # (echo "$da1"; sleep 2) |diff - "${tf}_1" >"${tdiff}1" (echo "$da2"; sleep 2) |diff - "${tf}_2" >"${tdiff}2" (echo "$da3"; sleep 2) |diff - "${tf}_3" >"${tdiff}3" if test -s "${tdiff}1" -o -s "${tdiff}2" -o -s "${tdiff}3"; then # FAILED only when none of the three transfers succeeded if test -s "${tdiff}1" -a -s "${tdiff}2" -a -s "${tdiff}3"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" cat "${te}1" echo "$CMD2 &" cat "${te}2" echo "$CMD3 &" cat "${te}3" echo "$CMD4 &" cat "${te}4" echo "$CMD5 &" cat "${te}5" echo "$CMD6 &" cat "${te}6_1" cat "${tdiff}1" echo "$CMD6 &" cat "${te}6_2" cat "${tdiff}2" echo "$CMD6 &" cat "${te}6_3" cat "${tdiff}3" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK ${YELLOW}(partial failure)${NORMAL}\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi numOK=$((numOK+1)) fi else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi numOK=$((numOK+1)) fi kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+5)) N=$((N+1)) # let us test the security features with -s, retry, and fork # method: first test without security feature if it works # then try with security feature, must fail # test the security features of a server address testserversec () { local N="$1" local title="$2" local opts="$3" local arg1="$4" # the server address local secopt0="$5" # option without security for server, mostly empty local secopt1="$6" # the security option for server, to be tested local arg2="$7" # the client address local ipvers="$8" # IP version, for check of listen port local proto="$9" # protocol, for check of listen port local port="${10}" # start client when this port is listening local expect="${11}" # expected behaviour of client: 0..empty output; -1..error local T="${12}"; [ -z "$T" ] && T=0 local tf="$td/test$N.stdout" local te="$td/test$N.stderr" local tdiff1="$td/test$N.diff1" local tdiff2="$td/test$N.diff2" local da="test$N.1 $(date) $RANDOM" local stat result $PRINTF "test $F_n %s... " $N "$title" # first: without security # start server $TRACE $SOCAT $opts "$arg1,$secopt0" echo 2>"${te}1" & spid=$! if [ "$port" ] && ! wait${proto}${ipvers}port $port 1; then kill $spid 2>/dev/null $PRINTF "$NO_RESULT (ph.1 server not working):\n" echo "$TRACE $SOCAT $opts \"$arg1,$secopt0\" echo &" cat "${te}1" numCANT=$((numCANT+1)) wait; return fi # now use client (echo "$da"; sleep $T) |$TRACE $SOCAT $opts - "$arg2" >"$tf" 2>"${te}2" stat="$?" kill $spid 2>/dev/null #killall $TRACE $SOCAT 2>/dev/null if [ "$stat" != 0 ]; then $PRINTF "$NO_RESULT (ph.1 function fails): $TRACE $SOCAT:\n" echo "$TRACE $SOCAT $opts \"$arg1,$secopt0\" echo &" cat "${te}1" echo "$TRACE $SOCAT $opts - \"$arg2\"" cat "${te}2" numCANT=$((numCANT+1)) wait; return elif echo "$da" |diff - "$tf" >"$tdiff1" 2>&1; then : # function without security is ok, go on else $PRINTF "$NO_RESULT (ph.1 function fails): diff:\n" echo "$TRACE $SOCAT $opts $arg1,$secopt0 echo &" cat "${te}1" echo "$TRACE $SOCAT $opts - $arg2" cat "${te}2" cat "$tdiff1" numCANT=$((numCANT+1)) wait; return fi # then: with security if [ "$port" ] && ! wait${proto}${ipvers}port $port 0; then $PRINTF "$NO_RESULT (ph.1 port remains in use)\n" numCANT=$((numCANT+1)) wait; return fi wait #set -vx # assemble address w/ security option; on dual, take read part: case "$arg1" in *!!*) arg="${arg1%!!*},$secopt1!!${arg1#*!!}" ;; *) arg="$arg1,$secopt1" ;; esac # start server CMD3="$TRACE $SOCAT $opts $arg echo" $CMD3 2>"${te}3" & spid=$! if [ "$port" ] && ! wait${proto}${ipvers}port $port 1; then kill $spid 2>/dev/null $PRINTF "$NO_RESULT (ph.2 server not working)\n" wait echo "$CMD3" cat "${te}3" numCANT=$((numCANT+1)) return fi # now use client da="test$N.2 $(date) $RANDOM" (echo "$da"; sleep $T) |$TRACE $SOCAT $opts - "$arg2" >"$tf" 2>"${te}4" stat=$? kill $spid 2>/dev/null #set +vx #killall $TRACE $SOCAT 2>/dev/null if [ "$stat" != 0 ]; then result=-1; # socat had error elif [ ! -s "$tf" ]; then result=0; # empty output elif echo "$da" |diff - "$tf" >"$tdiff2" 2>&1; then result=1; # output is copy of input else result=2; # output differs from input fi if [ X$result != X$expect ]; then case X$result in X-1) $PRINTF "$NO_RESULT (ph.2 client error): $TRACE $SOCAT:\n" echo "$TRACE $SOCAT $opts $arg echo" cat "${te}3" echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" numCANT=$((numCANT+1)) ;; X0) $PRINTF "$NO_RESULT (ph.2 diff failed): diff:\n" echo "$TRACE $SOCAT $opts $arg echo" cat "${te}3" echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" cat "$tdiff2" numCANT=$((numCANT+1)) ;; X1) $PRINTF "$FAILED: SECURITY BROKEN\n" echo "$TRACE $SOCAT $opts $arg echo" cat "${te}3" echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" cat "$tdiff2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" ;; X2) $PRINTF "$FAILED: diff:\n" echo "$TRACE $SOCAT $opts $arg echo" cat "${te}3" echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" cat "$tdiff2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" ;; esac else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi wait #set +vx } NAME=TCP4RANGEBITS case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then # we need access to a second addresses $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR/32" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 fi ;; # $SECONDADDR, NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=TCP4RANGEMASK case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then # we need access to a second addresses $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR:255.255.255.255" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 fi ;; # $SECONDADDR, NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) # like TCP4RANGEMASK, but the "bad" address is within the same class A network NAME=TCP4RANGEMASKHAIRY case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" if ! eval $NUMCOND; then :; else testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=127.0.0.0:255.255.0.0" "tcp4:$SECONDADDR:$PORT,bind=$SECONDADDR" 4 tcp $PORT 0 fi ;; # Linux, NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=TCP4SOURCEPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with SOURCEPORT option" if ! eval $NUMCOND; then :; else testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "sp=$PORT" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=TCP4LOWPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with LOWPORT option" if ! eval $NUMCOND; then :; else testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "lowport" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=TCP4WRAPPERS_ADDR case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: $SECONDADDR" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "hosts-allow=$ha,hosts-deny=$hd" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=TCP4WRAPPERS_NAME case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: $LOCALHOST" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "hosts-allow=$ha,hosts-deny=$hd" "tcp4:$SECONDADDR:$PORT,bind=$SECONDADDR" 4 tcp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=TCP6RANGE case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%range%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "tcp6-l:$PORT,reuseaddr,fork,retry=1" "" "range=[::2/128]" "tcp6:[::1]:$PORT" 6 tcp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=TCP6SOURCEPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "tcp6-l:$PORT,reuseaddr,fork,retry=1" "" "sp=$PORT" "tcp6:[::1]:$PORT" 6 tcp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=TCP6LOWPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "tcp6-l:$PORT,reuseaddr,fork,retry=1" "" "lowport" "tcp6:[::1]:$PORT" 6 tcp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=TCP6TCPWRAP case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp ip6 libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: [::2]" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "tcp6-l:$PORT,reuseaddr,fork,retry=1" "" "hosts-allow=$ha,hosts-deny=$hd" "tcp6:[::1]:$PORT" 6 tcp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP4RANGE case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of UDP4-L with RANGE option" if ! eval $NUMCOND; then :; else #testserversec "$N" "$TEST" "$opts -s" "udp4-l:$PORT,reuseaddr,fork" "" "range=$SECONDADDR/32" "udp4:127.0.0.1:$PORT" 4 udp $PORT 0 testserversec "$N" "$TEST" "$opts -s" "udp4-l:$PORT,reuseaddr" "" "range=$SECONDADDR/32" "udp4:127.0.0.1:$PORT" 4 udp $PORT 0 fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP4SOURCEPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of UDP4-L with SOURCEPORT option" if ! eval $NUMCOND; then :; else testserversec "$N" "$TEST" "$opts -s" "udp4-l:$PORT,reuseaddr" "" "sp=$PORT" "udp4:127.0.0.1:$PORT" 4 udp $PORT 0 fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP4LOWPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of UDP4-L with LOWPORT option" if ! eval $NUMCOND; then :; else testserversec "$N" "$TEST" "$opts -s" "udp4-l:$PORT,reuseaddr" "" "lowport" "udp4:127.0.0.1:$PORT" 4 udp $PORT 0 fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP4TCPWRAP case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of UDP4-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: $SECONDADDR" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "udp4-l:$PORT,reuseaddr,retry=1" "" "tcpwrap-etc=$td" "udp4:127.0.0.1:$PORT" 4 udp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6RANGE case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%$NAME%*) TEST="$NAME: security of UDP6-L with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else #testserversec "$N" "$TEST" "$opts -s" "udp6-l:$PORT,reuseaddr,fork" "" "range=[::2/128]" "udp6:[::1]:$PORT" 6 udp $PORT 0 testserversec "$N" "$TEST" "$opts -s" "udp6-l:$PORT,reuseaddr" "" "range=[::2/128]" "udp6:[::1]:$PORT" 6 udp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6SOURCEPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of UDP6-L with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "udp6-l:$PORT,reuseaddr" "" "sp=$PORT" "udp6:[::1]:$PORT" 6 udp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6LOWPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of UDP6-L with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "udp6-l:$PORT,reuseaddr" "" "lowport" "udp6:[::1]:$PORT" 6 udp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6TCPWRAP case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of UDP6-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp ip6 libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: [::2]" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "udp6-l:$PORT,reuseaddr" "" "lowport" "udp6:[::1]:$PORT" 6 udp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSLTCP4_RANGE case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%range%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv4 with RANGE option" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv testserversec "$N" "$TEST" "$opts -s" "SSL-L:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "range=$SECONDADDR/32" "SSL:$LOCALHOST:$PORT,cafile=testsrv.crt,$SOCAT_EGD" 4 tcp $PORT -1 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSLTCP4_SOURCEPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of SSL-L with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv testserversec "$N" "$TEST" "$opts -s" "SSL-L:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "sp=$PORT" "SSL:$LOCALHOST:$PORT,cafile=testsrv.crt,$SOCAT_EGD" 4 tcp $PORT -1 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSLTCP4_LOWPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of SSL-L with LOWPORT option" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv testserversec "$N" "$TEST" "$opts -s" "SSL-L:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "lowport" "SSL:$LOCALHOST:$PORT,cafile=testsrv.crt,$SOCAT_EGD" 4 tcp $PORT -1 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSLTCP4_TCPWRAP case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of SSL-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4 tcp libwrap openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: $SECONDADDR" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "SSL-L:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "tcpwrap-etc=$td" "SSL:$LOCALHOST:$PORT,cafile=testsrv.crt,$SOCAT_EGD" 4 tcp $PORT -1 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSLCERTSERVER case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%$NAME%*) TEST="$NAME: security of SSL-L with client certificate" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv gentestcert testcli testserversec "$N" "$TEST" "$opts -s" "SSL-L:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify,cert=testsrv.crt,key=testsrv.key" "cafile=testcli.crt" "cafile=testsrv.crt" "SSL:$LOCALHOST:$PORT,cafile=testsrv.crt,cert=testcli.pem,$SOCAT_EGD" 4 tcp $PORT -1 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSLCERTCLIENT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%$NAME%*) TEST="$NAME: security of SSL with server certificate" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv gentestcert testcli testserversec "$N" "$TEST" "$opts -s -lu -d" "ssl:$LOCALHOST:$PORT,pf=ip4,fork,retry=2,verify,cert=testcli.pem,$SOCAT_EGD" "cafile=testsrv.crt" "cafile=testcli.crt" "ssl-l:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cafile=testcli.crt,cert=testsrv.crt,key=testsrv.key" 4 tcp "" -1 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSLTCP6_RANGE case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%range%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with RANGE option" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert6 testsrv6 testserversec "$N" "$TEST" "$opts -s" "ssl-l:$PORT,pf=ip6,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv6.crt,key=testsrv6.key" "" "range=[::2/128]" "ssl:[::1]:$PORT,cafile=testsrv6.crt,$SOCAT_EGD" 6 tcp $PORT -1 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSLTCP6_SOURCEPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert6 testsrv6 testserversec "$N" "$TEST" "$opts -s" "ssl-l:$PORT,pf=ip6,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv6.crt,key=testsrv6.key" "" "sp=$PORT" "ssl:[::1]:$PORT,cafile=testsrv6.crt,$SOCAT_EGD" 6 tcp $PORT -1 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSLTCP6_LOWPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with LOWPORT option" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert6 testsrv6 testserversec "$N" "$TEST" "$opts -s" "ssl-l:$PORT,pf=ip6,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv6.crt,key=testsrv6.key" "" "lowport" "ssl:[::1]:$PORT,cafile=testsrv6.crt,$SOCAT_EGD" 6 tcp $PORT -1 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSLTCP6_TCPWRAP case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip6 tcp libwrap openssl) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert6 testsrv6 ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: [::2]" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "ssl-l:$PORT,pf=ip6,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv6.crt,key=testsrv6.key" "" "tcpwrap-etc=$td" "ssl:[::1]:$PORT,cafile=testsrv6.crt,$SOCAT_EGD" 6 tcp $PORT -1 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) # test security with the openssl-commonname option on client side NAME=OPENSSL_CN_CLIENT_SECURITY case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: security of client openssl-commonname option" # connect using non matching server name/address with commonname # options, this should succeed. Then without this option, should fail if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv gentestcert testcli testserversec "$N" "$TEST" "$opts" "SSL:127.0.0.1:$PORT,fork,retry=2,verify,cafile=testsrv.crt" "commonname=$LOCALHOST" "" "SSL-L:$PORT,pf=ip4,reuseaddr,cert=testsrv.crt,key=testsrv.key,verify=0" 4 tcp "" 0 fi ;; # testaddrs, NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) # test security with the openssl-commonname option on server side NAME=OPENSSL_CN_SERVER_SECURITY case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: security of server openssl-commonname option" # connect using with client certificate to server, this should succeed. # Then use the server with a non matching openssl-commonname option, # this must fail if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv gentestcert testcli testserversec "$N" "$TEST" "$opts" "SSL-L:$PORT,pf=ip4,reuseaddr,cert=testsrv.crt,key=testsrv.key,cafile=testcli.crt" "" "commonname=onlyyou" "SSL:$LOCALHOST:$PORT,verify=0,cafile=testsrv.crt,cert=testcli.crt,key=testcli.key" 4 tcp "" 0 fi ;; # testaddrs, NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSL_FIPS_SECURITY case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: OpenSSL restrictions by FIPS" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testoptions fips >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL/FIPS not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv gentestcert testcli # openssl client accepts a "normal" certificate only when not in fips mode testserversec "$N" "$TEST" "$opts -s" "ssl:$LOCALHOST:$PORT,fork,retry=2,verify,cafile=testsrv.crt" "" "fips" "ssl-l:$PORT,pf=ip4,reuseaddr,cert=testsrv.crt,key=testsrv.key" 4 tcp "" -1 fi ;; # testaddrs, NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=UNIEXECEOF case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: give exec'd write-only process a chance to flush (-u)" testod "$N" "$TEST" "" exec:"$OD_C" "$opts -u" esac N=$((N+1)) NAME=REVEXECEOF case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: give exec'd write-only process a chance to flush (-U)" testod "$N" "$TEST" exec:"$OD_C" "-" "$opts -U" esac N=$((N+1)) NAME=FILANDIR case "$TESTS" in *%$N%*|*%filan%*|*%$NAME%*) TEST="$NAME: check type printed for directories" if ! eval $NUMCOND; then :; else te="$td/test$N.stderr" printf "test $F_n $TEST... " $N type=$($FILAN -f . 2>$te |tail -n 1 |awk '{print($2);}') if [ "$type" = "dir" ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi ;; # NUMCOND esac N=$((N+1)) NAME=FILANSOCKET case "$TESTS" in *%$N%*|*%filan%*|*%$NAME%*) TEST="$NAME: capability to analyze named unix socket" if ! eval $NUMCOND; then :; else ts="$td/test$N.socket" te1="$td/test$N.stderr1" # socat te2="$td/test$N.stderr2" # filan printf "test $F_n $TEST... " $N $TRACE $SOCAT $opts UNIX-LISTEN:"$ts" /dev/null "$te1" & spid=$! waitfile "$ts" 1 type=$($FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print($2);}') if [ "$type" = "socket" ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" cat "$te1" cat "$te2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi kill $spid 2>/dev/null wait fi ;; # NUMCOND esac N=$((N+1)) testptywaitslave () { local N="$1" local TEST="$2" local PTYTYPE="$3" # ptmx or openpty local opts="$4" local tp="$td/test$N.pty" local ts="$td/test$N.socket" local tf="$td/test$N.file" local tdiff="$td/test$N.diff" local te1="$td/test$N.stderr1" local te2="$td/test$N.stderr2" local te3="$td/test$N.stderr3" local te4="$td/test$N.stderr4" local da="test$N $(date) $RANDOM" printf "test $F_n $TEST... " $N # first generate a pty, then a socket ($TRACE $SOCAT $opts -lpsocat1 pty,$PTYTYPE,pty-wait-slave,link="$tp" unix-listen:"$ts" 2>"$te1"; rm -f "$tp") 2>/dev/null & pid=$! waitfile "$tp" # if pty was non-blocking, the socket is active, and socat1 will term $TRACE $SOCAT $opts -T 10 -lpsocat2 file:/dev/null unix-connect:"$ts" 2>"$te2" # if pty is blocking, first socat is still active and we get a connection now #((echo "$da"; sleep 2) |$TRACE $SOCAT -lpsocat3 $opts - file:"$tp",$PTYOPTS2 >"$tf" 2>"$te3") & ( (waitfile "$ts"; echo "$da"; sleep 1) |$TRACE $SOCAT -lpsocat3 $opts - file:"$tp",$PTYOPTS2 >"$tf" 2>"$te3") & waitfile "$ts" # but we need an echoer on the socket $TRACE $SOCAT $opts -lpsocat4 unix:"$ts" echo 2>"$te4" # now $tf file should contain $da #kill $pid 2>/dev/null wait # if echo "$da" |diff - "$tf"> "$tdiff"; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "${YELLOW}FAILED${NORMAL}\n" cat "$te1" #cat "$te2" # not of interest cat "$te3" cat "$te4" cat "$tdiff" numCANT=$((numCANT+1)) fi } NAME=PTMXWAITSLAVE PTYTYPE=ptmx case "$TESTS" in *%$N%*|*%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection" if ! eval $NUMCOND; then :; else if ! feat=$(testaddrs pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then $PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts" fi fi ;; # NUMCOND esac N=$((N+1)) NAME=OPENPTYWAITSLAVE PTYTYPE=openpty case "$TESTS" in *%$N%*|*%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then $PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts" fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=CONNECTTIMEOUT case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%timeout%*|*%$NAME%*) TEST="$NAME: test the connect-timeout option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testoptions connect-timeout); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else # we need a hanging connection attempt, guess an address for this case "$UNAME" in Linux) HANGIP=1.0.0.1 ;; *) HANGIP=255.255.255.254 ;; esac te1="$td/test$N.stderr1" tk1="$td/test$N.kill1" te2="$td/test$N.stderr2" tk2="$td/test$N.kill2" $PRINTF "test $F_n $TEST... " $N # first, try to make socat hang and see if it can be killed #$TRACE $SOCAT $opts - tcp:$HANGIP:1 >"$te1" 2>&1 "$te1" 2>&1 "$tk1"; then $PRINTF "${YELLOW}does not hang${NORMAL}\n" numCANT=$((numCANT+1)) else # second, set connect-timeout and see if socat exits before kill $TRACE $SOCAT $opts - tcp:$HANGIP:1,connect-timeout=1.0 >"$te2" 2>&1 "$tk2"; then $PRINTF "$FAILED\n" echo "$CMD" cat "$te1" cat "$te2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" numOK=$((numOK+1)) fi fi wait fi ;; # testaddrs, NUMCOND esac N=$((N+1)) # version 1.7.0.0 had a bug with the connect-timeout option: while it correctly # terminated a hanging connect attempt, it prevented a successful connection # establishment from being recognized by socat, instead the timeout occurred NAME=CONNECTTIMEOUT_CONN if ! eval $NUMCOND; then :; else case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%timeout%*|*%$NAME%*) TEST="$NAME: TCP4 connect-timeout option when server replies" # just try a connection that is expected to succeed with the usual data # transfer; with the bug it will fail tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts STDIO TCP4:$ts,connect-timeout=1" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1=$! waittcp4port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" cat "${te}1" echo "$CMD2" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid1 2>/dev/null wait ;; esac PORT=$((PORT+1)) fi # NUMCOND N=$((N+1)) NAME=OPENSSLLISTENDSA case "$TESTS" in *%$N%*|*%functions%*|*%openssl%*|*%$NAME%*) TEST="$NAME: openssl listen with DSA certificate" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else SRVCERT=testsrvdsa gentestdsacert $SRVCERT tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cert=$SRVCERT.pem,key=$SRVCERT.key,verify=0 pipe" CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD" $PRINTF "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id waittcp4port $PORT echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # testaddrs, NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) # derive signal number from signal name # kill -l should provide the info signum () { if [ ! "$BASH_VERSION" -o -o posix ]; then # we expect: for i in $(POSIXLY_CORRECT=1 kill -l); do echo "$i"; done |grep -n -i "^$1$" |cut -d: -f1 else # expect: # " 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL" signam="$1" kill -l $tpp"'; echo \$$ '">$tp; read x\"",nofork 2>"$te"; stat=$? tsh="$td/test$N.sh" cat <"$tsh" #! /bin/bash echo \$PPID >"$tpp" echo \$\$ >"$tp" read x EOF chmod a+x "$tsh" #$TRACE $SOCAT $opts echo SYSTEM:"exec \"$tsh\"",pty,setsid,nofork 2>"$te"; stat=$? CMD="$TRACE $SOCAT $opts ECHO SYSTEM:\"exec\\\ \\\"$tsh\\\"\",pty,setsid,nofork" $TRACE $SOCAT $opts ECHO SYSTEM:"exec \"$tsh\"",pty,setsid,nofork 2>"$te" stat=$? sleep 1; kill -INT $(cat $tp) wait if [ "$stat" -eq $((128+$SIG)) ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi wait fi ;; # NUMCOND, feats esac N=$((N+1)) done NAME=READBYTES #set -vx case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: restrict reading from file with bytes option" if ! eval $NUMCOND; then :; elif false; then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tr="$td/test$N.ref" ti="$td/test$N.in" to="$td/test$N.out" te="$td/test$N.err" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" # the feature that we really want to test is in the readline.sh script: CMD="$TRACE $SOCAT $opts -u open:$ti,readbytes=100 -" printf "test $F_n $TEST... " $N rm -f "$tf" "$ti" "$to" # echo "AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA" >"$tr" # 100 bytes cat "$tr" "$tr" >"$ti" # 200 bytes $CMD >"$to" 2>"$te" if ! diff "$tr" "$to" >"$tdiff" 2>&1; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=UDPLISTENFORK case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%udp%*|*%listen%*|*%fork%*|*%$NAME%*) TEST="$NAME: UDP socket rebinds after first connection" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da1="test$N $(date) $RANDOM" da2="test$N $(date) $RANDOM" #establish a listening and forking udp socket in background #processes hang forever without -T SRV="$TRACE $SOCAT -T 5 $opts -lpserver UDP4-LISTEN:$PORT,bind=$LOCALHOST,fork PIPE" #make a first and a second connection CLI="$TRACE $SOCAT $opts -lpclient - UDP4-CONNECT:$LOCALHOST:$PORT" $PRINTF "test $F_n $TEST... " $N eval "$SRV 2>${te}s &" pids=$! waitudp4port "$PORT" echo "$da1" |eval "$CLI" >"${tf}1" 2>"${te}1" if [ $? -ne 0 ]; then kill "$pids" 2>/dev/null $PRINTF "$NO_RESULT (first conn failed):\n" echo "$SRV &" echo "$CLI" cat "${te}s" "${te}1" numCANT=$((numCANT+1)) elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$NO_RESULT (first conn failed); diff:\n" cat "$tdiff" numCANT=$((numCANT+1)) else sleep 2 # UDP-LISTEN sleeps 1s echo "$da2" |eval "$CLI" >"${tf}2" 2>"${te}2" rc="$?"; kill "$pids" 2>/dev/null if [ $rc -ne 0 ]; then $PRINTF "$FAILED:\n" echo "$SRV &" echo "$CLI" cat "${te}s" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da2" |diff - "${tf}2" >"$tdiff"; then $PRINTF "$FAILED: diff\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" numOK=$((numOK+1)) fi # !( $? -ne 0) fi # !(rc -ne 0) wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) # is a listen address capable of forking to child processes and have both # active? while read PROTOV MAJADDR MINADDR; do if [ -z "$PROTOV" ] || [[ "$PROTOV" == \#* ]]; then continue; fi protov="$(echo "$PROTOV" |tr A-Z a-z)" proto="${protov%%[0-9]}" NAME=${PROTOV}LISTENFORK case "$TESTS" in *%$N%*|*%functions%*|*%$protov%*|*%$proto%*|*%listen%*|*%fork%*|*%$NAME%*) TEST="$NAME: $PROTOV listen handles 2 concurrent connections" # have a listening address with fork option. connect with client1, send a piece # of data, wait 1s, connect with client2, send another piece of data, wait 1s, # and send another piece of data with client1. The server processes append all # data to the same file. Check all data are written to the file in correct # order. if ! eval $NUMCOND; then :; #elif ! feat=$(testaddrs $PROTOV); then # $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$PROTOV" |tr a-z A-Z) not available${NORMAL}\n" $N # numCANT=$((numCANT+1)) elif ! runs$protov; then $PRINTF "test $F_n $TEST... ${YELLOW}$PROTOV not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ts="$td/test$N.sock" tref="$td/test$N.ref" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da1a="test$N $(date) 1a $RANDOM" da1b="test$N $(date) 1b $RANDOM" da2="test$N $(date) 2 $RANDOM" case "$MAJADDR" in "FILE") tla="$ts" tca="$ts" waitproto="file" waitfor="$ts" ;; esac case "$MINADDR" in "PORT") tla="$PORT,bind=$MAJADDR" tca="$MAJADDR:$PORT" waitproto="${protov}port" waitfor="$PORT" ;; esac #set -xv echo -e "$da1a\n$da2\n$da1b" >"$tref" # establish a listening and forking listen socket in background # UDP processes hang forever without -T CMD0="$TRACE $SOCAT -T 5 $opts -lpserver $PROTOV-LISTEN:$tla,fork PIPE" # make a first and a second connection CMD1="$TRACE $SOCAT $opts -lpclient - $PROTOV-CONNECT:$tca" $PRINTF "test $F_n $TEST... " $N eval "$CMD0 2>${te}0 &" pid0=$! wait$waitproto "$waitfor" 1 2 (echo "$da1a"; sleep 2; echo "$da1b") |eval "$CMD1" >>"${tf}" 2>"${te}1" & sleep 1 # trailing sleep req for sctp because no half close (echo "$da2"; sleep 1) |eval "$CMD1" >>"${tf}" 2>"${te}2" & sleep 2 kill $pid0 2>/dev/null wait if ! diff "$tref" "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "${te}0" "${te}1" "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" numOK=$((numOK+1)) fi # !(rc -ne 0) wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) done <<<" TCP4 $LOCALHOST PORT TCP6 $LOCALHOST6 PORT UDP4 $LOCALHOST PORT UDP6 $LOCALHOST6 PORT SCTP4 $LOCALHOST PORT SCTP6 $LOCALHOST6 PORT UNIX FILE , " NAME=UNIXTOSTREAM case "$TESTS" in *%$N%*|*%functions%*|*%unix%*|*%listen%*|*%$NAME%*) TEST="$NAME: generic UNIX client connects to stream socket" if ! eval $NUMCOND; then :; else ts="$td/test$N.socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da1="test$N $(date) $RANDOM" #establish a listening unix socket in background SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\" PIPE" #make a connection CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts\"" $PRINTF "test $F_n $TEST... " $N eval "$SRV 2>${te}s &" pids=$! waitfile "$ts" echo "$da1" |eval "$CLI" >"${tf}1" 2>"${te}1" if [ $? -ne 0 ]; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" echo "$SRV &" echo "$CLI" cat "${te}s" "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED; diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" numOK=$((numOK+1)) fi # !(rc -ne 0) wait fi ;; # NUMCOND esac N=$((N+1)) NAME=UNIXTODGRAM case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%unix%*|*%recv%*|*%$NAME%*) TEST="$NAME: generic UNIX client connects to datagram socket" if ! eval $NUMCOND; then :; else ts1="$td/test$N.socket1" ts2="$td/test$N.socket2" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da1="test$N $(date) $RANDOM" #establish a receiving unix datagram socket in background SRV="$TRACE $SOCAT $opts -lpserver UNIX-RECVFROM:\"$ts1\" PIPE" #make a connection CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts1\",bind=\"$ts2\"" #CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts1\"" $PRINTF "test $F_n $TEST... " $N eval "$SRV 2>${te}s &" pids=$! waitfile "$ts1" echo "$da1" |eval "$CLI" >"${tf}1" 2>"${te}1" rc=$? wait if [ $rc -ne 0 ]; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" echo "$SRV &" cat "${te}s" echo "$CLI" cat "${te}1" "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" echo "$SRV &" cat "${te}s" echo "$CLI" cat "${te}1" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" numOK=$((numOK+1)) fi # !(rc -ne 0) fi ;; # NUMCOND esac N=$((N+1)) # there was an error in address EXEC with options pipes,stderr NAME=EXECPIPESSTDERR case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with pipes,stderr" # this test is known to fail when logging is enabled with OPTS/opts env var. SAVE_opts="$opts" opts="$(echo "$opts" |sed 's/-d//g')" testecho "$N" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts" opts="$SAVE_opts" esac N=$((N+1)) # EXEC and SYSTEM with stderr injected socat messages into the data stream. NAME=EXECSTDERRLOG case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with pipes,stderr" SAVE_opts="$opts" # make sure at least two -d are there case "$opts" in *-d*-d*) ;; *-d*) opts="$opts -d" ;; *) opts="-d -d" ;; esac testecho "$N" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts" opts="$SAVE_opts" esac N=$((N+1)) NAME=SIMPLEPARSE case "$TESTS" in *%$N%*|*%functions%*|*%PARSE%*|*%$NAME%*) TEST="$NAME: invoke socat from socat" testecho "$N" "$TEST" "" exec:"$SOCAT - exec\:$CAT,pipes" "$opts" esac N=$((N+1)) NAME=FULLPARSE case "$TESTS" in *%$N%*|*%functions%*|*%parse%*|*%$NAME%*) TEST="$NAME: correctly parse special chars" if ! eval $NUMCOND; then :; else $PRINTF "test $F_n $TEST... " $N tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" # a string where commas are hidden in nesting lexical constructs # if they are scanned incorrectly, socat will see an "unknown option" dain='(,)[,]{,}","([),])hugo' daout='(,)[,]{,},([),])hugo' $TRACE "$SOCAT" $opts -u "exec:echo $dain" - >"$tf" 2>"$te" rc=$? echo "$daout" |diff "$tf" - >"$tdiff" if [ "$rc" -ne 0 ]; then $PRINTF "$FAILED:\n" echo "$TRACE $SOCAT" -u "exec:echo $da" - cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif [ -s "$tdiff" ]; then $PRINTF "$FAILED:\n" echo diff: cat "$tdiff" if [ -n "$debug" ]; then cat $te; fi numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) NAME=NESTEDSOCATEXEC case "$TESTS" in *%parse%*|*%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: does lexical analysis work sensibly (exec)" testecho "$N" "$TEST" "" "exec:'$SOCAT - exec:$CAT,pipes'" "$opts" 1 esac N=$((N+1)) NAME=NESTEDSOCATSYSTEM case "$TESTS" in *%parse%*|*%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: does lexical analysis work sensibly (system)" testecho "$N" "$TEST" "" "system:\"$SOCAT - exec:$CAT,pipes\"" "$opts" 1 esac N=$((N+1)) NAME=TCP6BYTCP4 case "$TESTS" in *%$N%*|*%functions%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%$NAME%*) TEST="$NAME: TCP4 mapped into TCP6 address space" if ! eval $NUMCOND; then :; elif ! testaddrs tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts TCP6-listen:$tsl,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP6:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid=$! # background process id waittcp6port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null; wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) # test the UDP4-SENDTO and UDP4-RECVFROM addresses together NAME=UDP4DGRAM case "$TESTS" in *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%$NAME%*) TEST="$NAME: UDP/IPv4 sendto and recvfrom" # start a UDP4-RECVFROM process that echoes data, and send test data using # UDP4-SENDTO. The sent data should be returned. if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) ts1a="127.0.0.1" ts1="$ts1a:$ts1p" ts2p=$PORT; PORT=$((PORT+1)) ts2="127.0.0.1:$ts2p" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE" CMD2="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts1,bind=$ts2" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & pid1="$!" waitudp4port $ts1p 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2="$?" kill "$pid1" 2>/dev/null; wait; if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" cat "${te}1" echo "$CMD2" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" echo "$CMD1 &" cat "${te}1" echo "$CMD2" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6DGRAM case "$TESTS" in *%$N%*|*%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%dgram%*|*%$NAME%*) TEST="$NAME: UDP/IPv6 datagram" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) tsa="[::1]" ts1="$tsa:$ts1p" ts2p=$PORT; PORT=$((PORT+1)) ts2="$tsa:$ts2p" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts UDP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE" CMD2="$TRACE $SOCAT $opts - UDP6-SENDTO:$ts1,bind=$ts2" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & waitudp6port $ts1p 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=RAWIP4RECVFROM case "$TESTS" in *%$N%*|*%functions%*|*%ip%*|*%ip4%*|*%rawip%*|*%rawip4%*|*%dgram%*|*%root%*|*%$NAME%*) TEST="$NAME: raw IPv4 datagram" if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PROTO; PROTO=$((PROTO+1)) ts1a="127.0.0.1" ts1="$ts1a:$ts1p" ts2a="$SECONDADDR" ts2="$ts2a:$ts2p" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE" CMD2="$TRACE $SOCAT $opts - IP4-SENDTO:$ts1,bind=$ts2a" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & pid1=$! waitip4proto $ts1p 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # root, NUMCOND esac N=$((N+1)) if false; then NAME=RAWIP6RECVFROM case "$TESTS" in *%$N%*|*%functions%*|*%ip%*|*%ip6%*|*%rawip%*|*%rawip6%*|*%dgram%*|*%root%*|*%$NAME%*) TEST="$NAME: raw IPv6 datagram by self addressing" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip6 rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PROTO; PROTO=$((PROTO+1)) tsa="[::1]" ts1="$tsa:$ts1p" ts2="$tsa" da="test$N $(date) $RANDOM" #CMD1="$TRACE $SOCAT $opts IP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE" CMD2="$TRACE $SOCAT $opts - IP6-SENDTO:$ts1,bind=$ts2" printf "test $F_n $TEST... " $N #$CMD1 2>"${te}1" & waitip6proto $ts1p 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" # echo "$CMD1 &" # cat "${te}1" echo "$CMD2" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi numOK=$((numOK+1)) fi fi ;; # root, NUMCOND esac N=$((N+1)) fi #false NAME=UNIXDGRAM case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%unix%*|*%dgram%*|*%$NAME%*) TEST="$NAME: UNIX datagram" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1="$td/test$N.socket1" ts2="$td/test$N.socket2" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts UNIX-RECVFROM:$ts1,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts - UNIX-SENDTO:$ts1,bind=$ts2" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & pid1="$!" waitfile $ts1 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? kill "$pid1" 2>/dev/null; wait if [ $rc2 -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" cat "${te}1" echo "$CMD2" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi # NUMCOND ;; esac N=$((N+1)) NAME=UDP4RECV case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%ip4%*|*%dgram%*|*%udp%*|*%udp4%*|*%recv%*|*%$NAME%*) TEST="$NAME: UDP/IPv4 receive" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) ts1a="127.0.0.1" ts1="$ts1a:$ts1p" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -u UDP4-RECV:$ts1p,reuseaddr -" CMD2="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$ts1" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1="$!" waitudp4port $ts1p 1 echo "$da" |$CMD2 2>>"${te}2" rc2="$?" #ls -l $tf i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done kill "$pid1" 2>/dev/null; wait if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi # NUMCOND ;; esac N=$((N+1)) NAME=UDP6RECV case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%dgram%*|*%udp%*|*%udp6%*|*%recv%*|*%$NAME%*) TEST="$NAME: UDP/IPv6 receive" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) ts1a="[::1]" ts1="$ts1a:$ts1p" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -u UDP6-RECV:$ts1p,reuseaddr -" CMD2="$TRACE $SOCAT $opts -u - UDP6-SENDTO:$ts1" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1="$!" waitudp6port $ts1p 1 echo "$da" |$CMD2 2>>"${te}2" rc2="$?" #ls -l $tf i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done kill "$pid1" 2>/dev/null; wait if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=RAWIP4RECV case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%dgram%*|*%rawip%*|*%rawip4%*|*%recv%*|*%root%*|*%$NAME%*) TEST="$NAME: raw IPv4 receive" if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PROTO; PROTO=$((PROTO+1)) ts1a="127.0.0.1" ts1="$ts1a:$ts1p" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -u IP4-RECV:$ts1p,reuseaddr -" CMD2="$TRACE $SOCAT $opts -u - IP4-SENDTO:$ts1" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1="$!" waitip4proto $ts1p 1 echo "$da" |$CMD2 2>>"${te}2" rc2="$?" #ls -l $tf i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done kill "$pid1" 2>/dev/null; wait if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, root esac N=$((N+1)) NAME=RAWIP6RECV case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%dgram%*|*%rawip%*|*%rawip6%*|*%recv%*|*%root%*|*%$NAME%*) TEST="$NAME: raw IPv6 receive" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip6 rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PROTO; PROTO=$((PROTO+1)) ts1a="[::1]" ts1="$ts1a:$ts1p" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -u IP6-RECV:$ts1p,reuseaddr -" CMD2="$TRACE $SOCAT $opts -u - IP6-SENDTO:$ts1" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1="$!" waitip6proto $ts1p 1 echo "$da" |$CMD2 2>>"${te}2" rc2="$?" i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done kill "$pid1" 2>/dev/null; wait if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, root esac N=$((N+1)) NAME=UNIXRECV case "$TESTS" in *%$N%*|*%functions%*|*%unix%*|*%dgram%*|*%recv%*|*%$NAME%*) TEST="$NAME: UNIX receive" if ! eval $NUMCOND; then :; else ts="$td/test$N.socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1="$ts" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -u UNIX-RECV:$ts1,reuseaddr -" CMD2="$TRACE $SOCAT $opts -u - UNIX-SENDTO:$ts1" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1="$!" waitfile $ts1 1 echo "$da" |$CMD2 2>>"${te}2" rc2="$?" i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done kill "$pid1" 2>/dev/null; wait if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi # NUMCOND ;; esac N=$((N+1)) NAME=UDP4RECVFROM_SOURCEPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECVFROM with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "udp4-recvfrom:$PORT,reuseaddr" "" "sp=$PORT" "udp4-sendto:127.0.0.1:$PORT" 4 udp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP4RECVFROM_LOWPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECVFROM with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "udp4-recvfrom:$PORT,reuseaddr" "" "lowport" "udp4-sendto:127.0.0.1:$PORT" 4 udp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP4RECVFROM_RANGE case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECVFROM with RANGE option" #testserversec "$N" "$TEST" "$opts -s" "udp4-recvfrom:$PORT,reuseaddr,fork" "" "range=$SECONDADDR/32" "udp4-sendto:127.0.0.1:$PORT" 4 udp $PORT 0 if ! eval $NUMCOND; then :; else testserversec "$N" "$TEST" "$opts -s" "udp4-recvfrom:$PORT,reuseaddr" "" "range=$SECONDADDR/32" "udp4-sendto:127.0.0.1:$PORT" 4 udp $PORT 0 fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP4RECVFROM_TCPWRAP case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECVFROM with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4 udp libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: $SECONDADDR" >"$ha" $ECHO "ALL: ALL" >"$hd" #testserversec "$N" "$TEST" "$opts -s" "udp4-recvfrom:$PORT,reuseaddr,fork" "" "tcpwrap=$d" "udp4-sendto:127.0.0.1:$PORT" 4 udp $PORT 0 testserversec "$N" "$TEST" "$opts -s" "udp4-recvfrom:$PORT,reuseaddr" "" "tcpwrap-etc=$td" "udp4-sendto:127.0.0.1:$PORT" 4 udp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP4RECV_SOURCEPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECV with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else PORT1=$PORT; PORT=$((PORT+1)) PORT2=$PORT; PORT=$((PORT+1)) PORT3=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp4-recv:$PORT1,reuseaddr!!udp4-sendto:127.0.0.1:$PORT2" "" "sp=$PORT3" "udp4-recv:$PORT2!!udp4-sendto:127.0.0.1:$PORT1" 4 udp $PORT1 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP4RECV_LOWPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECV with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else PORT1=$PORT; PORT=$((PORT+1)) PORT2=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp4-recv:$PORT1,reuseaddr!!udp4-sendto:127.0.0.1:$PORT2" "" "lowport" "udp4-recv:$PORT2!!udp4-sendto:127.0.0.1:$PORT1" 4 udp $PORT1 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP4RECV_RANGE case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECV with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else PORT1=$PORT; PORT=$((PORT+1)) PORT2=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp4-recv:$PORT1,reuseaddr!!udp4-sendto:127.0.0.1:$PORT2" "" "range=$SECONDADDR/32" "udp4-recv:$PORT2!!udp4-sendto:127.0.0.1:$PORT1" 4 udp $PORT1 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP4RECV_TCPWRAP case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECV with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else PORT1=$PORT; PORT=$((PORT+1)) PORT2=$PORT ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: $SECONDADDR" >"$ha" $ECHO "ALL: ALL" >"$hd" # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp4-recv:$PORT1,reuseaddr!!udp4-sendto:127.0.0.1:$PORT2" "" "tcpwrap-etc=$td" "udp4-recv:$PORT2!!udp4-sendto:127.0.0.1:$PORT1" 4 udp $PORT1 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6RECVFROM_SOURCEPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECVFROM with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "udp6-recvfrom:$PORT,reuseaddr" "" "sp=$PORT" "udp6-sendto:[::1]:$PORT" 6 udp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6RECVFROM_LOWPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECVFROM with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "udp6-recvfrom:$PORT,reuseaddr" "" "lowport" "udp6-sendto:[::1]:$PORT" 6 udp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6RECVFROM_RANGE case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECVFROM with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else #testserversec "$N" "$TEST" "$opts -s" "udp6-recvfrom:$PORT,reuseaddr,fork" "" "range=[::2/128]" "udp6-sendto:[::1]:$PORT" 6 udp $PORT 0 testserversec "$N" "$TEST" "$opts -s" "udp6-recvfrom:$PORT,reuseaddr" "" "range=[::2/128]" "udp6-sendto:[::1]:$PORT" 6 udp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6RECVFROM_TCPWRAP case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECVFROM with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip6 libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: [::2]" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "udp6-recvfrom:$PORT,reuseaddr" "" "tcpwrap-etc=$td" "udp6-sendto:[::1]:$PORT" 6 udp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6RECV_SOURCEPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECV with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else PORT1=$PORT; PORT=$((PORT+1)) PORT2=$PORT; PORT=$((PORT+1)) PORT3=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp6-recv:$PORT1,reuseaddr!!udp6-sendto:[::1]:$PORT2" "" "sp=$PORT3" "udp6-recv:$PORT2!!udp6-sendto:[::1]:$PORT1" 6 udp $PORT1 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6RECV_LOWPORT case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECV with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else PORT1=$PORT; PORT=$((PORT+1)) PORT2=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp6-recv:$PORT1,reuseaddr!!udp6-sendto:[::1]:$PORT2" "" "lowport" "udp6-recv:$PORT2!!udp6-sendto:[::1]:$PORT1" 6 udp $PORT1 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6RECV_RANGE case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECV with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else PORT1=$PORT; PORT=$((PORT+1)) PORT2=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp6-recv:$PORT1,reuseaddr!!udp6-sendto:[::1]:$PORT2" "" "range=[::2/128]" "udp6-recv:$PORT2!!udp6-sendto:[::1]:$PORT1" 6 udp $PORT1 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6RECV_TCPWRAP case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECV with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip6 libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: [::2]" >"$ha" $ECHO "ALL: ALL" >"$hd" PORT1=$PORT; PORT=$((PORT+1)) PORT2=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp6-recv:$PORT1,reuseaddr!!udp6-sendto:[::1]:$PORT2" "" "tcpwrap-etc=$td" "udp6-recv:$PORT2!!udp6-sendto:[::1]:$PORT1" 6 udp $PORT1 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=IP4RECVFROM_RANGE case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip4%*|*%range%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP4-RECVFROM with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else #testserversec "$N" "$TEST" "$opts -s" "ip4-recvfrom:$PROTO,reuseaddr,fork" "" "range=$SECONDADDR/32" "ip4-sendto:127.0.0.1:$PROTO" 4 ip $PROTO 0 testserversec "$N" "$TEST" "$opts -s" "ip4-recvfrom:$PROTO,reuseaddr!!udp4-sendto:127.0.0.1:$PORT" "" "range=$SECONDADDR/32" "udp4-recv:$PORT!!ip4-sendto:127.0.0.1:$PROTO" 4 ip $PROTO 0 fi ;; # NUMCOND, feats, root esac PROTO=$((PROTO+1)) PORT=$((PORT+1)) N=$((N+1)) NAME=IP4RECVFROM_TCPWRAP case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip4%*|*%tcpwrap%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP4-RECVFROM with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4 rawip libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: $SECONDADDR" >"$ha" $ECHO "ALL: ALL" >"$hd" #testserversec "$N" "$TEST" "$opts -s" "ip4-recvfrom:$PROTO,reuseaddr,fork" "" "tcpwrap-etc=$td" "ip4-sendto:127.0.0.1:$PROTO" 4 ip $PROTO 0 testserversec "$N" "$TEST" "$opts -s" "ip4-recvfrom:$PROTO,reuseaddr!!udp4-sendto:127.0.0.1:$PORT" "" "tcpwrap-etc=$td" "udp4-recv:$PORT!!ip4-sendto:127.0.0.1:$PROTO" 4 ip $PROTO 0 fi # NUMCOND, feats, root ;; esac PROTO=$((PROTO+1)) PORT=$((PORT+1)) N=$((N+1)) NAME=IP4RECV_RANGE case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip4%*|*%range%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP4-RECV with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else PROTO1=$PROTO; PROTO=$((PROTO+1)) PROTO2=$PROTO # we use the forward channel (PROTO1) for testing, and have a backward channel # (PROTO2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "ip4-recv:$PROTO1,reuseaddr!!ip4-sendto:127.0.0.1:$PROTO2" "" "range=$SECONDADDR/32" "ip4-recv:$PROTO2!!ip4-sendto:127.0.0.1:$PROTO1" 4 ip $PROTO1 0 fi ;; # NUMCOND, feats, root esac PROTO=$((PROTO+1)) N=$((N+1)) NAME=IP4RECV_TCPWRAP case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip4%*|*%tcpwrap%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP4-RECV with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4 rawip libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else PROTO1=$PROTO; PROTO=$((PROTO+1)) PROTO2=$PROTO ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: $SECONDADDR" >"$ha" $ECHO "ALL: ALL" >"$hd" # we use the forward channel (PROTO1) for testing, and have a backward channel # (PROTO2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "ip4-recv:$PROTO1,reuseaddr!!ip4-sendto:127.0.0.1:$PROTO2" "" "tcpwrap-etc=$td" "ip4-recv:$PROTO2!!ip4-sendto:127.0.0.1:$PROTO1" 4 ip $PROTO1 0 fi ;; # NUMCOND, feats, root esac PROTO=$((PROTO+1)) N=$((N+1)) NAME=IP6RECVFROM_RANGE case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip6%*|*%range%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP6-RECVFROM with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip6 rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else #testserversec "$N" "$TEST" "$opts -s" "ip6-recvfrom:$PROTO,reuseaddr,fork" "" "range=[::2/128]" "ip6-sendto:[::1]:$PROTO" 6 ip $PROTO 0 testserversec "$N" "$TEST" "$opts -s" "ip6-recvfrom:$PROTO,reuseaddr!!udp6-sendto:[::1]:$PORT" "" "range=[::2/128]" "udp6-recv:$PORT!!ip6-sendto:[::1]:$PROTO" 6 ip $PROTO 0 fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) PORT=$((PORT+1)) N=$((N+1)) NAME=IP6RECVFROM_TCPWRAP case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip6%*|*%tcpwrap%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP6-RECVFROM with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip6 rawip libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: [::2]" >"$ha" $ECHO "ALL: ALL" >"$hd" #testserversec "$N" "$TEST" "$opts -s" "ip6-recvfrom:$PROTO,reuseaddr,fork" "" "tcpwrap-etc=$td" "ip6-sendto:[::1]:$PROTO" 6 ip $PROTO 0 testserversec "$N" "$TEST" "$opts -s" "ip6-recvfrom:$PROTO,reuseaddr!!udp6-sendto:[::1]:$PORT" "" "tcpwrap-etc=$td" "udp6-recv:$PORT!!ip6-sendto:[::1]:$PROTO" 6 ip $PROTO 0 fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) PORT=$((PORT+1)) N=$((N+1)) NAME=IP6RECV_RANGE case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip6%*|*%range%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP6-RECV with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip6 rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}raw IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else PROTO1=$PROTO; PROTO=$((PROTO+1)) PROTO2=$PROTO # we use the forward channel (PROTO1) for testing, and have a backward channel # (PROTO2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "ip6-recv:$PROTO1,reuseaddr!!ip6-sendto:[::1]:$PROTO2" "" "range=[::2/128]" "ip6-recv:$PROTO2!!ip6-sendto:[::1]:$PROTO1" 6 ip $PROTO1 0 fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) N=$((N+1)) NAME=IP6RECV_TCPWRAP case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip6%*|*%tcpwrap%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP6-RECV with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip6 rawip libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else PROTO1=$PROTO; PROTO=$((PROTO+1)) PROTO2=$PROTO ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: [::2]" >"$ha" $ECHO "ALL: ALL" >"$hd" # we use the forward channel (PROTO1) for testing, and have a backward channel # (PROTO2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "ip6-recv:$PROTO1,reuseaddr!!ip6-sendto:[::1]:$PROTO2" "" "tcpwrap-etc=$td" "ip6-recv:$PROTO2!!ip6-sendto:[::1]:$PROTO1" 6 ip $PROTO1 0 fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) N=$((N+1)) NAME=O_NOATIME_FILE case "$TESTS" in *%$N%*|*%functions%*|*%open%*|*%noatime%*|*%$NAME%*) TEST="$NAME: option O_NOATIME on file" # idea: create a file with o-noatime option; one second later create a file # without this option (using touch); one second later read from the first file. # Then we check which file has the later ATIME stamp. For this check we use # "ls -ltu" because it is more portable than "test ... -nt ..." if ! eval $NUMCOND; then :; elif ! testoptions o-noatime >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.file" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" $PRINTF "test $F_n $TEST... " $N CMD="$TRACE $SOCAT $opts -u open:\"${tf}1\",o-noatime /dev/null" # generate a file touch "${tf}1" sleep 1 # generate a reference file touch "${tf}2" sleep 1 # read from the first file $CMD 2>"$te" if [ $? -ne 0 ]; then # command failed $PRINTF "${FAILED}:\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else # check which file has a later atime stamp if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi numOK=$((numOK+1)) fi # wrong time stamps fi # command ok fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=O_NOATIME_FD case "$TESTS" in *%$N%*|*%functions%*|*%noatime%*|*%$NAME%*) TEST="$NAME: option O_NOATIME on file descriptor" # idea: use a fd of a file with o-noatime option; one second later create a file # without this option (using touch); one second later read from the first file. # Then we check which file has the later ATIME stamp. For this check we use # "ls -ltu" because it is more portable than "test ... -nt ..." if ! eval $NUMCOND; then :; elif ! testoptions o-noatime >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.file" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" $PRINTF "test $F_n $TEST... " $N touch ${tf}1 CMD="$TRACE $SOCAT $opts -u -,o-noatime /dev/null <${tf}1" # generate a file, len >= 1 touch "${tf}1" sleep 1 # generate a reference file touch "${tf}2" sleep 1 # read from the first file sh -c "$CMD" 2>"$te" if [ $? -ne 0 ]; then # command failed $PRINTF "${FAILED}:\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else # check which file has a later atime stamp if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi numOK=$((numOK+1)) fi # wrong time stamps fi # command ok fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=EXT2_NOATIME case "$TESTS" in *%$N%*|*%functions%*|*%ext2%*|*%noatime%*|*%$NAME%*) TEST="$NAME: extended file system options using ext2fs noatime option" # idea: create a file with ext2-noatime option; one second later create a file # without this option (using touch); one second later read from the first file. # Then we check which file has the later ATIME stamp. For this check we use # "ls -ltu" because it is more portable than "test ... -nt ..." if ! eval $NUMCOND; then :; elif ! testoptions ext2-noatime >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}ext2-noatime not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ts="$td/test$N.socket" tf="$td/test$N.file" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1="$ts" da="test$N $(date) $RANDOM" $PRINTF "test $F_n $TEST... " $N CMD0="$TRACE $SOCAT $opts -u /dev/null create:\"${tf}1\"" CMD="$TRACE $SOCAT $opts -u /dev/null create:\"${tf}1\",ext2-noatime" # check if this is a capable FS; lsattr does other things on AIX, thus socat $CMD0 2>"${te}0" if [ $? -ne 0 ]; then $PRINTF "${YELLOW} cannot test${NORMAL}\n" numCANT=$((numCANT+1)) else # generate a file with noatime, len >= 1 $CMD 2>"$te" if [ $? -ne 0 ]; then # command failed $PRINTF "${YELLOW}impotent file system?${NORMAL}\n" echo "$CMD" cat "$te" numCANT=$((numCANT+1)) else sleep 1 # generate a reference file touch "${tf}2" sleep 1 # read from the first file cat "${tf}1" >/dev/null # check which file has a later atime stamp #if [ $(ls -ltu "${tf}1" "${tf}2" |head -n 1 |awk '{print($8);}') != "${tf}2" ]; if [ $(ls -ltu "${tf}1" "${tf}2" |head -n 1 |sed "s|.*\\($td.*\\)|\1|g") != "${tf}2" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi numOK=$((numOK+1)) fi fi # not impotent fi # can test fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=COOLWRITE case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%coolwrite%*|*%$NAME%*) TEST="$NAME: option cool-write" if ! eval $NUMCOND; then :; elif ! testoptions cool-write >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else #set -vx ti="$td/test$N.pipe" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" # a reader that will terminate after 1 byte CMD1="$TRACE $SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null" CMD="$TRACE $SOCAT $opts -u - file:\"$ti\",cool-write" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & bg=$! # background process id sleep 1 (echo .; sleep 1; echo) |$CMD 2>"$te" rc=$? kill $bg 2>/dev/null; wait if [ $rc -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD &" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac N=$((N+1)) # test if option coolwrite can be applied to bidirectional address stdio # this failed up to socat 1.6.0.0 NAME=COOLSTDIO case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%coolwrite%*|*%$NAME%*) TEST="$NAME: option cool-write on bidirectional stdio" # this test starts a socat reader that terminates after receiving one+ # bytes (option readbytes); and a test process that sends two bytes via # named pipe to the receiving process and, a second later, sends another # byte. The last write will fail with "broken pipe"; if option coolwrite # has been applied successfully, socat will terminate with 0 (OK), # otherwise with error. if ! eval $NUMCOND; then :; elif ! testoptions cool-write >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else #set -vx ti="$td/test$N.pipe" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" # a reader that will terminate after 1 byte CMD1="$TRACE $SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null" CMD="$TRACE $SOCAT $opts -,cool-write pipe >\"$ti\"" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & bg=$! # background process id sleep 1 (echo .; sleep 1; echo) |eval "$CMD" 2>"$te" rc=$? kill $bg 2>/dev/null; wait if [ $rc -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD &" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=TCP4ENDCLOSE case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: end-close keeps TCP V4 socket open" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" p1=$PORT; PORT=$((PORT+1)) p2=$PORT da1a="$(date) $RANDOM" da1b="$(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -u - TCP4-CONNECT:$LOCALHOST:$p1" CMD="$TRACE $SOCAT $opts -U TCP4:$LOCALHOST:$p2,end-close TCP4-LISTEN:$p1,bind=$LOCALHOST,reuseaddr,fork" CMD3="$TRACE $SOCAT $opts -u TCP4-LISTEN:$p2,reuseaddr,bind=$LOCALHOST -" printf "test $F_n $TEST... " $N $CMD3 >"$tf" 2>"${te}3" & pid3=$! waittcp4port $p2 1 $CMD 2>"${te}2" & pid2=$! usleep $MICROS waittcp4port $p1 1 echo "$da1a" |$CMD1 2>>"${te}1a" echo "$da1b" |$CMD1 2>>"${te}1b" sleep 1 kill "$pid3" "$pid2" 2>/dev/null wait if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1a" "${te}1b" "${te}2" "${te}3" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! $ECHO "$da1a\n$da1b" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" cat "${te}1a" "${te}1b" "${te}2" "${te}3" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1a" "${te}1b" "${te}2" "${te}3"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=EXECENDCLOSE case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%$NAME%*) TEST="$NAME: end-close keeps EXEC child running" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" ts="$td/test$N.sock" tdiff="$td/test$N.diff" da1a="$(date) $RANDOM" da1b="$(date) $RANDOM" CMD1="$TRACE $SOCAT $opts - UNIX-CONNECT:$ts" CMD="$TRACE $SOCAT $opts EXEC:"$CAT",end-close UNIX-LISTEN:$ts,fork" printf "test $F_n $TEST... " $N $CMD 2>"${te}2" & pid2=$! waitfile $ts 1 echo "$da1a" |$CMD1 2>>"${te}1a" >"$tf" usleep $MICROS echo "$da1b" |$CMD1 2>>"${te}1b" >>"$tf" #usleep $MICROS kill "$pid2" 2>/dev/null wait if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1a" "${te}1b" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! $ECHO "$da1a\n$da1b" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" cat "${te}1a" "${te}1b" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1a" "${te}1b" "${te}2"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) # up to 1.7.0.0 option end-close led to an error with some address types due to # bad internal handling. here we check it for address PTY NAME=PTYENDCLOSE case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%$NAME%*) TEST="$NAME: PTY handles option end-close" # with the bug, socat exits with error. we invoke socat in a no-op mode and # check its return status. if ! eval $NUMCOND; then :; else tf="$td/test$N.stout" te="$td/test$N.stderr" CMD="$TRACE $SOCAT $opts /dev/null pty,end-close" printf "test $F_n $TEST... " $N $CMD 2>"${te}" rc=$? if [ "$rc" = 0 ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac N=$((N+1)) # test the shut-null and null-eof options NAME=SHUTNULLEOF case "$TESTS" in *%$N%*|*%functions%*|*%socket%*|*%$NAME%*) TEST="$NAME: options shut-null and null-eof" # run a receiving background process with option null-eof. # start a sending process with option shut-null that sends a test record to the # receiving process and then terminates. # send another test record. # whe the receiving process just got the first test record the test succeeded if ! eval $NUMCOND; then :; else tf="$td/test$N.stout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts -u UDP-RECV:$PORT,null-eof CREAT:$tf" CMD1="$TRACE $SOCAT $opts -u - UDP-SENDTO:127.0.0.1:$PORT,shut-null" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & pid0=$! waitudp4port $PORT 1 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" rc1=$? echo "xyz" |$CMD1 >"${tf}2" 2>"${te}2" rc2=$? kill $pid0 2>/dev/null; wait if [ $rc1 != 0 -o $rc2 != 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif echo "$da" |diff - "${tf}" >"$tdiff"; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" cat "${tdiff}" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac N=$((N+1)) NAME=UDP6LISTENBIND # this tests for a bug in (up to) 1.5.0.0: # with udp*-listen, the bind option supported only IPv4 case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%ip6%*|*%ipapp%*|*%udp%*|*%$NAME%*) TEST="$NAME: UDP6-LISTEN with bind" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="$LOCALHOST6:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts UDP6-LISTEN:$tsl,reuseaddr,bind=$LOCALHOST6 PIPE" CMD2="$TRACE $SOCAT $opts - UDP6:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1=$! waitudp6port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=TCPWRAPPERS_MULTIOPTS # this tests for a bug in 1.5.0.0 that let socat fail when more than one # tcp-wrappers related option was specified in one address case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: use of multiple tcpwrapper enabling options" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" ha="$td/hosts.allow" $ECHO "test : ALL : allow" >"$ha" CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr,hosts-allow=$ha,tcpwrap=test pipe" CMD2="$TRACE $SOCAT $opts - TCP:$LOCALHOST:$PORT" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & waittcp4port $PORT echo "$da" |$CMD2 >"$tf" 2>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=TCPWRAPPERS_TCP6ADDR # this tests for a bug in 1.5.0.0 that brought false results with tcp-wrappers # and IPv6 when case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: specification of TCP6 address in hosts.allow" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp ip6 libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat : [::1] : allow" >"$ha" $ECHO "ALL : ALL : deny" >"$hd" CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$PORT,reuseaddr,tcpwrap-etc=$td,tcpwrappers=socat pipe" CMD2="$TRACE $SOCAT $opts - TCP6:[::1]:$PORT" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & pid1=$! waittcp6port $PORT echo "$da" |$CMD2 >"$tf" 2>"${te}2" kill $pid1 2>/dev/null; wait if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=UDP4BROADCAST case "$TESTS" in *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%$NAME%*) TEST="$NAME: UDP/IPv4 broadcast" if ! eval $NUMCOND; then :; elif [ -z "$BCADDR" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) #ts1="$BCADDR/8:$ts1p" ts1="$BCADDR:$ts1p" ts2p=$PORT; PORT=$((PORT+1)) ts2="$BCIFADDR:$ts2p" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,broadcast PIPE" #CMD2="$TRACE $SOCAT $opts - UDP4-BROADCAST:$ts1" CMD2="$TRACE $SOCAT $opts - UDP4-DATAGRAM:$ts1,broadcast" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & pid1="$!" waitudp4port $ts1p 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2="$?" kill "$pid1" 2>/dev/null; wait; if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$tut" ]; then echo "$CMD1 &" echo "$CMD2" fi if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=IP4BROADCAST # test a local broadcast of a raw IPv4 protocol. # because we receive - in addition to the regular reply - our own broadcast, # we use a token XXXX that is changed to YYYY in the regular reply packet. case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%rawip%*|*%rawip4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%root%*|*%$NAME%*) TEST="$NAME: raw IPv4 broadcast" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}raw IP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ -z "$BCADDR" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PROTO #ts1="$BCADDR/8:$ts1p" ts1="$BCADDR:$ts1p" ts2p=$ts1p ts2="$BCIFADDR" da="test$N $(date) $RANDOM XXXX" sh="$td/test$N-sed.sh" echo 'sed s/XXXX/YYYY/' >"$sh" chmod a+x "$sh" CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,broadcast exec:$sh" #CMD2="$TRACE $SOCAT $opts - IP4-BROADCAST:$ts1" CMD2="$TRACE $SOCAT $opts - IP4-DATAGRAM:$ts1,broadcast" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & pid1="$!" waitip4port $ts1p 1 echo "$da" |$CMD2 2>>"${te}2" |grep -v XXXX >>"$tf" rc2="$?" kill "$pid1" 2>/dev/null; wait; if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" | sed 's/XXXX/YYYY/'|diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) N=$((N+1)) #NAME=UDP4BROADCAST_RANGE #case "$TESTS" in #*%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%range%*|*%$NAME%*) #TEST="$NAME: security of UDP4-BROADCAST with RANGE option" #if ! eval $NUMCOND; then :; #elif [ -z "$BCADDR" ]; then # $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N #else #testserversec "$N" "$TEST" "$opts -s" "UDP4-BROADCAST:$BCADDR/8:$PORT" "" "range=127.1.0.0:255.255.0.0" "udp4:127.1.0.0:$PORT" 4 udp $PORT 0 #fi ;; # NUMCOND, feats #esac #PORT=$((PORT+1)) #N=$((N+1)) NAME=UDP4MULTICAST_UNIDIR case "$TESTS" in *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%multicast%*|*%$NAME%*) TEST="$NAME: UDP/IPv4 multicast, send only" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4 udp) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) ts1a="$SECONDADDR" ts1="$ts1a:$ts1p" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT -u $opts UDP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -" CMD2="$TRACE $SOCAT -u $opts - UDP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" >"${tf}" & pid1="$!" waitudp4port $ts1p 1 echo "$da" |$CMD2 2>>"${te}2" rc2="$?" usleep $MICROS kill "$pid1" 2>/dev/null; wait; if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=IP4MULTICAST_UNIDIR case "$TESTS" in *%$N%*|*%functions%*|*%rawip%*|*%ip4%*|*%dgram%*|*%multicast%*|*%root%*|*%$NAME%*) TEST="$NAME: IPv4 multicast" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PROTO ts1a="$SECONDADDR" ts1="$ts1a:$ts1p" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT -u $opts IP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -" CMD2="$TRACE $SOCAT -u $opts - IP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" >"${tf}" & pid1="$!" waitip4proto $ts1p 1 usleep $MICROS echo "$da" |$CMD2 2>>"${te}2" rc2="$?" #usleep $MICROS sleep 1 kill "$pid1" 2>/dev/null; wait; if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) N=$((N+1)) if false; then NAME=UDP6MULTICAST_UNIDIR case "$TESTS" in *%$N%*|*%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%dgram%*|*%multicast%*|*%$NAME%*) TEST="$NAME: UDP/IPv6 multicast" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip6 udp) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) if1="$MCINTERFACE" ts1a="[::1]" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT -u $opts UDP6-RECV:$ts1p,reuseaddr,ipv6-join-group=[ff02::2]:$if1 -" CMD2="$TRACE $SOCAT -u $opts - UDP6-SENDTO:[ff02::2]:$ts1p,bind=$ts1a" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" >"${tf}" & pid1="$!" waitudp6port $ts1p 1 echo "$da" |$CMD2 2>>"${te}2" rc2="$?" usleep $MICROS kill "$pid1" 2>/dev/null; wait; if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac N=$((N+1)) fi # false NAME=UDP4MULTICAST_BIDIR case "$TESTS" in *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%multicast%*|*%$NAME%*) TEST="$NAME: UDP/IPv4 multicast, with reply" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) ts1a="$SECONDADDR" ts1="$ts1a:$ts1p" ts2p=$PORT; PORT=$((PORT+1)) ts2="$BCIFADDR:$ts2p" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE" #CMD2="$TRACE $SOCAT $opts - UDP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a" CMD2="$TRACE $SOCAT $opts - UDP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & pid1="$!" waitudp4port $ts1p 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2="$?" kill "$pid1" 2>/dev/null; wait; if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$tut" ]; then echo "$CMD1 &" echo "$CMD2" fi if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) NAME=IP4MULTICAST_BIDIR case "$TESTS" in *%$N%*|*%functions%*|*%rawip%*|*%ip4%*|*%dgram%*|*%multicast%*|*%root%*|*%$NAME%*) TEST="$NAME: IPv4 multicast, with reply" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PROTO ts1a="$SECONDADDR" ts1="$ts1a:$ts1p" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE" #CMD2="$TRACE $SOCAT $opts - IP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a" CMD2="$TRACE $SOCAT $opts - IP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & pid1="$!" waitip4port $ts1p 1 usleep 100000 # give process a chance to add multicast membership echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2="$?" kill "$pid1" 2>/dev/null; wait; if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$tut" ]; then echo "$CMD1 &" echo "$CMD2" fi if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) N=$((N+1)) NAME=TUNREAD case "$TESTS" in *%$N%*|*%functions%*|*%tun%*|*%root%*|*%$NAME%*) TEST="$NAME: reading data sent through tun interface" #idea: create a TUN interface and send a datagram to one of the addresses of # its virtual network. On the tunnel side, read the packet and compare its last # bytes with the datagram payload if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4 tun) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tl="$td/test$N.lock" da="test$N $(date) $RANDOM" dalen=$((${#da}+1)) TUNNET=10.255.255 CMD1="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$TUNNET.2:$PORT" #CMD="$TRACE $SOCAT $opts -u -L $tl TUN,ifaddr=$TUNNET.1,netmask=255.255.255.0,iff-up=1 -" CMD="$TRACE $SOCAT $opts -u -L $tl TUN:$TUNNET.1/24,iff-up=1 -" printf "test $F_n $TEST... " $N $CMD 2>"${te}" |tail -c $dalen >"${tf}" & sleep 1 echo "$da" |$CMD1 2>"${te}1" sleep 1 kill "$(cat $tl 2>/dev/null)" 2>/dev/null wait if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD &" echo "$CMD1" cat "${te}" "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" cat "${te}" "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}" "${te}1"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) # use the INTERFACE address on a tun/tap device and transfer data fully # transparent NAME=TUNINTERFACE case "$TESTS" in *%$N%*|*%functions%*|*%tun%*|*%interface%*|*%root%*|*%$NAME%*) TEST="$NAME: pass data through tun interface using INTERFACE" #idea: create a TUN interface and send a raw packet on the interface side. # It should arrive unmodified on the tunnel side. if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs ip4 tun interface) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tl="$td/test$N.lock" da="$(date) $RANDOM" dalen=$((${#da}+1)) TUNNET=10.255.255 TUNNAME=tun9 CMD1="$TRACE $SOCAT $opts -L $tl TUN:$TUNNET.1/24,iff-up=1,tun-type=tun,tun-name=$TUNNAME echo" CMD="$TRACE $SOCAT $opts - INTERFACE:$TUNNAME" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & pid1="$!" #waitinterface "$TUNNAME" sleep 1 echo "$da" |$CMD 2>"${te}1" >"$tf" 2>"${te}" kill $pid1 2>/dev/null wait if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD &" echo "$CMD1" cat "${te}" "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" cat "${te}" "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}" "${te}1"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) NAME=ABSTRACTSTREAM case "$TESTS" in *%$N%*|*%functions%*|*%unix%*|*%abstract%*|*%connect%*|*%listen%*|*%$NAME%*) TEST="$NAME: abstract UNIX stream socket, listen and connect" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ts="$td/test$N.socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da1="test$N $(date) $RANDOM" #establish a listening abstract unix socket SRV="$TRACE $SOCAT $opts -lpserver ABSTRACT-LISTEN:\"$ts\" PIPE" #make a connection CMD="$TRACE $SOCAT $opts - ABSTRACT-CONNECT:$ts" $PRINTF "test $F_n $TEST... " $N touch "$ts" # make a file with same name, so non-abstract fails eval "$SRV 2>${te}s &" pids=$! #waitfile "$ts" sleep 1 echo "$da1" |eval "$CMD" >"${tf}1" 2>"${te}1" if [ $? -ne 0 ]; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" echo "$SRV &" cat "${te}s" echo "$CMD" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" echo "$SRV &" cat "${te}s" echo "$CMD" cat "${te}1" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi # !(rc -ne 0) wait fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=ABSTRACTDGRAM case "$TESTS" in *%$N%*|*%functions%*|*%unix%*|*%abstract%*|*%dgram%*|*%$NAME%*) TEST="$NAME: abstract UNIX datagram" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1="$td/test$N.socket1" ts2="$td/test$N.socket2" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts ABSTRACT-RECVFROM:$ts1,reuseaddr PIPE" #CMD2="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2" CMD2="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2" printf "test $F_n $TEST... " $N touch "$ts1" # make a file with same name, so non-abstract fails $CMD1 2>"${te}1" & pid1="$!" sleep 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? kill "$pid1" 2>/dev/null; wait if [ $rc2 -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" cat "${te}1" echo "$CMD2" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac N=$((N+1)) NAME=ABSTRACTRECV case "$TESTS" in *%$N%*|*%functions%*|*%unix%*|*%abstract%*|*%dgram%*|*%recv%*|*%$NAME%*) TEST="$NAME: abstract UNIX datagram receive" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else ts="$td/test$N.socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1="$ts" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -u ABSTRACT-RECV:$ts1,reuseaddr -" CMD2="$TRACE $SOCAT $opts -u - ABSTRACT-SENDTO:$ts1" printf "test $F_n $TEST... " $N touch "$ts1" # make a file with same name, so non-abstract fails $CMD1 >"$tf" 2>"${te}1" & pid1="$!" #waitfile $ts1 1 sleep 1 echo "$da" |$CMD2 2>>"${te}2" rc2="$?" i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done kill "$pid1" 2>/dev/null; wait if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac N=$((N+1)) # bind with Linux abstract UNIX domain addresses bound to filesystem socket # instead of abstract namespace NAME=ABSTRACT_BIND case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%abstract%*|*%$NAME%*) TEST="$NAME: abstract bind" # open an abstract client address with bind option, bind to the target socket. # send a datagram. # when socat outputs the datagram it got the test succeeded if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1="$td/test$N.sock1" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts1" printf "test $F_n $TEST... " $N echo "$da" |$CMD1 >$tf 2>"${te}1" rc1=$? if [ $rc1 -ne 0 ]; then $PRINTF "$FAILED\n" echo "$CMD1" >&2 echo "rc=$rc1" >&2 cat "${te}1" >&2 numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif echo "$da" |diff -q - $tf; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD1" >&2 cat "${te}1" >&2 echo "$da" |diff - "$tf" >&2 numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) NAME=OPENSSLREAD # socat determined availability of data using select(). With openssl, the # following situation might occur: # a SSL data block with more than 8192 bytes (socats default blocksize) # arrives; socat calls SSL_read, and the SSL routine reads the complete block. # socat then reads 8192 bytes from the SSL layer, the rest remains buffered. # If the TCP connection stays idle for some time, the data in the SSL layer # keeps there and is not transferred by socat until the socket indicates more # data or EOF. case "$TESTS" in *%$N%*|*%functions%*|*%openssl%*|*%$NAME%*) TEST="$NAME: socat handles data buffered by openssl" #idea: have a socat process (server) that gets an SSL block that is larger than # socat transfer block size; keep the socket connection open and kill the # server process after a short time; if not the whole data block has been # transferred, the test has failed. if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs openssl) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.out" te="$td/test$N.err" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" SRVCERT=testsrv gentestcert "$SRVCERT" CMD1="$TRACE $SOCAT $opts -u -T 1 -b $($ECHO "$da\c" |wc -c) OPENSSL-LISTEN:$PORT,reuseaddr,cert=$SRVCERT.pem,verify=0 -" CMD2="$TRACE $SOCAT $opts -u - OPENSSL-CONNECT:$LOCALHOST:$PORT,verify=0" printf "test $F_n $TEST... " $N # $CMD1 2>"${te}1" >"$tf" & pid=$! # background process id waittcp4port $PORT (echo "$da"; sleep 2) |$CMD2 2>"${te}2" kill "$pid" 2>/dev/null; wait if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1" cat "${te}1" echo "$CMD2" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi wait fi # NUMCOND, featsesac ;; esac N=$((N+1)) # test: there is a bug with the readbytes option: when the socket delivered # exacly that many bytes as specified with readbytes and the stays idle (no # more data, no EOF), socat waits for more data instead of generating EOF on # this in put stream. NAME=READBYTES_EOF #set -vx case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: trigger EOF after that many bytes, even when socket idle" #idea: we deliver that many bytes to socat; the process should terminate then. # we try to transfer data in the other direction then; if transfer succeeds, # the process did not terminate and the bug is still there. if ! eval $NUMCOND; then :; elif false; then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tr="$td/test$N.ref" ti="$td/test$N.in" to="$td/test$N.out" te="$td/test$N.err" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" CMD="$TRACE $SOCAT $opts SYSTEM:\"echo A; sleep $((2*SECONDs))\",readbytes=2!!- -!!/dev/null" printf "test $F_n $TEST... " $N (usleep $((2*MICROS)); echo) |eval "$CMD" >"$to" 2>"$te" if test -s "$to"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, feats esac N=$((N+1)) # test: there was a bug with exec:...,pty that did not kill the exec'd sub # process under some circumstances. NAME=EXECPTYKILL case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%$NAME%*) TEST="$NAME: exec:...,pty explicitely kills sub process" # we want to check if the exec'd sub process is killed in time # for this we have a shell script that generates a file after two seconds; # it should be killed after one second, so if the file was generated the test # has failed if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" ts="$td/test$N.sock" tda="$td/test$N.data" tsh="$td/test$N.sh" tdiff="$td/test$N.diff" cat >"$tsh" <"${te}2" & pid1=$! sleep $SECONDs waitfile $ts $SECONDs $CMD 2>>"${te}1" >>"$tf" sleep $((2*SECONDs)) kill "$pid1" 2>/dev/null wait if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif [ -f "$tda" ]; then $PRINTF "$FAILED\n" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) # test if service name resolution works; this was buggy in 1.5 and 1.6.0.0 NAME=TCP4SERVICE case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: echo via connection to TCP V4 socket" # select a tcp entry from /etc/services, have a server listen on the port # number and connect using the service name; with the bug, connection will to a # wrong port if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" # find a service entry we do not need root for (>=1024; here >=1100 for ease) SERVENT="$(grep '^[a-z][a-z]*[^!-~][^!-~]*[1-9][1-9][0-9][0-9]/tcp' /etc/services |head -n 1)" SERVICE="$(echo $SERVENT |cut -d' ' -f1)" _PORT="$PORT" PORT="$(echo $SERVENT |sed 's/.* \([1-9][0-9]*\).*/\1/')" tsl="$PORT" ts="127.0.0.1:$SERVICE" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1=$! waittcp4port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" cat "${te}1" echo "$CMD2" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid1 2>/dev/null wait PORT="$_PORT" fi ;; # NUMCOND esac N=$((N+1)) # test: up to socat 1.6.0.0, the highest file descriptor supported in socats # transfer engine was FOPEN_MAX-1; this usually worked fine but would fail when # socat was invoked with many file descriptors already opened. socat would # just hang in the select() call. Thanks to Daniel Lucq for reporting this # problem. # FOPEN_MAX on different OS's: # OS FOPEN_ ulimit ulimit FD_ # MAX -H -n -S -n SETSIZE # Linux 2.6: 16 1024 1024 1024 # HP-UX 11.11: 60 2048 2048 2048 # FreeBSD: 20 11095 11095 1024 # Cygwin: 20 unlimit 256 64 # AIX: 32767 65534 65534 # SunOS 8: 20 1024 NAME=EXCEED_FOPEN_MAX case "$TESTS" in *%$N%*|*%functions%*|*%maxfds%*|*%$NAME%*) TEST="$NAME: more than FOPEN_MAX FDs in use" # this test opens a number of FDs before socat is invoked. socat will have to # allocate higher FD numbers and thus hang if it cannot handle them. if ! eval $NUMCOND; then :; else REDIR= #set -vx FOPEN_MAX=$($PROCAN -c 2>/dev/null |grep '^#define[ ][ ]*FOPEN_MAX' |awk '{print($3);}') if [ -z "$FOPEN_MAX" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}could not determine FOPEN_MAX${NORMAL}\n" "$N" numCANT=$((numCANT+1)) else OPEN_FILES=$FOPEN_MAX # more than the highest FOPEN_MAX i=3; while [ "$i" -lt "$OPEN_FILES" ]; do REDIR="$REDIR $i>&2" i=$((i+1)) done #echo "$REDIR" #testecho "$N" "$TEST" "" "pipe" "$opts -T 3" "" 1 #set -vx eval testecho "\"$N\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T $((2*SECONDs))\"" 1 $REDIR #set +vx fi # could determine FOPEN_MAX fi ;; # NUMCOND esac N=$((N+1)) # there was a bug with udp-listen and fork: terminating sub processes became # zombies because the master process did not catch SIGCHLD NAME=UDP4LISTEN_SIGCHLD case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%zombie%*|*%signal%*|*%$NAME%*) TEST="$NAME: test if UDP4-LISTEN child becomes zombie" # idea: run a udp-listen process with fork and -T. Connect once, so a sub # process is forked off. Make some transfer and wait until the -T timeout is # over. Now check for the child process: if it is zombie the test failed. # Correct is that child process terminated if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="$LOCALHOST:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -T 0.5 UDP4-LISTEN:$tsl,reuseaddr,fork PIPE" CMD2="$TRACE $SOCAT $opts - UDP4:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1=$! waitudp4port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? sleep 1 #read -p ">" l="$(childprocess $pid1)" kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then $PRINTF "$NO_RESULT (client failed)\n" # already handled in test UDP4STREAM numCANT=$((numCANT+1)) elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$NO_RESULT (diff failed)\n" # already handled in test UDP4STREAM numCANT=$((numCANT+1)) elif $(isdefunct "$l"); then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) #set +vx # there was a bug with udp-recvfrom and fork: terminating sub processes became # zombies because the master process caught SIGCHLD but did not wait() NAME=UDP4RECVFROM_SIGCHLD case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%udp%*|*%dgram%*|*%zombie%*|*%signal%*|*%$NAME%*) TEST="$NAME: test if UDP4-RECVFROM child becomes zombie" # idea: run a udp-recvfrom process with fork and -T. Send it one packet, so a # sub process is forked off. Make some transfer and wait until the -T timeout # is over. Now check for the child process: if it is zombie the test failed. # Correct is that child process terminated if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="$LOCALHOST:$tsl" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -T 0.5 UDP4-RECVFROM:$tsl,reuseaddr,fork PIPE" CMD2="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1=$! waitudp4port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? sleep 1 #read -p ">" l="$(childprocess $pid1)" kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM numCANT=$((numCANT+1)) elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM numCANT=$((numCANT+1)) elif $(isdefunct "$l"); then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) # test: there was a bug with ip*-recv and bind option: it would not bind, and # with the first received packet an error: # socket_init(): unknown address family 0 # occurred NAME=RAWIP4RECVBIND case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%dgram%*|*%rawip%*|*%rawip4%*|*%recv%*|*%root%*|*%$NAME%*) TEST="$NAME: raw IPv4 receive with bind" # idea: start a socat process with ip4-recv:...,bind=... and send it a packet # if the packet passes the test succeeded if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PROTO; PROTO=$((PROTO+1)) ts1a="127.0.0.1" ts1="$ts1a:$ts1p" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -u IP4-RECV:$ts1p,bind=$ts1a,reuseaddr -" CMD2="$TRACE $SOCAT $opts -u - IP4-SENDTO:$ts1" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1="$!" waitip4proto $ts1p 1 echo "$da" |$CMD2 2>>"${te}2" rc2="$?" #ls -l $tf i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done kill "$pid1" 2>/dev/null; wait if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND, root esac PROTO=$((PROTO+1)) N=$((N+1)) # there was a bug in *-recvfrom with fork: due to an error in the appropriate # signal handler the master process would hang after forking off the first # child process. NAME=UDP4RECVFROM_FORK case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) TEST="$NAME: test if UDP4-RECVFROM handles more than one packet" # idea: run a UDP4-RECVFROM process with fork and -T. Send it one packet; # send it a second packet and check if this is processed properly. If yes, the # test succeeded. if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsp=$PORT ts="$LOCALHOST:$tsp" da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -T 2 UDP4-RECVFROM:$tsp,reuseaddr,fork PIPE" CMD2="$TRACE $SOCAT $opts -T 1 - UDP4-SENDTO:$ts" printf "test $F_n $TEST... " $N $CMD1 >/dev/null 2>"${te}1" & pid1=$! waitudp4port $tsp 1 echo "$da" |$CMD2 >/dev/null 2>>"${te}2" # this should always work rc2a=$? sleep 1 echo "$da" |$CMD2 >"$tf" 2>>"${te}3" # this would fail when bug rc2b=$? kill $pid1 2>/dev/null; wait if [ $rc2b -ne 0 ]; then $PRINTF "$NO_RESULT\n" numCANT=$((numCANT+1)) elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" "${te}3" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) # there was a bug in parsing the arguments of exec: consecutive spaces resulted # in additional empty arguments NAME=EXECSPACES case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%parse%*|*%$NAME%*) TEST="$NAME: correctly parse exec with consecutive spaces" if ! eval $NUMCOND; then :; else $PRINTF "test $F_n $TEST... " $N tf="$td/test$N.stdout" te="$td/test$N.stderr" da="test$N $(date) $RANDOM" # with a double space tdiff="$td/test$N.diff" # put the test data as first argument after two spaces. expect the data in the # first argument of the exec'd command. $TRACE $SOCAT $opts -u "exec:\"bash -c \\\"echo \\\\\\\"\$1\\\\\\\"\\\" \\\"\\\" \\\"$da\\\"\"" - >"$tf" 2>"$te" rc=$? echo "$da" |diff - "$tf" >"$tdiff" if [ "$rc" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif [ -s "$tdiff" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo diff: cat "$tdiff" if [ -n "$debug" ]; then cat $te; fi numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) # a bug was found in the way UDP-LISTEN handles the listening socket: # when UDP-LISTEN continued to listen after a packet had been dropped by, e.g., # range option, the old listen socket would not be closed but a new one created. NAME=UDP4LISTENCONT case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%ip4%*|*%udp%*|*%$NAME%*) TEST="$NAME: let range drop a packet and see if old socket is closed" # idea: run a UDP4-LISTEN process with range option. Send it one packet from an # address outside range and check if two listening sockets are open then if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" while [ "$(netstat -an |grep "^udp.*127.0.0.1:$PORT" |wc -l)" -ne 0 ]; do PORT=$((PORT+1)) done tp=$PORT da1="test$N $(date) $RANDOM" a1="$LOCALHOST" a2="$SECONDADDR" #CMD0="$TRACE $SOCAT $opts UDP4-LISTEN:$tp,bind=$a1,range=$a2/32 PIPE" CMD0="$TRACE $SOCAT $opts UDP4-LISTEN:$tp,range=$a2/32 PIPE" CMD1="$TRACE $SOCAT $opts - UDP-CONNECT:$a1:$tp" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & pid1=$! waitudp4port $tp 1 echo "$da1" |$CMD1 >"${tf}1" 2>"${te}1" # this should fail rc1=$? waitudp4port $tp 1 nsocks="$(netstat -an |grep "^udp.*[:.]$PORT" |wc -l)" kill $pid1 2>/dev/null; wait if [ $rc1 -ne 0 ]; then $PRINTF "$NO_RESULT\n" numCANT=$((numCANT+1)) elif [ $nsocks -eq 0 ]; then $PRINTF "$NO_RESULT\n" numCANT=$((numCANT+1)) elif [ $nsocks -ne 1 ]; then $PRINTF "$FAILED ($nsocks listening sockets)\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) # during wait for next poll time option ignoreeof blocked the data transfer in # the reverse direction NAME=IGNOREEOFNOBLOCK case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%socket%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof does not block other direction" # have socat poll in ignoreeof mode. while it waits one second for next check, # we send data in the reverse direction and then the total timeout fires. # it the data has passed, the test succeeded. if ! eval $NUMCOND; then :; else tf="$td/test$N.stout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts /dev/null,ignoreeof!!- -!!/dev/null" printf "test $F_n $TEST... " $N (usleep 333333; echo "$da") |$CMD0 >"$tf" 2>"${te}0" rc0=$? if [ $rc0 != 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif echo "$da" |diff - "$tf" >/dev/null; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi ;; # NUMCOND esac N=$((N+1)) # test the escape option NAME=ESCAPE case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%escape%*|*%$NAME%*) TEST="$NAME: escape character triggers EOF" # idea: start socat just echoing input, but apply escape option. send a string # containing the escape character and check if the output is truncated if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD="$TRACE $SOCAT $opts -,escape=27 pipe" printf "test $F_n $TEST... " $N $ECHO "$da\n\x1bXYZ" |$CMD >"$tf" 2>"$te" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) # test the escape option combined with ignoreeof NAME=ESCAPE_IGNOREEOF case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%escape%*|*%$NAME%*) TEST="$NAME: escape character triggers EOF" # idea: start socat just echoing input, but apply escape option. send a string # containing the escape character and check if the output is truncated if ! eval $NUMCOND; then :; else ti="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD="$TRACE $SOCAT -T 5 $opts file:$ti,ignoreeof,escape=27!!- pipe" printf "test $F_n $TEST... " $N >"$ti" $CMD >"$tf" 2>"$te" & $ECHO "$da\n\x1bXYZ" >>"$ti" sleep 1 if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" cat "$te" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) # test: logging of ancillary message while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_TYPE SCM_NAME ROOT SCM_VALUE do if [ -z "$PF" ] || [[ "$PF" == \#* ]]; then continue; fi # pf="$(echo "$PF" |tr A-Z a-z)" proto="$(echo "$KEYW" |tr A-Z a-z)" NAME=${KEYW}SCM_$SCM_TYPE case "$TESTS" in *%$N%*|*%functions%*|*%$pf%*|*%dgram%*|*%udp%*|*%$proto%*|*%recv%*|*%ancillary%*|*%$ROOT%*|*%$NAME%*) TEST="$NAME: $KEYW log ancillary message $SCM_TYPE $SCM_NAME" # idea: start a socat process with *-RECV:..,... , ev. with ancillary message # enabling option and send it a packet, ev. with some option. check the info log # for the appropriate output. if ! eval $NUMCOND; then :; #elif [[ "$PF" == "#*" ]]; then : elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ "$PF" = "IP6" ] && ( ! feat=$(testaddrs ip6) || ! runsip6 >/dev/null ); then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testoptions $SCM_RECV >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}option $SCM_RECV not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" case "X$IPPORT" in "XPORT") tra="$PORT" # test recv address tsa="$ADDR:$PORT" # test sendto address PORT=$((PORT+1)) ;; "XPROTO") tra="$PROTO" # test recv address tsa="$ADDR:$PROTO" # test sendto address PROTO=$((PROTO+1)) ;; *) tra="$(eval echo "$ADDR")" # resolve $N tsa="$tra" esac CMD0="$TRACE $SOCAT $opts -d -d -d -u $KEYW-RECV:$tra,reuseaddr,$SCM_RECV -" CMD1="$TRACE $SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE" printf "test $F_n $TEST... " $N # is this option supported? if $TRACE $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then $CMD0 >"$tf" 2>"${te}0" & pid0="$!" wait${proto}port $tra 1 echo "XYZ" |$CMD1 2>"${te}1" rc1="$?" sleep 1 i=0; while [ ! -s "${te}0" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done kill "$pid0" 2>/dev/null; wait # do not show more messages than requested case "$opts" in *-d*-d*-d*-d*) LEVELS="[EWNID]" ;; *-d*-d*-d*) LEVELS="[EWNI]" ;; *-d*-d*) LEVELS="[EWN]" ;; *-d*) LEVELS="[EW]" ;; *) LEVELS="[E]" ;; esac if [ "$SCM_VALUE" = "timestamp" ]; then SCM_VALUE="$(date '+%a %b %e %H:%M:.. %Y')" fi if [ "$rc1" -ne 0 ]; then $PRINTF "$NO_RESULT: $TRACE $SOCAT:\n" echo "$CMD0 &" echo "$CMD1" grep " $LEVELS " "${te}0" grep " $LEVELS " "${te}1" numCANT=$((numCANT+1)) elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=" ${te}0 >/dev/null; then $PRINTF "$FAILED\n" echo "variable $SCM_TYPE: $SCM_NAME not set" echo "$CMD0 &" echo "$CMD1" grep " $LEVELS " "${te}0" grep " $LEVELS " "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE" ${te}0 >/dev/null; then $PRINTF "$FAILED\n" badval="$(grep "ancillary message: $SCM_TYPE: $SCM_NAME" ${te}0 |sed 's/.*=//g')" echo "variable $SCM_TYPE: $SCM_NAME has value \"$badval\" instead of pattern \"$SCM_VALUE\"" >&2 echo "$CMD0 &" echo "$CMD1" grep " $LEVELS " "${te}0" grep " $LEVELS " "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then grep " $LEVELS " "${te}0"; echo; grep " $LEVELS " "${te}1"; fi numOK=$((numOK+1)) fi #set +vx else # option is not supported $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n" numCANT=$((numCANT+1)) fi # option is not supported fi # NUMCOND, root, feats ;; esac N=$((N+1)) # done <<<" IP4 UDP4 127.0.0.1 PORT ip-options=x01000000 ip-recvopts IP_OPTIONS options user x01000000 IP4 UDP4 127.0.0.1 PORT , so-timestamp SCM_TIMESTAMP timestamp user timestamp IP4 UDP4 127.0.0.1 PORT ip-ttl=53 ip-recvttl IP_TTL ttl user 53 IP4 UDP4 127.0.0.1 PORT ip-tos=7 ip-recvtos IP_TOS tos user 7 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO locaddr user 127.0.0.1 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO dstaddr user 127.0.0.1 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO if user lo IP4 UDP4 127.0.0.1 PORT , ip-recvif IP_RECVIF if user lo0 IP4 UDP4 127.0.0.1 PORT , ip-recvdstaddr IP_RECVDSTADDR dstaddr user 127.0.0.1 IP4 IP4 127.0.0.1 PROTO ip-options=x01000000 ip-recvopts IP_OPTIONS options root x01000000 IP4 IP4 127.0.0.1 PROTO , so-timestamp SCM_TIMESTAMP timestamp root timestamp IP4 IP4 127.0.0.1 PROTO ip-ttl=53 ip-recvttl IP_TTL ttl root 53 IP4 IP4 127.0.0.1 PROTO ip-tos=7 ip-recvtos IP_TOS tos root 7 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO locaddr root 127.0.0.1 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO dstaddr root 127.0.0.1 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO if root lo IP4 IP4 127.0.0.1 PROTO , ip-recvif IP_RECVIF if root lo0 IP4 IP4 127.0.0.1 PROTO , ip-recvdstaddr IP_RECVDSTADDR dstaddr root 127.0.0.1 IP6 UDP6 [::1] PORT , so-timestamp SCM_TIMESTAMP timestamp user timestamp IP6 UDP6 [::1] PORT , ipv6-recvpktinfo IPV6_PKTINFO dstaddr user [[]0000:0000:0000:0000:0000:0000:0000:0001[]] IP6 UDP6 [::1] PORT ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT hoplimit user 35 IP6 UDP6 [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS tclass user xaa000000 IP6 IP6 [::1] PROTO , so-timestamp SCM_TIMESTAMP timestamp root timestamp IP6 IP6 [::1] PROTO , ipv6-recvpktinfo IPV6_PKTINFO dstaddr root [[]0000:0000:0000:0000:0000:0000:0000:0001[]] IP6 IP6 [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT hoplimit root 35 IP6 IP6 [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS tclass root xaa000000 #UNIX UNIX $td/test\$N.server - , so-timestamp SCM_TIMESTAMP timestamp user timestamp " # this one fails, appearently due to a Linux weakness: # UNIX so-timestamp # test: setting of environment variables that describe a stream socket # connection: SOCAT_SOCKADDR, SOCAT_PEERADDR; and SOCAT_SOCKPORT, # SOCAT_PEERPORT when applicable while read KEYW FEAT TEST_SOCKADDR TEST_PEERADDR TEST_SOCKPORT TEST_PEERPORT; do if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi # test_proto="$(echo "$KEYW" |tr A-Z a-z)" NAME=${KEYW}LISTENENV case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$test_proto%*|*%envvar%*|*%$NAME%*) TEST="$NAME: $KEYW-LISTEN sets environment variables with socket addresses" # have a server accepting a connection and invoking some shell code. The shell # code extracts and prints the SOCAT related environment vars. # outside code then checks if the environment contains the variables correctly # describing the peer and local sockets. if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs $FEAT); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ "$KEYW" = "TCP6" -o "$KEYW" = "UDP6" -o "$KEYW" = "SCTP6" ] && \ ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ "$KEYW" = "SCTP4" ] && ! runssctp4 "$((PORT))"; then $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not available${NORMAL}\n" $N elif [ "$KEYW" = "SCTP6" ] && ! runssctp4 "$((PORT))"; then #!!! branch not reached - caught above! $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not available${NORMAL}\n" $N else tf="$td/test$N.stdout" te="$td/test$N.stderr" TEST_SOCKADDR="$(echo "$TEST_SOCKADDR" |sed "s/\$N/$N/g")" # actual vars tsa="$TEST_SOCKADDR" # test server address tsp="$TEST_SOCKPORT" # test server port if [ "$tsp" != ',' ]; then tsa1="$tsp"; tsa2="$tsa"; tsa="$tsa:$tsp" # tsa2 used for server bind= else tsa1="$tsa"; tsa2= # tsa1 used for addr parameter fi TEST_PEERADDR="$(echo "$TEST_PEERADDR" |sed "s/\$N/$N/g")" # actual vars tca="$TEST_PEERADDR" # test client address tcp="$TEST_PEERPORT" # test client port if [ "$tcp" != ',' ]; then tca="$tca:$tcp" fi #CMD0="$TRACE $SOCAT $opts -u $KEYW-LISTEN:$tsa1 SYSTEM:\"export -p\"" CMD0="$TRACE $SOCAT $opts -u -lpsocat $KEYW-LISTEN:$tsa1 SYSTEM:\"echo SOCAT_SOCKADDR=\\\$SOCAT_SOCKADDR; echo SOCAT_PEERADDR=\\\$SOCAT_PEERADDR; echo SOCAT_SOCKPORT=\\\$SOCAT_SOCKPORT; echo SOCAT_PEERPORT=\\\$SOCAT_PEERPORT; sleep 1\"" CMD1="$TRACE $SOCAT $opts -u - $KEYW-CONNECT:$tsa,bind=$tca" printf "test $F_n $TEST... " $N eval "$CMD0 2>\"${te}0\" >\"$tf\" &" pid0=$! wait${test_proto}port $tsa1 1 echo |$CMD1 2>"${te}1" rc1=$? waitfile "$tf" 2 kill $pid0 2>/dev/null; wait #set -vx if [ $rc1 != 0 ]; then $PRINTF "$NO_RESULT (client failed):\n" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numCANT=$((numCANT+1)) elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")" = "$TEST_SOCKADDR" -a \ "$(grep SOCAT_PEERADDR "${tf}" |sed -e 's/^[^=]*=//' -e "s/[\"']//g")" = "$TEST_PEERADDR" -a \ \( "$TEST_SOCKPORT" = ',' -o "$(grep SOCAT_SOCKPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$tsp" \) -a \ \( "$TEST_PEERPORT" = ',' -o "$(grep SOCAT_PEERPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$tcp" \) \ ]; then $PRINTF "$OK\n" if [ "$debug" ]; then echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" fi numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" echo -e "SOCAT_SOCKADDR=$TEST_SOCKADDR\nSOCAT_PEERADDR=$TEST_PEERADDR\nSOCAT_SOCKPORT=$TEST_SOCKPORT\nSOCAT_PEERPORT=$TEST_PEERPORT" | diff - "${tf}" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND, feats ;; esac N=$((N+1)) #set +xv # done <<<" TCP4 TCP 127.0.0.1 $SECONDADDR $PORT $((PORT+1)) TCP6 IP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+2)) $((PORT+3)) UDP6 IP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+6)) $((PORT+7)) SCTP4 SCTP 127.0.0.1 $SECONDADDR $((PORT+8)) $((PORT+9)) SCTP6 SCTP [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+10)) $((PORT+11)) UNIX UNIX $td/test\$N.server $td/test\$N.client , , " # this one fails due to weakness in socats UDP4-LISTEN implementation: #UDP4 $LOCALHOST $SECONDADDR $((PORT+4)) $((PORT+5)) # test: environment variables from ancillary message while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_ENVNAME ROOT SCM_VALUE do if [ -z "$PF" ] || [[ "$PF" == \#* ]]; then continue; fi # pf="$(echo "$PF" |tr A-Z a-z)" proto="$(echo "$KEYW" |tr A-Z a-z)" NAME=${KEYW}ENV_$SCM_ENVNAME case "$TESTS" in *%$N%*|*%functions%*|*%$pf%*|*%dgram%*|*%udp%*|*%$proto%*|*%recv%*|*%ancillary%*|*%envvar%*|*%$ROOT%*|*%$NAME%*) #set -vx TEST="$NAME: $KEYW ancillary message sets env SOCAT_$SCM_ENVNAME" # idea: start a socat process with *-RECVFROM:..,... , ev. with ancillary # message enabling option and send it a packet, ev. with some option. write # the resulting environment to a file and check its contents for the # appropriate variable. if ! eval $NUMCOND; then :; elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ "$PF" = "IP6" ] && ( ! feat=$(testaddrs ip6) || ! runsip6 ) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" case "X$IPPORT" in "XPORT") tra="$PORT" # test recv address tsa="$ADDR:$PORT" # test sendto address PORT=$((PORT+1)) ;; "XPROTO") tra="$PROTO" # test recv address tsa="$ADDR:$PROTO" # test sendto address PROTO=$((PROTO+1)) ;; *) tra="$(eval echo "$ADDR")" # resolve $N tsa="$tra" esac #CMD0="$TRACE $SOCAT $opts -u $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV SYSTEM:\"export -p\"" CMD0="$TRACE $SOCAT $opts -u -lpsocat $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV SYSTEM:\"echo \\\$SOCAT_$SCM_ENVNAME\"" CMD1="$TRACE $SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE" printf "test $F_n $TEST... " $N # is this option supported? if $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then eval "$CMD0 >\"$tf\" 2>\"${te}0\" &" pid0="$!" wait${proto}port $tra 1 echo "XYZ" |$CMD1 2>"${te}1" rc1="$?" waitfile "$tf" 2 #i=0; while [ ! -s "${te}0" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done kill "$pid0" 2>/dev/null; wait # do not show more messages than requested if [ "$SCM_VALUE" = "timestamp" ]; then SCM_VALUE="$(date '+%a %b %e %H:%M:.. %Y'), ...... usecs" fi if [ "$rc1" -ne 0 ]; then $PRINTF "$NO_RESULT: $SOCAT:\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" numCANT=$((numCANT+1)) #elif ! egrep "^export SOCAT_$SCM_ENVNAME=[\"']?$SCM_VALUE[\"']?\$" ${tf} >/dev/null; then #elif ! eval echo "$TRACE $SOCAT_\$SCM_VALUE" |diff - "${tf}" >/dev/null; then elif ! expr "$(cat "$tf")" : "$(eval echo "\$SCM_VALUE")" >/dev/null; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0"; echo; cat "${te}1"; fi numOK=$((numOK+1)) fi else # option is not supported $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n" numCANT=$((numCANT+1)) fi # option is not supported fi ;; # NUMCOND, feats esac N=$((N+1)) # done <<<" IP4 UDP4 127.0.0.1 PORT ip-options=x01000000 ip-recvopts IP_OPTIONS user x01000000 IP4 UDP4 127.0.0.1 PORT , so-timestamp TIMESTAMP user timestamp IP4 UDP4 127.0.0.1 PORT ip-ttl=53 ip-recvttl IP_TTL user 53 IP4 UDP4 127.0.0.1 PORT ip-tos=7 ip-recvtos IP_TOS user 7 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_LOCADDR user 127.0.0.1 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_DSTADDR user 127.0.0.1 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_IF user lo IP4 UDP4 127.0.0.1 PORT , ip-recvif IP_IF user lo0 IP4 UDP4 127.0.0.1 PORT , ip-recvdstaddr IP_DSTADDR user 127.0.0.1 IP4 IP4 127.0.0.1 PROTO ip-options=x01000000 ip-recvopts IP_OPTIONS root x01000000 IP4 IP4 127.0.0.1 PROTO , so-timestamp TIMESTAMP root timestamp IP4 IP4 127.0.0.1 PROTO ip-ttl=53 ip-recvttl IP_TTL root 53 IP4 IP4 127.0.0.1 PROTO ip-tos=7 ip-recvtos IP_TOS root 7 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_LOCADDR root 127.0.0.1 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_DSTADDR root 127.0.0.1 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_IF root lo IP4 IP4 127.0.0.1 PROTO , ip-recvif IP_IF root lo0 IP4 IP4 127.0.0.1 PROTO , ip-recvdstaddr IP_DSTADDR root 127.0.0.1 IP6 UDP6 [::1] PORT , ipv6-recvpktinfo IPV6_DSTADDR user [[]0000:0000:0000:0000:0000:0000:0000:0001[]] IP6 UDP6 [::1] PORT ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT user 35 IP6 UDP6 [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS user xaa000000 IP6 IP6 [::1] PROTO , ipv6-recvpktinfo IPV6_DSTADDR root [[]0000:0000:0000:0000:0000:0000:0000:0001[]] IP6 IP6 [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT root 35 IP6 IP6 [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS root xaa000000 #UNIX UNIX $td/test\$N.server - , so-timestamp TIMESTAMP user timestamp " # test the SOCKET-CONNECT address (against TCP4-LISTEN) NAME=SOCKET_CONNECT_TCP4 case "$TESTS" in *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%$NAME%*) TEST="$NAME: socket connect with TCP/IPv4" # start a TCP4-LISTEN process that echoes data, and send test data using # SOCKET-CONNECT, selecting TCP/IPv4. The sent data should be returned. if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts0p=$PORT; PORT=$((PORT+1)) ts0a="127.0.0.1" ts1p=$(printf "%04x" $ts0p); ts1a="7f000001" # "127.0.0.1" ts1="x${ts1p}${ts1a}x0000000000000000" ts1b=$(printf "%04x" $PORT); PORT=$((PORT+1)) da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$ts0p,reuseaddr,bind=$ts0a PIPE" CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:2:6:$ts1,bind=x${ts1b}00000000x0000000000000000" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" & pid0="$!" waittcp4port $ts0p 1 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" rc1="$?" kill "$pid0" 2>/dev/null; wait; if [ "$rc1" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) PF_INET6="$($PROCAN -c |grep "^#define[[:space:]]*PF_INET6[[:space:]]" |cut -d' ' -f3)" # test the SOCKET-CONNECT address (against TCP6-LISTEN) NAME=SOCKET_CONNECT_TCP6 case "$TESTS" in *%$N%*|*%functions%*|*%generic%*|*%tcp6%*|*%socket%*|*%$NAME%*) TEST="$NAME: socket connect with TCP/IPv6" if ! eval $NUMCOND; then :; elif ! testaddrs tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else # start a TCP6-LISTEN process that echoes data, and send test data using # SOCKET-CONNECT, selecting TCP/IPv6. The sent data should be returned. tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts0p=$PORT; PORT=$((PORT+1)) ts0a="[::1]" ts1p=$(printf "%04x" $ts0p); ts1a="00000000000000000000000000000001" # "[::1]" ts1="x${ts1p}x00000000x${ts1a}x00000000" ts1b=$(printf "%04x" $PORT); PORT=$((PORT+1)) da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts TCP6-LISTEN:$ts0p,reuseaddr,bind=$ts0a PIPE" CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:$PF_INET6:6:$ts1,bind=x${ts1b}x00000000x00000000000000000000000000000000x00000000" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" & pid0="$!" waittcp6port $ts0p 1 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" rc1="$?" kill "$pid0" 2>/dev/null; wait; if [ "$rc1" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) # test the SOCKET-CONNECT address (against UNIX-LISTEN) NAME=SOCKET_CONNECT_UNIX case "$TESTS" in *%$N%*|*%functions%*|*%generic%*|*%unix%*|*%socket%*|*%$NAME%*) TEST="$NAME: socket connect with UNIX domain" # start a UNIX-LISTEN process that echoes data, and send test data using # SOCKET-CONNECT, selecting UNIX socket. The sent data should be returned. if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts0="$td/test$N.server" ts1="$td/test$N.client" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts0,reuseaddr PIPE" CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:1:0:\\\"$ts0\\\0\\\",bind=\\\"$ts1\\\0\\\"" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" & pid0="$!" waitfile $ts0 1 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" rc1="$?" kill "$pid0" 2>/dev/null; wait; if [ "$rc1" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac N=$((N+1)) # test the SOCKET-LISTEN address (with TCP4-CONNECT) NAME=SOCKET_LISTEN case "$TESTS" in *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%$NAME%*) TEST="$NAME: socket recvfrom with TCP/IPv4" # start a SOCKET-LISTEN process that uses TCP/IPv4 and echoes data, and # send test data using TCP4-CONNECT. The sent data should be returned. if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) ts1a="127.0.0.1" ts0p=$(printf "%04x" $ts1p); ts0a="7f000001" # "127.0.0.1" ts0="x${ts0p}${ts0a}x0000000000000000" ts1b=$PORT; PORT=$((PORT+1)) ts1="$ts1a:$ts1p" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts SOCKET-LISTEN:2:6:$ts0,reuseaddr PIPE" CMD1="$TRACE $SOCAT $opts - TCP4-CONNECT:$ts1,bind=:$ts1b" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" & pid0="$!" #sleep 1 waittcp4port $ts1p 1 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" rc1="$?" kill "$pid0" 2>/dev/null; wait; if [ "$rc1" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) SOCK_DGRAM="$($PROCAN -c |grep "^#define[[:space:]]*SOCK_DGRAM[[:space:]]" |cut -d' ' -f3)" # test the SOCKET-SENDTO address (against UDP4-RECVFROM) NAME=SOCKET_SENDTO case "$TESTS" in *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) TEST="$NAME: socket sendto with UDP/IPv4" # start a UDP4-RECVFROM process that echoes data, and send test data using # SOCKET-SENDTO, selecting UDP/IPv4. The sent data should be returned. if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts0p=$PORT; PORT=$((PORT+1)) ts0a="127.0.0.1" ts1p=$(printf "%04x" $ts0p); ts1a="7f000001" # "127.0.0.1" ts1="x${ts1p}${ts1a}x0000000000000000" ts1b=$(printf "%04x" $PORT); PORT=$((PORT+1)) da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts0p,reuseaddr,bind=$ts0a PIPE" CMD1="$TRACE $SOCAT $opts - SOCKET-SENDTO:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" & pid0="$!" waitudp4port $ts0p 1 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" rc1="$?" kill "$pid0" 2>/dev/null; wait; if [ "$rc1" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) # test the SOCKET-RECVFROM address (with UDP4-SENDTO) NAME=SOCKET_RECVFROM case "$TESTS" in *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) TEST="$NAME: socket recvfrom with UDP/IPv4" # start a SOCKET-RECVFROM process that uses UDP/IPv4 and echoes data, and # send test data using UDP4-SENDTO. The sent data should be returned. if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) ts1a="127.0.0.1" ts0p=$(printf "%04x" $ts1p); ts0a="7f000001" # "127.0.0.1" ts0="x${ts0p}${ts0a}x0000000000000000" ts1b=$PORT; PORT=$((PORT+1)) ts1="$ts1a:$ts1p" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts SOCKET-RECVFROM:2:$SOCK_DGRAM:17:$ts0,reuseaddr PIPE" CMD1="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts1,bind=:$ts1b" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" & pid0="$!" sleep 1 # waitudp4port $ts1p 1 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" rc1="$?" kill "$pid0" 2>/dev/null; wait; if [ "$rc1" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) # test the SOCKET-RECV address (with UDP4-SENDTO) NAME=SOCKET_RECV case "$TESTS" in *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) TEST="$NAME: socket recv with UDP/IPv4" # start a SOCKET-RECV process that uses UPD/IPv4 and writes received data to file, and # send test data using UDP4-SENDTO. if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) ts1a="127.0.0.1" ts0p=$(printf "%04x" $ts1p); ts0a="7f000001" # "127.0.0.1" ts0="x${ts0p}${ts0a}x0000000000000000" ts1b=$PORT; PORT=$((PORT+1)) ts1="$ts1a:$ts1p" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts -u SOCKET-RECV:2:$SOCK_DGRAM:17:$ts0,reuseaddr -" CMD1="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$ts1,bind=:$ts1b" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" >"$tf" & pid0="$!" sleep 1 # waitudp4port $ts1p 1 echo "$da" |$CMD1 2>>"${te}1" rc1="$?" sleep 1 kill "$pid0" 2>/dev/null; wait; if [ "$rc1" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) # test SOCKET-DATAGRAM (with UDP4-DATAGRAM) NAME=SOCKET_DATAGRAM case "$TESTS" in *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) TEST="$NAME: socket datagram via UDP/IPv4" # start a UDP4-DATAGRAM process that echoes data, and send test data using # SOCKET-DATAGRAM, selecting UDP/IPv4. The sent data should be returned. if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts0p=$PORT; PORT=$((PORT+1)) ts1p=$PORT; PORT=$((PORT+1)) ts0a="127.0.0.1" ts1b=$(printf "%04x" $ts0p); ts1a="7f000001" # "127.0.0.1" ts0b=$(printf "%04x" $ts0p) ts1b=$(printf "%04x" $ts1p) ts1="x${ts0b}${ts1a}x0000000000000000" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts UDP4-DATAGRAM:$ts0a:$ts1p,bind=:$ts0p,reuseaddr PIPE" CMD1="$TRACE $SOCAT $opts - SOCKET-DATAGRAM:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" & pid0="$!" waitudp4port $ts0p 1 echo "$da" |$CMD1 2>>"${te}1" >"$tf" rc1="$?" kill "$pid0" 2>/dev/null; wait; if [ "$rc1" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) NAME=SOCKETRANGEMASK case "$TESTS" in *%$N%*|*%functions%*|*%security%*|*%generic%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%socket%*|*%range%*|*%$NAME%*) TEST="$NAME: security of generic socket-listen with RANGE option" if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then # we need access to more loopback addresses $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N numCANT=$((numCANT+1)) else ts1p=$(printf "%04x" $PORT); testserversec "$N" "$TEST" "$opts -s" "SOCKET-LISTEN:2:6:x${ts1p}x00000000x0000000000000000,reuseaddr,fork,retry=1" "" "range=x0000x7f000000:x0000xffffffff" "SOCKET-CONNECT:2:6:x${ts1p}x${SECONDADDRHEX}x0000000000000000" 4 tcp $PORT 0 fi ;; # NUMCOND, $SECONDADDR esac PORT=$((PORT+1)) N=$((N+1)) TIOCEXCL="$($PROCAN -c |grep "^#define[[:space:]]*TIOCEXCL[[:space:]]" |cut -d' ' -f3)" # test the generic ioctl-void option NAME=IOCTL_VOID case "$TESTS" in *%$N%*|*%functions%*|*%pty%*|*%generic%*|*%$NAME%*) TEST="$NAME: test the ioctl-void option" # there are not many ioctls that apply to non global resources and do not # require root. TIOCEXCL seems to fit: # process 0 provides a pty; # process 1 opens it with the TIOCEXCL ioctl; # process 2 opens it too and fails with "device or resource busy" only when the # previous ioctl was successful if ! eval $NUMCOND; then :; elif [ -z "$TIOCEXCL" ]; then # we use the numeric value of TIOCEXL which is system dependent $PRINTF "test $F_n $TEST... ${YELLOW}no value of TIOCEXCL${NORMAL}\n" $N numCANT=$((numCANT+1)) else tp="$td/test$N.pty" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts PTY,LINK=$tp pipe" CMD1="$TRACE $SOCAT $opts - file:$tp,ioctl-void=$TIOCEXCL,raw,echo=0" CMD2="$TRACE $SOCAT $opts - file:$tp,raw,echo=0" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & pid0=$! waitfile $tp 1 (echo "$da"; sleep 2) |$CMD1 >"$tf" 2>"${te}1" & # this should always work pid1=$! usleep 1000000 $CMD2 >/dev/null 2>"${te}2" /dev/null; wait if ! echo "$da" |diff - "$tf" >/dev/null; then $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n" echo "$CMD0 &" echo "$CMD1" echo "$da" |diff - "$tf" numCANT=$((numCANT+1)) elif [ $rc2 -eq 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" echo "$CMD1" echo "$CMD2" cat "${te}0" "${te}1" "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi fi # NUMCOND, TIOCEXCL ;; esac N=$((N+1)) SOL_SOCKET="$($PROCAN -c |grep "^#define[[:space:]]*SOL_SOCKET[[:space:]]" |cut -d' ' -f3)" SO_REUSEADDR="$($PROCAN -c |grep "^#define[[:space:]]*SO_REUSEADDR[[:space:]]" |cut -d' ' -f3)" # test the generic setsockopt-int option if false; then # this test no longer works due to fix for options on listening sockets NAME=SETSOCKOPT_INT case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%tcp%*|*%generic%*|*%$NAME%*) TEST="$NAME: test the setsockopt-int option" # there are not many socket options that apply to non global resources, do not # require root, do not require a network connection, and can easily be # tested. SO_REUSEADDR seems to fit: # process 0 provides a tcp listening socket with reuseaddr; # process 1 connects to this port; thus the port is connected but no longer # listening # process 2 tries to listen on this port with SO_REUSEADDR, will fail if the # (generically specified) SO_REUSEADDR socket options did not work # process 3 connects to this port; only if it is successful the test is ok if ! eval $NUMCOND; then :; elif [ -z "SO_REUSEADDR" ]; then # we use the numeric value of SO_REUSEADDR which might be system dependent $PRINTF "test $F_n $TEST... ${YELLOW}value of SO_REUSEADDR not known${NORMAL}\n" $N numCANT=$((numCANT+1)) else tp="$PORT" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts TCP4-L:$tp,setsockopt-int=$SOL_SOCKET:$SO_REUSEADDR:1 PIPE" CMD1="$TRACE $SOCAT $opts - TCP:localhost:$tp" CMD2="$CMD0" CMD3="$CMD1" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & pid0=$! waittcp4port $tp 1 (echo "$da"; sleep 3) |$CMD1 >"$tf" 2>"${te}1" & # this should always work pid1=$! usleep 1000000 $CMD2 >/dev/null 2>"${te}2" & pid2=$! waittcp4port $tp 1 (echo "$da") |$CMD3 >"${tf}3" 2>"${te}3" rc3=$? kill $pid0 $pid1 $pid2 2>/dev/null; wait if ! echo "$da" |diff - "$tf"; then $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n" echo "$CMD0 &" echo "$CMD1" numCANT=$((numCANT+1)) elif [ $rc3 -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD3" cat "${te}2" "${te}3" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "${tf}3"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD3" echo "$da" |diff - "${tf}3" numCANT=$((numCANT+1)) else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi numOK=$((numOK+1)) fi fi # NUMCOND, SO_REUSEADDR ;; esac PORT=$((PORT+1)) N=$((N+1)) # fi NAME=SCTP4STREAM case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%sctp%*|*%$NAME%*) TEST="$NAME: echo via connection to SCTP V4 socket" PORT="$((PORT+1))" if ! eval $NUMCOND; then :; elif ! testaddrs sctp ip4 >/dev/null || ! runsip4 >/dev/null || ! runssctp4 "$((PORT-1))" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then # RHEL5 based systems became unusable when an sctp socket was created but # module sctp not loaded $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" da=$(date) CMD1="$TRACE $SOCAT $opts SCTP4-LISTEN:$tsl,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout SCTP4:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1=$! waitsctp4port $tsl 1 # SCTP does not seem to support half close, so we give it 1s to finish (echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" cat "${te}1" echo "$CMD2" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid1 2>/dev/null wait fi # NUMCOND, feats ;; esac PORT=$((PORT+1)) N=$((N+1)) NAME=SCTP6STREAM case "$TESTS" in *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%sctp%*|*%$NAME%*) TEST="$NAME: echo via connection to SCTP V6 socket" PORT="$((PORT+1))" if ! eval $NUMCOND; then :; elif ! testaddrs sctp ip6 >/dev/null || ! runsip6 >/dev/null || ! runssctp6 "$((PORT-1))" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SCTP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="[::1]:$tsl" da=$(date) CMD1="$TRACE $SOCAT $opts SCTP6-listen:$tsl,reuseaddr PIPE" CMD2="$TRACE $SOCAT $opts stdin!!stdout SCTP6:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid=$! # background process id waitsctp6port $tsl 1 # SCTP does not seem to support half close, so we let it 1s to finish (echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" cat "${te}1" echo "$CMD2" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null fi # NUMCOND, feats ;; esac PORT=$((PORT+1)) N=$((N+1)) # socat up to 1.7.1.1 (and 2.0.0-b3) terminated with error when an openssl peer # performed a renegotiation. Test if this is fixed. NAME=OPENSSLRENEG1 case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%socket%*|*%$NAME%*) TEST="$NAME: OpenSSL connections survive renogotiation" # connect with s_client to socat ssl-l; force a renog, then transfer data. When # data is passed the test succeeded if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE" CMD1="openssl s_client -port $PORT -verify 0" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & pid0=$! waittcp4port $PORT 1 (echo "R"; sleep 1; echo "$da"; sleep 1) |$CMD1 2>"${te}1" |fgrep "$da" >"${tf}1" rc1=$? kill $pid0 2>/dev/null; wait if echo "$da" |diff - ${tf}1 >"$tdiff"; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" # cat "${te}1" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # socat up to 1.7.1.1 (and 2.0.0-b3) terminated with error when an openssl peer # performed a renegotiation. The first temporary fix to this problem might # leave socat in a blocking ssl-read state. Test if this has been fixed. NAME=OPENSSLRENEG2 case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%socket%*|*%$NAME%*) TEST="$NAME: OpenSSL connections do not block after renogotiation" # connect with s_client to socat ssl-l; force a renog, then transfer data from # socat to the peer. When data is passed this means that the former ssl read no # longer blocks and the test succeeds if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,cert=testsrv.crt,key=testsrv.key,verify=0 SYSTEM:\"sleep 1; echo \\\\\\\"\\\"$da\\\"\\\\\\\"; sleep 1\"!!STDIO" CMD1="openssl s_client -port $PORT -verify 0" printf "test $F_n $TEST... " $N eval "$CMD0 >/dev/null 2>\"${te}0\" &" pid0=$! waittcp4port $PORT 1 (echo "R"; sleep 2) |$CMD1 2>"${te}1" |fgrep "$da" >"${tf}1" rc1=$? kill $pid0 2>/dev/null; wait if echo "$da" |diff - ${tf}1 >"$tdiff"; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" # cat "${te}1" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # socat up to 1.7.1.2 had a stack overflow vulnerability that occurred when # command line arguments (whole addresses, host names, file names) were longer # than 512 bytes. NAME=HOSTNAMEOVFL case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%$NAME%*) TEST="$NAME: stack overflow on overly long host name" # provide a long host name to TCP-CONNECT and check socats exit code if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" # prepare long data - perl might not be installed rm -f "$td/test$N.dat" i=0; while [ $i -lt 64 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done CMD0="$TRACE $SOCAT $opts TCP-CONNECT:$(cat "$td/test$N.dat"):$PORT STDIO" printf "test $F_n $TEST... " $N $CMD0 &0 2>"${te}0" rc0=$? if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # socat up to 1.7.1.2 had a stack overflow vulnerability that occurred when # command line arguments (whole addresses, host names, file names) were longer # than 512 bytes. NAME=FILENAMEOVFL case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%openssl%*|*%$NAME%*) TEST="$NAME: stack overflow on overly long file name" # provide a 600 bytes long key file option to SSL-CONNECT and check socats exit code if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" i=0; while [ $i -lt 64 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done CMD0="$TRACE $SOCAT $opts OPENSSL:localhost:$PORT,key=$(cat "$td/test$N.dat") STDIO" printf "test $F_n $TEST... " $N $CMD0 &0 2>"${te}0" rc0=$? if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # socat up to 1.7.3.0 had a stack overflow vulnerability that occurred when # command line arguments (whole addresses, host names, file names) were longer # than 512 bytes and specially crafted. NAME=NESTEDOVFL case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%exec%*|*%$NAME%*) TEST="$NAME: stack overflow on overly long nested arg" # provide a long host name to TCP-CONNECT and check socats exit code if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" # prepare long data - perl might not be installed rm -f "$td/test$N.dat" i=0; while [ $i -lt 64 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done CMD0="$TRACE $SOCAT $opts EXEC:[$(cat "$td/test$N.dat")] STDIO" printf "test $F_n $TEST... " $N $CMD0 &0 2>"${te}0" rc0=$? if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # test for a bug in gopen that lead to crash or warning when opening a unix # domain socket with GOPEN NAME=GOPEN_UNIX_CRASH case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%gopen%*|*%unix%*|*%socket%*|*%$NAME%*) TEST="$NAME: check crash when connecting to a unix domain socket using address GOPEN" # a unix domain server is started in background. the check process connects to # its socket. when this process crashes or issues a warning the bug is present. # please note that a clean behaviour does not proof anything; behaviour of bug # depends on the value of an uninitialized var #set -vx if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" ts="$td/test$N.sock" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts PIPE" CMD1="$TRACE $SOCAT $opts -d - GOPEN:$ts" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" "${tf}1" 2>"${te}1" rc1=$? kill $pid0 2>/dev/null; wait if [ $rc1 -ne 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif grep -q ' W ' "${te}1"; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - ${tf}1 >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" numOK=$((numOK+1)) fi fi # NUMCOND ;; esac N=$((N+1)) # test if socat keeps an existing file where it wanted to create a UNIX socket NAME=UNIXLISTEN_KEEPFILE case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%unix%*|*%socket%*|*%$NAME%*) TEST="$NAME: socat keeps an existing file where it wanted to create a UNIX socket" # we create a file and start socat with UNIX-LISTEN on this file. expected # behaviour: socat exits immediately with error, but keeps the file # up to 1.7.1.3, it removed the file if ! eval $NUMCOND; then :; else tf="$td/test$N.file" te="$td/test$N.stderr" CMD0="$TRACE $SOCAT $opts -u UNIX-LISTEN:$tf /dev/null" printf "test $F_n $TEST... " $N rm -f "$tf"; touch "$tf" $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ $rc0 -ne 0 -a -f "$tf" ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac N=$((N+1)) # PTY address allowed to sepcify address parameters but ignored them NAME=PTY_VOIDARG case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%$NAME%*) TEST="$NAME: check if address params of PTY produce error" # invoke socat with address PTY and some param; expect an error if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts /dev/null PTY:/tmp/xyz" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ $rc0 -ne 0 ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac N=$((N+1)) # incomplete writes were reported but led to data loss NAME=INCOMPLETE_WRITE case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%$NAME%*) TEST="$NAME: check if incomplete writes are handled properly" # write to a nonblocking fd a block that is too large for atomic write # and check if all data arrives if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tp="$td/test$N.pipe" tw="$td/test$N.wc-c" # this is the size we write() in one call; data is never stored on disk, so # make it large enough to exceed any atomic write size; but higher number might # take much time bytes=100000 # for Linux 2.6.? this must be >65536 CMD0="$TRACE $SOCAT $opts -u PIPE:$tp STDOUT" CMD1="$TRACE $SOCAT $opts -u -b $bytes OPEN:/dev/zero,readbytes=$bytes FILE:$tp,o-nonblock" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" |wc -c >"$tw" & pid=$! waitfile "$tp" $CMD1 2>"${te}1" >"${tf}1" rc1=$? wait if [ $rc1 -ne 0 ]; then $PRINTF "$NO_RESULT\n" numCANT=$((numCANT+1)) elif [ ! -e "$tw" ]; then $PRINTF "$NO_RESULT\n" numCANT=$((numCANT+1)) elif [ "$bytes" -eq $(cat "$tw") ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "transferred only $(cat $tw) of $bytes bytes" >&2 numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac N=$((N+1)) NAME=OPENSSL_ANULL case "$TESTS" in *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: OpenSSL server with cipher aNULL " if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,$SOCAT_EGD,ciphers=aNULL,verify=0 pipe" CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,ciphers=aNULL,verify=0,$SOCAT_EGD" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id waittcp4port $PORT echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD2 &" echo "$CMD" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) # test the max-children option NAME=MAXCHILDREN case "$TESTS" in *%$N%*|*%functions%*|*%socket%*|*%$NAME%*) TEST="$NAME: max-children option" # start a listen process with max-children=1; connect with a client, let it # sleep some time before sending data; connect with second client that sends # data immediately. If max-children is working correctly the first data should # arrive first because the second process has to wait. if ! eval $NUMCOND; then :; else ts="$td/test$N.sock" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts -U FILE:$tf,o-trunc,o-creat,o-append UNIX-L:$ts,fork,max-children=1" CMD1="$TRACE $SOCAT $opts -u - UNIX-CONNECT:$ts" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & pid0=$! waitunixport $ts 1 (sleep 2; echo "$da 1") |$CMD1 >"${tf}1" 2>"${te}1" & pid1=$! sleep 1 echo "$da 2" |$CMD1 >"${tf}2" 2>"${te}2" rc2=$? sleep 2 kill $pid0 $pid1 2>/dev/null; wait if echo -e "$da 1\n$da 2" |diff $tf - >$tdiff; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0 &" echo "(sleep 2; echo \"$da 1\") |$CMD1" echo "echo \"$da 2\" |$CMD1" cat "${te}0" cat "${te}1" cat "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac N=$((N+1)) # socat up to 1.7.2.0 had a bug in xioscan_readline() that could be exploited # to overflow a heap based buffer (socat security advisory 3) # problem reported by Johan Thillemann NAME=READLINE_OVFL case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%$NAME%*) TEST="$NAME: test for buffer overflow in readline prompt handling" # address 1 is the readline where write data was handled erroneous # address 2 provides data to trigger the buffer overflow # when no SIGSEGV or so occurs the test succeeded (bug fixed) if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" ti="$td/test$N.data" CMD0="$SOCAT $opts READLINE $ti" printf "test $F_n $TEST... " $N # prepare long data - perl might not be installed #perl -e 'print "\r","Z"x513' >"$ti" echo $E -n "\rA" >"$ti" i=0; while [ $i -lt 32 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$ti"; let i=i+1; done $TRACE $SOCAT - SYSTEM:"$CMD0; echo rc=\$? >&2",pty >/dev/null 2>"${te}0" rc=$? rc0="$(grep ^rc= "${te}0" |sed 's/.*=//')" if [ $rc -ne 0 ]; then $PRINTF "${YELLOW}framework failed${NORMAL}\n" elif [ $rc0 -eq 0 ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0" grep -v ^rc= "${te}0" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # socat up to 1.7.2.1 did only shutdown() but not close() an accept() socket # that was rejected due to range, tcpwrap, lowport, or sourceport option. # This file descriptor leak could be used for a denial of service attack. NAME=FDLEAK case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%$NAME%*) TEST="$NAME: file descriptor leak with range option" # have a TCP-LISTEN with range option; connect with wrong source address until # "open files" limit would exceed. When server continues operation the bug is # not present. if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" RLIMIT_NOFILE="$(ulimit -n)" if ! [[ "$RLIMIT_NOFILE" =~ ^[0-9][0-9]*$ ]]; then $PRINTF "${YELLOW}cannot determine ulimit -n" else CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,reuseaddr,range=$LOCALHOST:255.255.255.255 PIPE" CMD1="$TRACE $SOCAT $opts -t 0 /dev/null TCP:$SECONDADDR:$PORT,bind=$SECONDADDR" CMD2="$TRACE $SOCAT $opts - TCP:$LOCALHOST:$PORT,bind=$LOCALHOST" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & pid0=$! waittcp4port $PORT 1 while [ $RLIMIT_NOFILE -gt 0 ]; do $CMD1 >/dev/null 2>>"${te}1" let RLIMIT_NOFILE=RLIMIT_NOFILE-1 done echo "$da" |$CMD2 >"${tf}2" 2>"${te}2" rc2=$? kill $pid0 2>/dev/null; wait echo -e "$da" |diff "${tf}2" - >$tdiff if [ $rc2 -ne 0 ]; then $PRINTF "$FAILED\n" echo "$CMD2 &" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif [ -f "$tdiff" -a ! -s "$tdiff" ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" echo "$CMD2" cat "${te}0" cat "${te}1" cat "${te}2" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # ulimit -n fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) if false; then # this overflow is not reliably reproducable # socat up to 2.0.0-b6 did not check the length of the PROXY-CONNECT command line paramters when copying them into the HTTP request buffer. This could lead to a buffer overflow. NAME=PROXY_ADDR_OVFL case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%$NAME%*) TEST="$NAME: proxy address parameters overflow" # invoke socat PROXY-CONNECT with long proxy server and target server names. If it terminates with exit code >= 128 it is vulnerable # However, even if vulnerable it often does not crash. Therefore we try to use a boundary check program like ElectricFence; only with its help we can tell that clean run proofs absence of vulnerability if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" EF=; for p in ef; do if type ef >/dev/null 2>&1; then EF="ef "; break fi done CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,reuseaddr FILE:/dev/null" #CMD1="$EF $TRACE $SOCAT $opts FILE:/dev/null PROXY-CONNECT:$(perl -e "print 'A' x 256"):$(perl -e "print 'A' x 256"):80" CMD1="$EF $TRACE $SOCAT $opts FILE:/dev/null PROXY-CONNECT:localhost:$(perl -e "print 'A' x 384"):80,proxyport=$PORT" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & pid0=$! waittcp4port $PORT 1 $CMD1 >/dev/null 2>"${te}1" rc1=$? if [ $rc1 -lt 128 ]; then if [ "$EF" ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$UNKNOWN $RED(install ElectricFEnce!)$NORMAL\n" numCANT=$((num+1)) fi else $PRINTF "$FAILED\n" echo "$CMD1" cat "${te}" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) fi # false # LISTEN addresses in socat up to 1.7.2.1 applied many file descriptor, socket, # and TCP options only to the listening socket instead of the connection socket. NAME=LISTEN_KEEPALIVE case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%listen%*|*%keepalive%*|*%socket%*|*%$NAME%*) TEST="$NAME: keepalive option is applied to connection socket" # instance 0 has TCP-LISTEN with option so-keepalive and invokes filan after # accept(). filan writes its output to the socket. instance 1 connects to # instance 0. The value of the sockets so-keepalive option is checked, it must # be 1 if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" #tdiff="$td/test$N.diff" #da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr,so-keepalive EXEC:\"$FILAN -i 1\",nofork" CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT" printf "test $F_n $TEST... " $N eval $CMD0 >/dev/null 2>"${te}0" & pid0=$! waittcp4port $PORT 1 $CMD1 >"${tf}1" 2>"${te}1" KEEPALIVE="$(cat "${tf}1" |tail -n +2 |sed -e "s/.*KEEPALIVE=//" -e "s/[[:space:]].*//")" rc1=$? kill $pid0 2>/dev/null; wait if [ -z "$KEEPALIVE" ]; then $PRINTF "$NO_RESULT\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" numWARN=$((numWARN+1)) elif [ "$KEEPALIVE" = "1" ]; then $PRINTF "$OK\n"; numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # OPENSSL-CONNECT with bind option failed on some systems (eg.FreeBSD, but not # Linux) with "Invalid argument". NAME=OPENSSL_CONNECT_BIND case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%openssl%*|*%$NAME%*) TEST="$NAME: test OPENSSL-CONNECT with bind option" # have a simple SSL server that just echoes data. # connect with socat using OPENSSL-CONNECT with bind, send data and check if the # reply is identical. if ! eval $NUMCOND; then :; else tf0="$td/test$N.0.stdout" te0="$td/test$N.0.stderr" tf1="$td/test$N.1.stdout" te1="$td/test$N.1.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,ciphers=aNULL,verify=0, PIPE" CMD1="$TRACE $SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,bind=$LOCALHOST,ciphers=aNULL,verify=0" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"$te0" & pid0=$! waittcp4port $PORT 1 echo "$da" |$CMD1 >"$tf1" 2>"$te1" rc1=$? kill $pid0 2>/dev/null; wait if [ "$rc1" -ne 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "$te0" cat "$te1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - $tf1 >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" numOK=$((numOK+1)) fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # socat up to version 1.7.2.3 # had a bug that converted a bit mask of 0 internally to 0xffffffff NAME=TCP4RANGE_0BITS case "$TESTS" in *%$N%*|*%functions%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: correct evaluation of range mask 0" if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then # we need access to a second addresses $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" #testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR/32" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 CMD0="$TRACE $SOCAT $opts -u TCP4-LISTEN:$PORT,reuseaddr,range=127.0.0.1/0 CREATE:$tf" CMD1="$TRACE $SOCAT $opts -u - TCP4-CONNECT:$SECONDADDR:$PORT,bind=$SECONDADDR" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" & pid0=$! waittcp4port $PORT 1 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" rc1=$? kill $pid0 2>/dev/null; wait if [ $rc1 != 0 ]; then $PRINTF "${YELLOW}invocation failed${NORMAL}\n" numCANT=$((numCANT+1)) elif ! [ -f "$tf" ]; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "${YELLOW}diff failed${NORMAL}\n" numCANT=$((numCANT+1)) else $PRINTF "$OK\n" numOK=$((numOK+1)) fi fi ;; # $SECONDADDR, NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) # test: OPENSSL sets of environment variables with important values of peer certificate while read ssldist MODE MODULE FIELD TESTADDRESS PEERADDRESS VALUE; do if [ -z "$ssldist" ] || [[ "$ssldist" == \#* ]]; then continue; fi # SSLDIST=${ssldist^^*} NAME="ENV_${SSLDIST}_${MODE}_${MODULE}_${FIELD}" case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$ssldist%*|*%envvar%*|*%$NAME%*) TEST="$NAME: $SSLDIST sets env SOCAT_${SSLDIST}_${MODULE}_${FIELD}" # have a server accepting a connection and invoking some shell code. The shell # code extracts and prints the SOCAT related environment vars. # outside code then checks if the environment contains the variables correctly # describing the desired field. if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs $FEAT); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" gentestcert testsrv gentestcert testcli test_proto=tcp4 case "$MODE" in SERVER) CMD0="$SOCAT $opts -u $TESTADDRESS system:\"echo SOCAT_${SSLDIST}_${MODULE}_${FIELD}=\\\$SOCAT_${SSLDIST}_${MODULE}_${FIELD}; sleep 1\"" CMD1="$SOCAT $opts -u /dev/null $PEERADDRESS" printf "test $F_n $TEST... " $N eval "$CMD0 2>\"${te}0\" >\"$tf\" &" pid0=$! wait${test_proto}port $PORT 1 $CMD1 2>"${te}1" rc1=$? waitfile "$tf" 2 kill $pid0 2>/dev/null; wait ;; CLIENT) CMD0="$SOCAT $opts -u /dev/null $PEERADDRESS" CMD1="$SOCAT $opts -u $TESTADDRESS system:\"echo SOCAT_${SSLDIST}_${MODULE}_${FIELD}=\\\$SOCAT_${SSLDIST}_${MODULE}_${FIELD}; sleep 1\"" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" & pid0=$! wait${test_proto}port $PORT 1 eval "$CMD1 2>\"${te}1\" >\"$tf\"" rc1=$? waitfile "$tf" 2 kill $pid0 2>/dev/null; wait ;; esac if [ $rc1 != 0 ]; then $PRINTF "$NO_RESULT (client failed):\n" echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numCANT=$((numCANT+1)) elif effval="$(grep SOCAT_${SSLDIST}_${MODULE}_${FIELD} "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")"; [ "$effval" = "$VALUE" ]; then $PRINTF "$OK\n" if [ "$debug" ]; then echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" fi numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "expected \"$VALUE\", got \"$effval\"" >&2 echo "$CMD0 &" cat "${te}0" echo "$CMD1" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND, feats ;; esac N=$((N+1)) # done <<<" openssl SERVER X509 ISSUER OPENSSL-LISTEN:$PORT,so-reuseaddr,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_ISSUER openssl SERVER X509 SUBJECT OPENSSL-LISTEN:$PORT,so-reuseaddr,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_SUBJECT openssl SERVER X509 COMMONNAME OPENSSL-LISTEN:$PORT,so-reuseaddr,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_COMMONNAME openssl SERVER X509 COUNTRYNAME OPENSSL-LISTEN:$PORT,so-reuseaddr,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_COUNTRYNAME openssl SERVER X509 LOCALITYNAME OPENSSL-LISTEN:$PORT,so-reuseaddr,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_LOCALITYNAME openssl SERVER X509 ORGANIZATIONALUNITNAME OPENSSL-LISTEN:$PORT,so-reuseaddr,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_ORGANIZATIONALUNITNAME openssl SERVER X509 ORGANIZATIONNAME OPENSSL-LISTEN:$PORT,so-reuseaddr,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_ORGANIZATIONNAME openssl CLIENT X509 SUBJECT OPENSSL-CONNECT:$LOCALHOST:$PORT,cert=testcli.pem,cafile=testsrv.crt,verify=1 OPENSSL-LISTEN:$PORT,so-reuseaddr,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 $TESTCERT_SUBJECT openssl CLIENT X509 ISSUER OPENSSL-CONNECT:$LOCALHOST:$PORT,cert=testcli.pem,cafile=testsrv.crt,verify=1 OPENSSL-LISTEN:$PORT,so-reuseaddr,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 $TESTCERT_ISSUER " ############################################################################### # tests: option umask with "passive" NAMED group addresses while read addr fileopt addropts proto diropt ADDR2; do if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi # some passive (listening...) filesystem based addresses did not implement the # umask option ADDR=${addr^^*} ADDR_=${ADDR/-/_} PROTO=${proto^^*} if [ "$diropt" = "." ]; then diropt=; fi if [ "$fileopt" = "." ]; then fileopt=; fi if [ "$addropts" = "." ]; then addropts=; fi NAME=${ADDR_}_UMASK case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%proto%*|*%socket%*|*%$proto%*|*%$NAME%*) TEST="$NAME: $ADDR applies option umask" # start a socat process with passive/listening file system entry. Check the # permissions of the FS entry, then terminate the process. # Test succeeds when FS entry exists and has expected permissions. if ! eval $NUMCOND; then :; else if [ $ADDR = PTY ]; then set -xv; fi tlog="$td/test$N.log" te0="$td/test$N.0.stderr" tsock="$td/test$N.sock" if [ -z "$fileopt" ]; then CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts,unlink-close=0,umask=177 $ADDR2" else CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,unlink-close=0,umask=177 $ADDR2" fi printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"$te0" & pid0=$! wait${proto} $tsock 1 2>"$tlog" ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi perms=$(fileperms "$tsock") kill $pid0 2>>"$tlog" wait if [ "$ERRNOENT" ]; then $PRINTF "${RED}no entry${NORMAL}\n" echo "$CMD0 &" cat "$te0" cat "$tlog" let numFAIL=numFAIL+1 listFAIL="$listFAIL $N" elif [ "$perms" != "600" ]; then $PRINTF "${RED}perms \"$perms\", expected \"600\" ${NORMAL}\n" echo "$CMD0 &" cat "$te0" let numFAIL=numFAIL+1 listFAIL="$listFAIL $N" else $PRINTF "$OK\n" let numOK=numOK+1 fi set +xv fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # done <<<" # address fileopt addropts waitfor direction ADDR2 create . . file -U FILE:/dev/null open . creat file . FILE:/dev/null gopen . creat file . FILE:/dev/null unix-listen . . unixport . FILE:/dev/null unix-recvfrom . . unixport . FILE:/dev/null unix-recv . . unixport -u FILE:/dev/null pipe . . file -u FILE:/dev/null # pty does not seem to honor umask: #pty link . file . PIPE " # tests: option perm with "passive" NAMED group addresses while read addr fileopt addropts proto diropt; do if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi # test if passive (listening...) filesystem based addresses implement option perm ADDR=${addr^^*} ADDR_=${ADDR/-/_} PROTO=${proto^^*} if [ "$diropt" = "." ]; then diropt=; fi if [ "$fileopt" = "." ]; then fileopt=; fi if [ "$addropts" = "." ]; then addropts=; fi NAME=${ADDR_}_PERM case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%proto%*|*%socket%*|*%$proto%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: $ADDR applies option perm" # start a socat process with passive/listening file system entry. Check the # permissions of the FS entry, then terminate the process. # Test succeeds when FS entry exists and has expected permissions. if ! eval $NUMCOND; then :; else tlog="$td/test$N.log" te0="$td/test$N.0.stderr" tsock="$td/test$N.sock" # set -vx if [ -z "$fileopt" ]; then CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts,perm=511 FILE:/dev/null,ignoreeof" else CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,perm=511 FILE:/dev/null,ignoreeof" fi printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"$te0" & pid0=$! wait${proto} $tsock 1 2>"$tlog" ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi perms=$(fileperms "$tsock") kill $pid0 2>>"$tlog" wait if [ "$ERRNOENT" ]; then $PRINTF "${RED}no entry${NORMAL}\n" echo "$CMD0 &" cat "$te0" cat "$tlog" let numFAIL=numFAIL+1 listFAIL="$listFAIL $N" elif [ "$perms" != "511" ]; then $PRINTF "${RED}perms \"$perms\", expected \"511\" ${NORMAL}\n" echo "$CMD0 &" cat "$te0" let numFAIL=numFAIL+1 listFAIL="$listFAIL $N" else $PRINTF "$OK\n" let numOK=numOK+1 fi set +vx fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # done <<<" # address fileopt addropts waitfor direction create . . file -U open . creat file . gopen . creat file . unix-listen . . unixport . unix-recvfrom . . unixport . unix-recv . . unixport -u pipe . . file -u pty link . file . " # tests: option user with "passive" NAMED group addresses while read addr fileopt addropts proto diropt; do if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi # test if passive (listening...) filesystem based addresses implement option user ADDR=${addr^^*} ADDR_=${ADDR/-/_} PROTO=${proto^^*} if [ "$diropt" = "." ]; then diropt=; fi if [ "$fileopt" = "." ]; then fileopt=; fi if [ "$addropts" = "." ]; then addropts=; fi NAME=${ADDR_}_USER case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%proto%*|*%socket%*|*%$proto%*|*%root%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: $ADDR applies option user" # start a socat process with passive/listening file system entry with user option. # Check the owner of the FS entry, then terminate the process. # Test succeeds when FS entry exists and has expected owner. if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else tlog="$td/test$N.log" te0="$td/test$N.0.stderr" tsock="$td/test$N.sock" # set -vx if [ -z "$fileopt" ]; then CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts,user=$SUBSTUSER FILE:/dev/null,ignoreeof" else CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,user=$SUBSTUSER FILE:/dev/null,ignoreeof" fi printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"$te0" & pid0=$! wait${proto} $tsock 1 2>"$tlog" ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi user=$(fileuser "$tsock") kill $pid0 2>>"$tlog" wait if [ "$ERRNOENT" ]; then $PRINTF "${RED}no entry${NORMAL}\n" echo "$CMD0 &" cat "$te0" cat "$tlog" let numFAIL=numFAIL+1 listFAIL="$listFAIL $N" elif [ "$user" != "$SUBSTUSER" ]; then $PRINTF "${RED}user \"$user\", expected \"$SUBSTUSER\" ${NORMAL}\n" echo "$CMD0 &" cat "$te0" let numFAIL=numFAIL+1 listFAIL="$listFAIL $N" else $PRINTF "$OK\n" let numOK=numOK+1 fi set +vx fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # done <<<" # address fileopt addropts waitfor direction create . . file -U open . creat file . gopen . creat file . unix-listen . . unixport . unix-recvfrom . . unixport . unix-recv . . unixport -u pipe . . file -u pty link . file . " # tests: is "passive" filesystem entry removed at the end? (without fork) while read addr fileopt addropts proto diropt crit ADDR2; do if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi # some passive (listening...) filesystem based addresses did not remove the file # system entry at the end ADDR=${addr^^*} ADDR_=${ADDR/-/_} PROTO=${proto^^*} if [ "$diropt" = "." ]; then diropt=; fi if [ "$fileopt" = "." ]; then fileopt=; fi if [ "$addropts" = "." ]; then addropts=; fi # $ADDR removes the file system entry when the process is terminated NAME=${ADDR_}_REMOVE case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%unix%*|*%socket%*|*%$NAME%*) TEST="$NAME: $ADDR removes socket entry when terminated during accept" # start a socat process with listening unix domain socket etc. Terminate the # process and check if the file system socket entry still exists. # Test succeeds when entry does not exist. if ! eval $NUMCOND; then :; else tlog="$td/test$N.log" te0="$td/test$N.0.stderr" tsock="$td/test$N.sock" if [ -z "$fileopt" ]; then CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts $ADDR2" else CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts $ADDR2" fi printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"$te0" & pid0=$! wait${proto} "$crit" $tsock 1 2>"$tlog" kill $pid0 2>>"$tlog" rc1=$? wait >>"$tlog" if [ $rc1 != 0 ]; then $PRINTF "${YELLOW}setup failed${NORMAL}\n" echo "$CMD0 &" cat "$te0" cat "$tlog" let numCANT=numCANT+1 elif ! [ $crit $tsock ]; then $PRINTF "$OK\n" let numOK=numOK+1 else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "$te0" cat "$tlog" let numFAIL=numFAIL+1 listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # done <<<" # address fileopt addropts waitfor direction crit ADDR2 unix-listen . . unixport . -e FILE:/dev/null unix-recvfrom . . unixport . -e FILE:/dev/null unix-recv . . unixport -u -e FILE:/dev/null pipe . . file -u -e FILE:/dev/null pty link . file . -L PIPE " # tests: is "passive" filesystem entry removed at the end? (with fork) while read addr fileopt addropts proto diropt crit ADDR2; do if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi # some passive (listening...) filesystem based addresses with fork did not remove # the file system entry at the end ADDR=${addr^^*} ADDR_=${ADDR/-/_} PROTO=${proto^^*} if [ "$diropt" = "." ]; then diropt=; fi if [ "$fileopt" = "." ]; then fileopt=; fi if [ "$addropts" = "." ]; then addropts=; fi # $ADDR with fork removes the file system entry when the process is terminated NAME=${ADDR_}_REMOVE_FORK case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%unix%*|*%socket%*|*%$NAME%*) TEST="$NAME: $ADDR with fork removes socket entry when terminated during accept" # start a socat process with listening unix domain socket etc and option fork. # Terminate the process and check if the file system socket entry still exists. # Test succeeds when entry does not exist. if ! eval $NUMCOND; then :; else tlog="$td/test$N.log" te0="$td/test$N.0.stderr" tsock="$td/test$N.sock" if [ -z "$fileopt" ]; then CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,fork,$addropts $ADDR2" else CMD0="$TRACE $SOCAT $opts $diropt $ADDR,fork,$fileopt=$tsock,$addropts $ADDR2" fi printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"$te0" & pid0=$! wait${proto} "$crit" $tsock 1 2>"$tlog" kill $pid0 2>>"$tlog" rc1=$? wait if [ $rc1 != 0 ]; then $PRINTF "${YELLOW}setup failed${NORMAL}\n" echo "$CMD0 &" cat "$te0" cat "$tlog" let numCANT=numCANT+1 elif ! [ $crit $tsock ]; then $PRINTF "$OK\n" let numOK=numOK+1 else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "$te0" cat "$tlog" let numFAIL=numFAIL+1 listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # done <<<" # address fileopt addropts waitfor direction crit ADDR2 unix-listen . . unixport . -e FILE:/dev/null unix-recvfrom . . unixport . -e FILE:/dev/null " # bug fix: SYSTEM address child process shut down parents sockets including # SSL connection under some circumstances. NAME=SYSTEM_SHUTDOWN case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%system%*|*%openssl%*|*%socket%*|*%$NAME%*) TEST="$NAME: SYSTEM address does not shutdown its parents addresses" # start an OpenSSL echo server using SYSTEM:cat # start an OpenSSL client that sends data # when the client recieves its data and terminates without error the test succeeded # in case of the bug the client issues an error like: # SSL_connect(): error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,cipher=aNULL,verify=0 SYSTEM:cat" CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,cipher=aNULL,verify=0" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & pid0=$! waittcp4port $PORT 1 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" rc1=$? kill $pid0 2>/dev/null; wait if [ $rc1 -ne 0 ]; then $PRINTF "$FAILED\n" echo "rc1=$rc1" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "${tf}1" >"$tdiff" 2>&1; then $PRINTF "$FAILED\n" echo "diff:" cat "$tdiff" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" numOK=$((numOK+1)) fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # test if TCP4-LISTEN with empty port arg terminates with error NAME=TCP4_NOPORT case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%tcp%*|*%tcp4%*|*%$NAME%*) TEST="$NAME: test if TCP4-LISTEN with empty port arg bails out" # run socat with TCP4-LISTEN with empty port arg. Check if it terminates # immediately with return code 1 if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" t0rc="$td/test$N.rc" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$SOCAT $opts TCP4-LISTEN: /dev/null" printf "test $F_n $TEST... " $N { $CMD0 >/dev/null 2>"${te}0"; echo $? >"$t0rc"; } & 2>/dev/null pid0=$! sleep 1 kill $pid0 2>/dev/null; wait if [ ! -f "$t0rc" ]; then $PRINTF "$FAILED\n" echo "no return code of CMD0 stored" >&2 echo "$CMD0 &" cat "${te}0" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo 1 |diff - "$t0rc" >"$tdiff"; then $PRINTF "$FAILED\n" echo "CMD0 exited with $(cat $t0rc), expected 1" echo "$CMD0 &" cat "${te}0" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" numOK=$((numOK+1)) fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) # test if the various SSL methods can be used with OpenSSL for method in SSL3 SSL23 TLS1 TLS1.1 TLS1.2 DTLS1; do NAME=OPENSSL_METHOD_$method case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%openssl%*|*%$NAME%*) TEST="$NAME: test OpenSSL method $method" # Start a socat process listening with OpenSSL and echoing data, # using the selected method # Start a second socat process connecting to the listener using # the same method, send some data and catch the reply. # If the reply is identical to the sent data the test succeeded. if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,method=$method,cipher=aNULL,verify=0 PIPE" CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,method=$method,cipher=aNULL,verify=0" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & pid0=$! waittcp4port $PORT 1 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" rc1=$? kill $pid0 2>/dev/null; wait if echo "$da" |diff - "${tf}1"; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) done # give a description of what is tested (a bugfix, a new feature...) NAME=FDOUT_ERROR case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*) TEST="$NAME: fdout bails out in write-only context" # use EXEC in write-only context with option fdout. Expected behaviour: error if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD="$SOCAT $opts -u /dev/null EXEC:cat,fdout=1" printf "test $F_n $TEST... " $N $CMD >/dev/null 2>"${te}" rc=$? if [ $rc -eq 1 ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" echo "command did not terminate with error!" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) ################################################################################## #================================================================================= # here come tests that might affect your systems integrity. Put normal tests # before this paragraph. # tests must be explicitely selected by roottough or name (not number) NAME=PTYGROUPLATE case "$TESTS" in *%roottough%*|*%$NAME%*) TEST="$NAME: pty with group-late works on pty" # up to socat 1.7.1.1 address pty changed the ownership of /dev/ptmx instead of # the pty with options user-late, group-late, or perm-late. # here we check for correct behaviour. # ATTENTION: in case of failure of this test the # group of /dev/ptmx might be changed! if ! eval $NUMCOND; then :; else # save current /dev/ptmx properties F= for f in /dev/ptmx /dev/ptc; do if [ -e $f ]; then F=$(echo "$f" |tr / ..) ls -l $f >"$td/test$N.$F.ls-l" break fi done printf "test $F_n $TEST... " $N if [ -z "$F" ]; then echo -e "${YELLOW}no /dev/ptmx or /dev/ptc${NORMAL}" else GROUP=daemon tf="$td/test$N.stdout" te="$td/test$N.stderr" tl="$td/test$N.pty" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts pty,link=$tl,group-late=$GROUP,escape=0x1a PIPE" CMD1="$TRACE $SOCAT $opts - $tl,raw,echo=0" $CMD0 >/dev/null 2>"${te}0" & pid0=$! (echo "$da"; usleep $MICROS; echo -e "\x1a") |$CMD1 >"${tf}1" 2>"${te}1" >"$tf" rc1=$? kill $pid0 2>/dev/null; wait if [ $rc1 -ne 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif echo "$da" |diff - "$tf" >$tdiff; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" cat "$tdiff" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi if ! ls -l $f |diff "$td/test$N.$F.ls-l" -; then $PRINTF "${RED}this test changed properties of $f!${NORMAL}\n" fi fi # no /dev/ptmx fi # NUMCOND ;; esac N=$((N+1)) echo "summary: $((N-1)) tests, $((numOK+numFAIL+numCANT)) selected; $numOK ok, $numFAIL failed, $numCANT could not be performed" if [ "$numFAIL" -gt 0 ]; then echo "FAILED: $listFAIL" exit 1 fi exit 0 #============================================================================== rm -f testsrv.* testcli.* testsrvdsa* testsrvfips* testclifips* # end # too dangerous - run as root and having a shell problem, it might purge your # file systems #rm -r "$td" # sometimes subprocesses hang; we want to see this wait exit # test template # give a description of what is tested (a bugfix, a new feature...) NAME=SHORT_UNIQUE_TESTNAME case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*) TEST="$NAME: give a one line description of test" # describe how the test is performed, and what's the success criteria if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts server-address PIPE" CMD1="$TRACE $SOCAT $opts - client-address" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & pid0=$! waitport $PORT 1 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" rc1=$? kill $pid0 2>/dev/null; wait if [ !!! ]; then $PRINTF "$OK\n" numOK=$((numOK+1)) else $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" fi fi # NUMCOND ;; esac PORT=$((PORT+1)) N=$((N+1)) socat-1.7.3.1/PORTING0000644000201000020100000000602707703051070013631 0ustar gerhardgerhard DEVELOPMENT PLATFORMS Primary development platform for socat is currently SuSE Linux 8.2 with a 2.4.20 kernel. New features are then ported to the non-Linux platforms on the Sourceforge compile farm (per July 2003: SunOS 5.8 with gcc, and MacOS X 10.2), and AIX 5.1 with gcc. But due to limited time resources and restricted (non-root) access to these systems I cannot extensively test socat there. PORTING STEPS If you want to port socat to another operating system you will typically go through two phases: First, you might just try to compile and run the actual socat distribution (passive phase). Then, you should see if your platform has some nice features that are not yet used in socat, and add code for supporting them (active phase). At last, I encourage you to send me your changes so I can integrate them into the main socat distribution. PASSIVE PHASE: * Generate Makefile and config.h: . If you have gcc, then just invoke "./configure". . If you use another C compiler, configure might not work properly; You will have to adapt config.h and Makefile manually. Change compiler options or defines to use all features of the operating system (not only ANSI-C; e.g. HP-UX: -Ae!) Some practical config..h examples have been included in the Config directory of the source that might serve as starting point. * Try to "make" socat; correct the errors. If some constants are undefined, please disable these parts option-dependent, not platform-dependent (use #ifdef TCP_OPTION instead of #if MY_OS) * If you have big troubles compiling socat then try configure with options --disable-filan --disable-sycls; this excludes some of the most system dependent parts. * After successful compilation and linking, run "make test" and try some examples. ACTIVE PHASE: * Check the man pages of your operating system for open(2), fcntl(2), setsockopt(2), ioctl(2), socket(7), ip(7), tcp(7), termios etc. and the include files where you find the definitions of existing options, for new options and implement them - again option-dependent. Places to add code for the new options: . xioopts.h: enum e_optcode (sorted numerically/alphabetically by name) . xio-*.c: select the appropriate address file (e.g., xio-tcp.c for TCP-options) and make a record of type struct optdesc: opt_newoption . xio-*.h: the declation of struct optdesc . xioopts.c: add records to struct optname optionnames for all appropriate names (sorted strictly ASCII for binary search) . filan.c: add the option to the appropriate array (sockopts, ipopts, tcpopts) . socat.html, socat.1, xio.help: write a short documentation and tell which platform and version implements this option * problems may occur especially: . with 16 or 64 bit systems . if snprintf() etc. is missing . on UNIX emulations, e.g. Cygwin INTEGRATION * If you ported socat to another platform: To let other people participate please send the modified files or a patch file and the files generated by ./gatherinfo.sh to socat@dest-unreach.org. socat-1.7.3.1/configure0000755000201000020100000203036212460744256014507 0ustar gerhardgerhard#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_unique_file="socat.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS FIPSLD_CC LIBOBJS FILAN SSLCLS SYCLS HAVE_FIPSLD EGREP GREP CPP AR RANLIB OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM SYSDEFS target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_help enable_stdio enable_fdnum enable_file enable_creat enable_gopen enable_pipe enable_termios enable_unix enable_abstract_unixsocket enable_ip4 enable_ip6 enable_rawip enable_genericsocket enable_interface enable_tcp enable_udp enable_sctp enable_listen enable_socks4 enable_socks4a enable_proxy enable_exec enable_system enable_pty enable_ext2 enable_readline enable_openssl enable_fips enable_tun enable_sycls enable_filan enable_retry enable_msglevel enable_libwrap ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-help disable help --disable-stdio disable STDIO support --disable-fdnum disable FD-number support --disable-file disable direct file support --disable-creat disable direct create support --disable-gopen disable open for UNIX socket support --disable-pipe disable pipe support --disable-termios disable termios support --disable-unix disable UNIX domain socket support --disable-abstract-unixsocket disable abstract UNIX domain socket support --disable-ip4 disable IPv4 support --disable-ip6 disable IPv6 support --disable-rawip disable raw IP support --disable-genericsocket disable generic socket support --disable-interface disable network interface support --disable-tcp disable TCP support --disable-udp disable UDP support --disable-sctp disable SCTP support --disable-listen disable listen support --disable-socks4 disable socks4 support --disable-socks4a disable socks4a support --disable-proxy disable proxy connect support --disable-exec disable exec support --disable-system disable system (shell) support --disable-pty disable pty support --disable-ext2 disable ext2 fs attributes support --disable-readline disable readline support --disable-openssl disable OpenSSL support --enable-fips enable OpenSSL FIPS support --disable-tun disable TUN/TAP support --disable-sycls disable system call tracing --disable-filan disable file descriptor analyzer --disable-retry disable retry support --enable-msglevel=N set max verbosity to debug,info,notice,warn,error,fatal --disable-libwrap disable libwrap support Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including # INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } if eval \${$4+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$4 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" if test -f /usr/xpg4/bin/fgrep; then FGREP=/usr/xpg4/bin/fgrep # Solaris else FGREP=fgrep fi # find out which defines gcc passes to cpp, so makedepend does not run into # (harmless) "error architecture not supported" { $as_echo "$as_me:${as_lineno-$LINENO}: checking which defines needed for makedepend" >&5 $as_echo_n "checking which defines needed for makedepend... " >&6; } __cpp_defs=`gcc -v -E - &1 |$FGREP -e '/cpp ' -e '/cc1 '` SYSDEFS=`aa=; for a in $__cpp_defs do case "$a" in -D*) aa="$aa $a";; esac; done; echo "$aa"` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SYSDEFS" >&5 $as_echo "$SYSDEFS" >&6; } # this must come before AC_PROG_CC if test -z "$CFLAGS"; then # if CFLAGS is not set, we preset it to -O # with this setting, we prevent autoconf from defaulting to "-g -O2" export CFLAGS=-O fi ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="gar" fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # # we need to explicitely call this here; otherwise, with --disable-libwrap we # fail if test "$GCC" = yes; then CFLAGS="$CFLAGS -D_GNU_SOURCE -Wall -Wno-parentheses" ERRONWARN="-Werror -O0" elif test "$CC" = "clang"; then CFLAGS="$CFLAGS -D_GNU_SOURCE -Wall -Wno-parentheses" ERRONWARN="-Werror -O0" #elif Sun Studio # ERRONWARN="-errwarn" else ERRONWARN= fi export CFLAGS ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in stdbool.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdbool.h" "ac_cv_header_stdbool_h" "$ac_includes_default" if test "x$ac_cv_header_stdbool_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDBOOL_H 1 _ACEOF fi done for ac_header in inttypes.h do : ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" if test "x$ac_cv_header_inttypes_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INTTYPES_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 $as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } if ${ac_cv_header_sys_wait_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main () { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_sys_wait_h=yes else ac_cv_header_sys_wait_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 $as_echo "$ac_cv_header_sys_wait_h" >&6; } if test $ac_cv_header_sys_wait_h = yes; then $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h fi for ac_header in fcntl.h limits.h strings.h sys/param.h sys/ioctl.h sys/time.h syslog.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in pwd.h grp.h stdint.h sys/types.h poll.h sys/poll.h sys/socket.h sys/uio.h sys/stat.h netdb.h sys/un.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in pty.h do : ac_fn_c_check_header_mongrel "$LINENO" "pty.h" "ac_cv_header_pty_h" "$ac_includes_default" if test "x$ac_cv_header_pty_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PTY_H 1 _ACEOF fi done for ac_header in netinet/in.h netinet/in_systm.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in netinet/ip.h do : ac_fn_c_check_header_compile "$LINENO" "netinet/ip.h" "ac_cv_header_netinet_ip_h" "$ac_includes_default #if HAVE_NETINET_IN_H && HAVE_NETINET_IN_SYSTM_H #include #include #endif " if test "x$ac_cv_header_netinet_ip_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NETINET_IP_H 1 _ACEOF fi done # Solaris prerequisites for netinet/ip.h for ac_header in netinet/tcp.h do : ac_fn_c_check_header_mongrel "$LINENO" "netinet/tcp.h" "ac_cv_header_netinet_tcp_h" "$ac_includes_default" if test "x$ac_cv_header_netinet_tcp_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NETINET_TCP_H 1 _ACEOF fi done ac_fn_c_check_header_compile "$LINENO" "net/if.h" "ac_cv_header_net_if_h" "$ac_includes_default #if HAVE_SYS_SOCKET_H #include #endif " if test "x$ac_cv_header_net_if_h" = xyes; then : $as_echo "#define HAVE_NET_IF_H 1" >>confdefs.h fi # Mac OS X requires including sys/socket.h for ac_header in arpa/nameser.h do : ac_fn_c_check_header_mongrel "$LINENO" "arpa/nameser.h" "ac_cv_header_arpa_nameser_h" "$ac_includes_default" if test "x$ac_cv_header_arpa_nameser_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ARPA_NAMESER_H 1 _ACEOF fi done for ac_header in sys/types.h netinet/in.h arpa/nameser.h netdb.h resolv.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_NETINET_IN_H # include /* inet_ functions / structs */ #endif #ifdef HAVE_ARPA_NAMESER_H # include /* DNS HEADER struct */ #endif #ifdef HAVE_NETDB_H # include #endif " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in termios.h linux/if_tun.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in net/if_dl.h do : ac_fn_c_check_header_mongrel "$LINENO" "net/if_dl.h" "ac_cv_header_net_if_dl_h" "$ac_includes_default" if test "x$ac_cv_header_net_if_dl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NET_IF_DL_H 1 _ACEOF fi done for ac_header in linux/types.h do : ac_fn_c_check_header_mongrel "$LINENO" "linux/types.h" "ac_cv_header_linux_types_h" "$ac_includes_default" if test "x$ac_cv_header_linux_types_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LINUX_TYPES_H 1 _ACEOF fi done ac_fn_c_check_header_compile "$LINENO" "linux/errqueue.h" "ac_cv_header_linux_errqueue_h" "#include #include " if test "x$ac_cv_header_linux_errqueue_h" = xyes; then : $as_echo "#define HAVE_LINUX_ERRQUEUE_H 1" >>confdefs.h fi for ac_header in sys/utsname.h sys/select.h sys/file.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in util.h bsd/libutil.h libutil.h sys/stropts.h regex.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in linux/fs.h linux/ext2_fs.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in setgrent getgrent endgrent do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in getgrouplist do : ac_fn_c_check_func "$LINENO" "getgrouplist" "ac_cv_func_getgrouplist" if test "x$ac_cv_func_getgrouplist" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETGROUPLIST 1 _ACEOF fi done for ac_func in cfmakeraw do : ac_fn_c_check_func "$LINENO" "cfmakeraw" "ac_cv_func_cfmakeraw" if test "x$ac_cv_func_cfmakeraw" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CFMAKERAW 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing res_9_init" >&5 $as_echo_n "checking for library containing res_9_init... " >&6; } if ${ac_cv_search_res_9_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char res_9_init (); int main () { return res_9_init (); ; return 0; } _ACEOF for ac_lib in '' resolv; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_res_9_init=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_res_9_init+:} false; then : break fi done if ${ac_cv_search_res_9_init+:} false; then : else ac_cv_search_res_9_init=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_res_9_init" >&5 $as_echo "$ac_cv_search_res_9_init" >&6; } ac_res=$ac_cv_search_res_9_init if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi ac_fn_c_check_func "$LINENO" "hstrerror" "ac_cv_func_hstrerror" if test "x$ac_cv_func_hstrerror" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hstrerror in -lresolv" >&5 $as_echo_n "checking for hstrerror in -lresolv... " >&6; } if ${ac_cv_lib_resolv_hstrerror+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char hstrerror (); int main () { return hstrerror (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_resolv_hstrerror=yes else ac_cv_lib_resolv_hstrerror=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_hstrerror" >&5 $as_echo "$ac_cv_lib_resolv_hstrerror" >&6; } if test "x$ac_cv_lib_resolv_hstrerror" = xyes; then : LIBS="$LIBS -lresolv"; $as_echo "#define HAVE_HSTRERROR 1" >>confdefs.h fi fi ac_fn_c_check_func "$LINENO" "gethostent" "ac_cv_func_gethostent" if test "x$ac_cv_func_gethostent" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostent in -lnsl" >&5 $as_echo_n "checking for gethostent in -lnsl... " >&6; } if ${ac_cv_lib_nsl_gethostent+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostent (); int main () { return gethostent (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_gethostent=yes else ac_cv_lib_nsl_gethostent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostent" >&5 $as_echo "$ac_cv_lib_nsl_gethostent" >&6; } if test "x$ac_cv_lib_nsl_gethostent" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" fi fi ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt" if test "x$ac_cv_func_setsockopt" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lsocket" >&5 $as_echo_n "checking for setsockopt in -lsocket... " >&6; } if ${ac_cv_lib_socket_setsockopt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char setsockopt (); int main () { return setsockopt (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_setsockopt=yes else ac_cv_lib_socket_setsockopt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_setsockopt" >&5 $as_echo "$ac_cv_lib_socket_setsockopt" >&6; } if test "x$ac_cv_lib_socket_setsockopt" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hstrerror prototype" >&5 $as_echo_n "checking for hstrerror prototype... " >&6; } if ${sc_cv_have_prototype_hstrerror+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')"; cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { hstrerror(); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_have_prototype_hstrerror=no else sc_cv_have_prototype_hstrerror=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext; CFLAGS="$CFLAGS1" fi if test $sc_cv_have_prototype_hstrerror = yes; then $as_echo "#define HAVE_PROTOTYPE_HSTRERROR 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_have_prototype_hstrerror" >&5 $as_echo "$sc_cv_have_prototype_hstrerror" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include help" >&5 $as_echo_n "checking whether to include help... " >&6; } # Check whether --enable-help was given. if test "${enable_help+set}" = set; then : enableval=$enable_help; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_HELP 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_HELP 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include STDIO support" >&5 $as_echo_n "checking whether to include STDIO support... " >&6; } # Check whether --enable-stdio was given. if test "${enable_stdio+set}" = set; then : enableval=$enable_stdio; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_STDIO 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_STDIO 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include FD-number support" >&5 $as_echo_n "checking whether to include FD-number support... " >&6; } # Check whether --enable-fdnum was given. if test "${enable_fdnum+set}" = set; then : enableval=$enable_fdnum; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_FDNUM 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_FDNUM 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include direct file support" >&5 $as_echo_n "checking whether to include direct file support... " >&6; } # Check whether --enable-file was given. if test "${enable_file+set}" = set; then : enableval=$enable_file; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_FILE 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_FILE 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include direct create support" >&5 $as_echo_n "checking whether to include direct create support... " >&6; } # Check whether --enable-creat was given. if test "${enable_creat+set}" = set; then : enableval=$enable_creat; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_CREAT 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_CREAT 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include gopen support" >&5 $as_echo_n "checking whether to include gopen support... " >&6; } # Check whether --enable-gopen was given. if test "${enable_gopen+set}" = set; then : enableval=$enable_gopen; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_GOPEN 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_GOPEN 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include explicit pipe support" >&5 $as_echo_n "checking whether to include explicit pipe support... " >&6; } # Check whether --enable-pipe was given. if test "${enable_pipe+set}" = set; then : enableval=$enable_pipe; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_PIPE 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_PIPE 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include explicit termios support" >&5 $as_echo_n "checking whether to include explicit termios support... " >&6; } # Check whether --enable-termios was given. if test "${enable_termios+set}" = set; then : enableval=$enable_termios; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_TERMIOS 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_TERMIOS 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include UNIX socket support" >&5 $as_echo_n "checking whether to include UNIX socket support... " >&6; } # Check whether --enable-unix was given. if test "${enable_unix+set}" = set; then : enableval=$enable_unix; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_UNIX 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_UNIX 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include abstract UNIX socket support" >&5 $as_echo_n "checking whether to include abstract UNIX socket support... " >&6; } # Check whether --enable-abstract_unixsocket was given. if test "${enable_abstract_unixsocket+set}" = set; then : enableval=$enable_abstract_unixsocket; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_ABSTRACT_UNIXSOCKET 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else case "`uname`" in Linux) $as_echo "#define WITH_ABSTRACT_UNIXSOCKET 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include IPv4 support" >&5 $as_echo_n "checking whether to include IPv4 support... " >&6; } # Check whether --enable-ip4 was given. if test "${enable_ip4+set}" = set; then : enableval=$enable_ip4; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_IP4 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_IP4 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include IPv6 support" >&5 $as_echo_n "checking whether to include IPv6 support... " >&6; } # Check whether --enable-ip6 was given. if test "${enable_ip6+set}" = set; then : enableval=$enable_ip6; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; WITH_IP6= ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_IP6=1 ;; esac else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_IP6=1 fi if test "$WITH_IP6"; then for ac_header in netinet/ip6.h do : ac_fn_c_check_header_compile "$LINENO" "netinet/ip6.h" "ac_cv_header_netinet_ip6_h" "$ac_includes_default #ifdef HAVE_NETINET_IN_H # include #endif " if test "x$ac_cv_header_netinet_ip6_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NETINET_IP6_H 1 _ACEOF $as_echo "#define HAVE_NETINET_IP6_H 1" >>confdefs.h $as_echo "#define WITH_IP6 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: include file netinet/ip6.h not found, disabling IP6" >&5 $as_echo "$as_me: WARNING: include file netinet/ip6.h not found, disabling IP6" >&2;} fi done for ac_header in netinet6/in6.h do : ac_fn_c_check_header_mongrel "$LINENO" "netinet6/in6.h" "ac_cv_header_netinet6_in6_h" "$ac_includes_default" if test "x$ac_cv_header_netinet6_in6_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NETINET6_IN6_H 1 _ACEOF fi done # found on OpenBSD and Lion, used for IPV6_* { $as_echo "$as_me:${as_lineno-$LINENO}: checking if __APPLE_USE_RFC_2292 is helpful" >&5 $as_echo_n "checking if __APPLE_USE_RFC_2292 is helpful... " >&6; } if ${ac_cv_apple_use_rfc_2292+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef IPV6_HOPOPTS murks; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_apple_use_rfc_2292=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define __APPLE_USE_RFC_2292 int main () { #ifndef IPV6_HOPOPTS murks; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_apple_use_rfc_2292=yes else ac_cv_apple_use_rfc_2292=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "$ac_cv_apple_use_rfc_2292" = yes; then $as_echo "#define __APPLE_USE_RFC_2292 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_apple_use_rfc_2292" >&5 $as_echo "$ac_cv_apple_use_rfc_2292" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include raw IP support" >&5 $as_echo_n "checking whether to include raw IP support... " >&6; } # Check whether --enable-rawip was given. if test "${enable_rawip+set}" = set; then : enableval=$enable_rawip; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_RAWIP 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_RAWIP 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include generic socket support" >&5 $as_echo_n "checking whether to include generic socket support... " >&6; } # Check whether --enable-genericsocket was given. if test "${enable_genericsocket+set}" = set; then : enableval=$enable_genericsocket; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_GENERICSOCKET 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_GENERICSOCKET 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include generic network interface support" >&5 $as_echo_n "checking whether to include generic network interface support... " >&6; } # Check whether --enable-interface was given. if test "${enable_interface+set}" = set; then : enableval=$enable_interface; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; WITH_INTERFACE= ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_INTERFACE=1 ;; esac else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_INTERFACE=1 fi if test "$WITH_INTERFACE"; then ac_fn_c_check_header_mongrel "$LINENO" "netpacket/packet.h" "ac_cv_header_netpacket_packet_h" "$ac_includes_default" if test "x$ac_cv_header_netpacket_packet_h" = xyes; then : $as_echo "#define HAVE_NETPACKET_PACKET_H 1" >>confdefs.h else WITH_INTERFACE=; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: include file netpacket/packet.h not found, disabling interface" >&5 $as_echo "$as_me: WARNING: include file netpacket/packet.h not found, disabling interface" >&2;} fi fi if test "$WITH_INTERFACE"; then ac_fn_c_check_header_compile "$LINENO" "netinet/if_ether.h" "ac_cv_header_netinet_if_ether_h" "$ac_includes_default #if HAVE_NET_IF_H && HAVE_NETINET_IN_H #include #include #endif " if test "x$ac_cv_header_netinet_if_ether_h" = xyes; then : $as_echo "#define HAVE_NETINET_IF_ETHER_H 1" >>confdefs.h else WITH_INTERFACE=; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: include file netinet/if_ether.h not found, disabling interface" >&5 $as_echo "$as_me: WARNING: include file netinet/if_ether.h not found, disabling interface" >&2;} fi fi if test "$WITH_INTERFACE"; then $as_echo "#define WITH_INTERFACE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include TCP support" >&5 $as_echo_n "checking whether to include TCP support... " >&6; } # Check whether --enable-tcp was given. if test "${enable_tcp+set}" = set; then : enableval=$enable_tcp; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_TCP 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_TCP 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include UDP support" >&5 $as_echo_n "checking whether to include UDP support... " >&6; } # Check whether --enable-udp was given. if test "${enable_udp+set}" = set; then : enableval=$enable_udp; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_UDP 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_UDP 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include SCTP support" >&5 $as_echo_n "checking whether to include SCTP support... " >&6; } # Check whether --enable-sctp was given. if test "${enable_sctp+set}" = set; then : enableval=$enable_sctp; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; WITH_SCTP= ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_SCTP=1 ;; esac else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_SCTP=1 fi if test -n "$WITH_SCTP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IPPROTO_SCTP" >&5 $as_echo_n "checking for IPPROTO_SCTP... " >&6; } if ${sc_cv_define_ipproto_sctp+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { IPPROTO_SCTP; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_define_ipproto_sctp=yes else sc_cv_define_ipproto_sctp=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_define_ipproto_sctp" >&5 $as_echo "$sc_cv_define_ipproto_sctp" >&6; } if test $sc_cv_define_ipproto_sctp = yes; then $as_echo "#define WITH_SCTP 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IPPROTO_SCTP undefined, disabling SCTP support" >&5 $as_echo "$as_me: WARNING: IPPROTO_SCTP undefined, disabling SCTP support" >&2;} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include listen support" >&5 $as_echo_n "checking whether to include listen support... " >&6; } # Check whether --enable-listen was given. if test "${enable_listen+set}" = set; then : enableval=$enable_listen; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_LISTEN 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_LISTEN 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include socks4 support" >&5 $as_echo_n "checking whether to include socks4 support... " >&6; } # Check whether --enable-socks4 was given. if test "${enable_socks4+set}" = set; then : enableval=$enable_socks4; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_SOCKS4 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_SOCKS4 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include socks4a support" >&5 $as_echo_n "checking whether to include socks4a support... " >&6; } # Check whether --enable-socks4a was given. if test "${enable_socks4a+set}" = set; then : enableval=$enable_socks4a; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_SOCKS4A 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_SOCKS4A 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include proxy connect support" >&5 $as_echo_n "checking whether to include proxy connect support... " >&6; } # Check whether --enable-proxy was given. if test "${enable_proxy+set}" = set; then : enableval=$enable_proxy; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_PROXY 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_PROXY 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include exec support" >&5 $as_echo_n "checking whether to include exec support... " >&6; } # Check whether --enable-exec was given. if test "${enable_exec+set}" = set; then : enableval=$enable_exec; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_EXEC 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_EXEC 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include system (shell) support" >&5 $as_echo_n "checking whether to include system (shell) support... " >&6; } # Check whether --enable-system was given. if test "${enable_system+set}" = set; then : enableval=$enable_system; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_SYSTEM 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_SYSTEM 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include pty address support" >&5 $as_echo_n "checking whether to include pty address support... " >&6; } # Check whether --enable-pty was given. if test "${enable_pty+set}" = set; then : enableval=$enable_pty; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_PTY 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_PTY 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include ext2 fs attributes support" >&5 $as_echo_n "checking whether to include ext2 fs attributes support... " >&6; } # Check whether --enable-ext2 was given. if test "${enable_ext2+set}" = set; then : enableval=$enable_ext2; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_EXT2 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_EXT2 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include readline support" >&5 $as_echo_n "checking whether to include readline support... " >&6; } # Check whether --enable-readline was given. if test "${enable_readline+set}" = set; then : enableval=$enable_readline; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; WITH_READLINE= ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_READLINE=1 ;; esac else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_READLINE=1 fi if test -n "$WITH_READLINE"; then CPPFLAGS_ORIG=$CPPFLAGS CFLAGS_ORIG=$CFLAGS LIBS_ORIG=$LIBS sc_usable_readline_found= for D in "" "/usr/local" "/opt/local" "/sw" "/opt/freeware" "/usr/sfw"; do if test -n "$D" ; then CPPFLAGS="$CPPFLAGS -I$D/include" CFLAGS="$CFLAGS -L$D/lib" DLOC="in location $D" else DLOC="in default location" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for usable readline $DLOC" >&5 $as_echo_n "checking for usable readline $DLOC... " >&6; } # Some systems require -lcurses, some require -lncurses. # Mac OS X 10.4 (and others) ships with libedit masquerading as readline, # but it doesn't work well with socat. It can be recognized by the absence # of append_history. for L in "" "-lcurses" "-lncurses"; do LIBS="$LIBS_ORIG -lreadline $L" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { readline(NULL); append_history(0, NULL); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : sc_usable_readline_found=1 break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done if test -n "$sc_usable_readline_found"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_READLINE_READLINE_H 1" >>confdefs.h $as_echo "#define HAVE_READLINE_HISTORY_H 1" >>confdefs.h $as_echo "#define HAVE_LIBREADLINE 1" >>confdefs.h $as_echo "#define WITH_READLINE 1" >>confdefs.h break else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CPPFLAGS=$CPPFLAGS_ORIG CFLAGS=$CFLAGS_ORIG LIBS=$LIBS_ORIG fi done if test -z "$sc_usable_readline_found"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no suitable version of readline found; perhaps you need to install a newer version" >&5 $as_echo "$as_me: WARNING: no suitable version of readline found; perhaps you need to install a newer version" >&2;} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include openssl support" >&5 $as_echo_n "checking whether to include openssl support... " >&6; } # Check whether --enable-openssl was given. if test "${enable_openssl+set}" = set; then : enableval=$enable_openssl; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; WITH_OPENSSL= ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_OPENSSL=1 ;; esac else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_OPENSSL=1 fi # if test -n "$WITH_OPENSSL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for components of OpenSSL" >&5 $as_echo "$as_me: checking for components of OpenSSL" >&6;} # first, we need to find the include file if ${sc_cv_have_openssl_ssl_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { ; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_have_openssl_ssl_h=yes; OPENSSL_ROOT=""; else sc_cv_have_openssl_ssl_h=no for D in "/sw" "/usr/local" "/opt/freeware" "/usr/sfw" "/usr/local/ssl"; do I="$D/include" i="$I/openssl/ssl.h" if test -r "$i"; then #V_INCL="$V_INCL -I$I" CPPFLAGS="$CPPFLAGS -I$I" { $as_echo "$as_me:${as_lineno-$LINENO}: found $i" >&5 $as_echo "$as_me: found $i" >&6;} sc_cv_have_openssl_ssl_h=yes; OPENSSL_ROOT="$D" break; fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "$sc_cv_have_openssl_ssl_h" = "yes"; then $as_echo "#define HAVE_OPENSSL_SSL_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checked for openssl/ssl.h... $sc_cv_have_openssl_ssl_h" >&5 $as_echo "$as_me: checked for openssl/ssl.h... $sc_cv_have_openssl_ssl_h" >&6;} fi # end checking for openssl/ssl.h # if test -n "$WITH_OPENSSL" -a "$sc_cv_have_openssl_ssl_h" = 'yes'; then # next, we search for the openssl library (libssl.*) # interesting: Linux only requires -lssl, FreeBSD requires -lssl -lcrypto # Note, version OpenSSL 0.9.7j requires -lcrypto even on Linux. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libssl" >&5 $as_echo_n "checking for libssl... " >&6; } if ${sc_cv_have_libssl+:} false; then : $as_echo_n "(cached) " >&6 else LIBS0="$LIBS" if test -n "$OPENSSL_ROOT"; then L="$OPENSSL_ROOT/lib"; LIBS="$LIBS -L$L -lssl" else LIBS="$LIBS -lssl" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { SSL_library_init();ERR_error_string() ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : sc_cv_have_libssl='yes' else LIBS="$LIBS -lcrypto" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { SSL_library_init() ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : sc_cv_have_libssl='yes' else sc_cv_have_libssl='no' fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$sc_cv_have_libssl" != 'yes'; then LIBS="$LIBS0" fi fi if test "$sc_cv_have_libssl" = 'yes'; then $as_echo "#define HAVE_LIBSSL 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_have_libssl" >&5 $as_echo "$sc_cv_have_libssl" >&6; } fi # # # a possible location for openssl (on Sourceforge/Solaris) # AC_CHECK_FILE(/usr/local/ssl/lib, LIBS="$LIBS -L/usr/local/ssl/lib/") # # sometimes on Solaris: # AC_CHECK_FILE(/pkgs/lib, LIBS="$LIBS -L/pkgs/lib/") # # for AIX 5.1 with Linux toolbox: # AC_CHECK_FILE(/opt/freeware/lib, LIBS="$LIBS -L/opt/freeware/lib/") # # AC_CHECK_LIB(crypto, main) # AC_CHECK_LIB(ssl, main) # # # MacOSX has openssl includes in another directory # if test -d /sw/include/; then # V_INCL="$V_INCL -I/sw/include" # # and Solaris at sourceforge here: # elif test -d /usr/local/ssl/include/; then # V_INCL="$V_INCL -I/usr/local/ssl/include" # # and AIX 5.1 with Linux toolbox: # elif test -d /opt/freeware/include; then # V_INCL="$V_INCL -I/opt/freeware/include" # fi #fi if test -n "$WITH_OPENSSL"; then if test "$sc_cv_have_openssl_ssl_h" = "yes" -a "$sc_cv_have_libssl" = "yes"; then $as_echo "#define WITH_OPENSSL 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: not all components of OpenSSL found, disabling it" >&5 $as_echo "$as_me: WARNING: not all components of OpenSSL found, disabling it" >&2;}; fi fi # check for fips support { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include openssl fips support" >&5 $as_echo_n "checking whether to include openssl fips support... " >&6; } # Check whether --enable-fips was given. if test "${enable_fips+set}" = set; then : enableval=$enable_fips; case "$enableval" in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_FIPS=1 ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; WITH_FIPS= ;; esac else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; WITH_FIPS= fi if test -n "$WITH_FIPS"; then if test -n "$WITH_OPENSSL"; then # Extract the first word of "fipsld", so it can be a program name with args. set dummy fipsld; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_HAVE_FIPSLD+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_FIPSLD"; then ac_cv_prog_HAVE_FIPSLD="$HAVE_FIPSLD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_HAVE_FIPSLD="1" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi HAVE_FIPSLD=$ac_cv_prog_HAVE_FIPSLD if test -n "$HAVE_FIPSLD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_FIPSLD" >&5 $as_echo "$HAVE_FIPSLD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$sc_cv_have_openssl_ssl_h" != "yes" -o "$sc_cv_have_libssl" != "yes" -o ! "$HAVE_FIPSLD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: not all components of OpenSSL found, disabling FIPS" >&5 $as_echo "$as_me: WARNING: not all components of OpenSSL found, disabling FIPS" >&2;}; WITH_FIPS= fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: must enable OpenSSL to enable FIPS; use --enable-openssl" >&5 $as_echo "$as_me: WARNING: must enable OpenSSL to enable FIPS; use --enable-openssl" >&2;}; fi fi if test -n "$WITH_FIPS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for components of OpenSSL FIPS" >&5 $as_echo_n "checking for components of OpenSSL FIPS... " >&6; } # first, we need to find the include file if ${sc_cv_have_openssl_fips_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define OPENSSL_FIPS #include #include int main () { ; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_have_openssl_fips_h=yes; else sv_cv_have_openssl_fips_h=no if test -n "$OPENSSL_ROOT"; then I="$OPENSSL_ROOT/include" i="$I/openssl/fips.h" if test -r "$i"; then { $as_echo "$as_me:${as_lineno-$LINENO}: found $i" >&5 $as_echo "$as_me: found $i" >&6;} sc_cv_have_openssl_fips_h=yes; fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "$sv_cv_have_openssl_fips_h" = "yes"; then $as_echo "#define HAVE_OPENSSL_FIPS_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checked for openssl/fips.h... $sc_cv_have_openssl_ssl_h" >&5 $as_echo "$as_me: checked for openssl/fips.h... $sc_cv_have_openssl_ssl_h" >&6;} fi if test -n "$WITH_FIPS" -a "$sc_cv_have_openssl_fips_h" = 'yes'; then # check for the libcrypto library with fips support { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libcrypto with FIPS support" >&5 $as_echo_n "checking for libcrypto with FIPS support... " >&6; } if ${sc_cv_have_libcrypto+:} false; then : $as_echo_n "(cached) " >&6 else LIBS0="$LIBS" echo $LIBS | grep -q "\-lcrypto" if test $? -ne 0; then if test -n "$OPENSSL_ROOT"; then L="$OPENSSL_ROOT/lib"; LIBS="$LIBS -L$L -lcrypto" else LIBS="$LIBS -lcrypto" fi fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define OPENSSL_FIPS #include #include int main () { int res = FIPS_mode_set(1); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : sc_cv_have_libcrypto='yes' else sc_cv_have_libcrypto='no' fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$sc_cv_have_libcrypto" != 'yes'; then LIBS="$LIBS0" fi fi if test "$sc_cv_have_libcrypto" = 'yes'; then $as_echo "#define HAVE_LIBCRYPTO 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_have_libcrypto" >&5 $as_echo "$sc_cv_have_libcrypto" >&6; } fi if test -n "$WITH_FIPS"; then if test "$sc_cv_have_openssl_fips_h" = 'yes' -a "$sc_cv_have_libcrypto" = 'yes'; then $as_echo "#define WITH_FIPS 1" >>confdefs.h $as_echo "#define OPENSSL_FIPS 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: not all components of OpenSSL FIPS found, disabling it" >&5 $as_echo "$as_me: WARNING: not all components of OpenSSL FIPS found, disabling it" >&2;}; fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include tun/tap address support" >&5 $as_echo_n "checking whether to include tun/tap address support... " >&6; } # Check whether --enable-tun was given. if test "${enable_tun+set}" = set; then : enableval=$enable_tun; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; WITH_TUN= ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_TUN=1 ;; esac else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_TUN=1 fi # if ! test "$ac_cv_header_linux_if_tun_h" = 'yes'; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: include file linux/if_tun.h not found" >&5 $as_echo "$as_me: WARNING: include file linux/if_tun.h not found" >&2;} WITH_TUN= fi # if test -n "$WITH_TUN"; then $as_echo "#define WITH_TUN 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include system call tracing" >&5 $as_echo_n "checking whether to include system call tracing... " >&6; } # Check whether --enable-sycls was given. if test "${enable_sycls+set}" = set; then : enableval=$enable_sycls; case "$enableval" in no) SYCLS=""; SSLCLS=""; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_SYCLS 1" >>confdefs.h SYCLS="sycls.c"; SSLCLS="sslcls.c"; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_SYCLS 1" >>confdefs.h SYCLS="sycls.c"; SSLCLS="sslcls.c"; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include file descriptor analyzer" >&5 $as_echo_n "checking whether to include file descriptor analyzer... " >&6; } # Check whether --enable-filan was given. if test "${enable_filan+set}" = set; then : enableval=$enable_filan; case "$enableval" in no) FILAN=""; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_FILAN 1" >>confdefs.h FILAN="filan.c"; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_FILAN 1" >>confdefs.h FILAN="filan.c"; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include retry support" >&5 $as_echo_n "checking whether to include retry support... " >&6; } # Check whether --enable-retry was given. if test "${enable_retry+set}" = set; then : enableval=$enable_retry; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };; *) $as_echo "#define WITH_RETRY 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; };; esac else $as_echo "#define WITH_RETRY 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking included message level" >&5 $as_echo_n "checking included message level... " >&6; } # Check whether --enable-msglevel was given. if test "${enable_msglevel+set}" = set; then : enableval=$enable_msglevel; case "$enableval" in debug) $as_echo "#define WITH_MSGLEVEL 0" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: debug" >&5 $as_echo "debug" >&6; };; info) $as_echo "#define WITH_MSGLEVEL 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: info" >&5 $as_echo "info" >&6; };; notice) $as_echo "#define WITH_MSGLEVEL 2" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: notice" >&5 $as_echo "notice" >&6; };; warn) $as_echo "#define WITH_MSGLEVEL 3" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: warn" >&5 $as_echo "warn" >&6; };; error) $as_echo "#define WITH_MSGLEVEL 4" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: error" >&5 $as_echo "error" >&6; };; fatal) $as_echo "#define WITH_MSGLEVEL 5" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: fatal" >&5 $as_echo "fatal" >&6; };; *) $as_echo "#define WITH_MSGLEVEL 0" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: debug" >&5 $as_echo "debug" >&6; };; esac else $as_echo "#define WITH_MSGLEVEL 0" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: debug" >&5 $as_echo "debug" >&6; } fi #AC_SUBST(V_INCL) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 $as_echo_n "checking for uid_t in sys/types.h... " >&6; } if ${ac_cv_type_uid_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "uid_t" >/dev/null 2>&1; then : ac_cv_type_uid_t=yes else ac_cv_type_uid_t=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 $as_echo "$ac_cv_type_uid_t" >&6; } if test $ac_cv_type_uid_t = no; then $as_echo "#define uid_t int" >>confdefs.h $as_echo "#define gid_t int" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" if test "x$ac_cv_type_mode_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define mode_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" if test "x$ac_cv_type_off_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define off_t long int _ACEOF fi ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" if test "x$ac_cv_type_pid_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_BLKSIZE 1 _ACEOF $as_echo "#define HAVE_ST_BLKSIZE 1" >>confdefs.h fi ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_BLOCKS 1 _ACEOF $as_echo "#define HAVE_ST_BLOCKS 1" >>confdefs.h else case " $LIBOBJS " in *" fileblocks.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS fileblocks.$ac_objext" ;; esac fi ac_fn_c_check_member "$LINENO" "struct stat" "st_rdev" "ac_cv_member_struct_stat_st_rdev" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_rdev" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_RDEV 1 _ACEOF $as_echo "#define HAVE_ST_RDEV 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep" if test "x$ac_cv_func_nanosleep" = xyes; then : $as_echo "#define HAVE_NANOSLEEP 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nanosleep in -lrt" >&5 $as_echo_n "checking for nanosleep in -lrt... " >&6; } if ${ac_cv_lib_rt_nanosleep+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nanosleep (); int main () { return nanosleep (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_nanosleep=yes else ac_cv_lib_rt_nanosleep=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_nanosleep" >&5 $as_echo "$ac_cv_lib_rt_nanosleep" >&6; } if test "x$ac_cv_lib_rt_nanosleep" = xyes; then : LIBS="-lrt $LIBS"; $as_echo "#define HAVE_NANOSLEEP 1" >>confdefs.h fi fi #AC_CHECK_FUNC(nanosleep, , AC_CHECK_LIB(rt, nanosleep)) if test $ac_cv_c_compiler_gnu = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 $as_echo_n "checking whether $CC needs -traditional... " >&6; } if ${ac_cv_prog_gcc_traditional+:} false; then : $as_echo_n "(cached) " >&6 else ac_pattern="Autoconf.*'x'" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Autoconf TIOCGETP _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes else ac_cv_prog_gcc_traditional=no fi rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Autoconf TCGETA _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes fi rm -f conftest* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 $as_echo "$ac_cv_prog_gcc_traditional" >&6; } if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5 $as_echo_n "checking for working memcmp... " >&6; } if ${ac_cv_func_memcmp_working+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_memcmp_working=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Some versions of memcmp are not 8-bit clean. */ char c0 = '\100', c1 = '\200', c2 = '\201'; if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) return 1; /* The Next x86 OpenStep bug shows up only when comparing 16 bytes or more and with at least one buffer not starting on a 4-byte boundary. William Lewis provided this test program. */ { char foo[21]; char bar[21]; int i; for (i = 0; i < 4; i++) { char *a = foo + i; char *b = bar + i; strcpy (a, "--------01111111"); strcpy (b, "--------10000000"); if (memcmp (a, b, 16) >= 0) return 1; } return 0; } ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_memcmp_working=yes else ac_cv_func_memcmp_working=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5 $as_echo "$ac_cv_func_memcmp_working" >&6; } test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in *" memcmp.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 $as_echo_n "checking return type of signal handlers... " >&6; } if ${ac_cv_type_signal+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_type_signal=int else ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 $as_echo "$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF for ac_func in strftime do : ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime" if test "x$ac_cv_func_strftime" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRFTIME 1 _ACEOF else # strftime is in -lintl on SCO UNIX. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strftime in -lintl" >&5 $as_echo_n "checking for strftime in -lintl... " >&6; } if ${ac_cv_lib_intl_strftime+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lintl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char strftime (); int main () { return strftime (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_intl_strftime=yes else ac_cv_lib_intl_strftime=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_strftime" >&5 $as_echo "$ac_cv_lib_intl_strftime" >&6; } if test "x$ac_cv_lib_intl_strftime" = xyes; then : $as_echo "#define HAVE_STRFTIME 1" >>confdefs.h LIBS="-lintl $LIBS" fi fi done for ac_func in putenv select poll socket strtod strtol do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in strtoul uname getpgid getsid getaddrinfo do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in setgroups inet_aton do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in grantpt unlockpt do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # GR AC_CHECK_FUNCS only checks linking, not prototype. This may lead to implicit # function declarations and to SIGSEGV on systems with 32bit int and 64bit pointer ################################### # check for prototype and existence of functions that return a pointer # defines in config.h: HAVE_PROTOTYPE_LIB_$1 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strdup prototype" >&5 $as_echo_n "checking for strdup prototype... " >&6; } if ${sc_cv_have_prototype_lib_strdup+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN -Wall $CFLAGS1"; cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { return(&strdup==(void *)&strdup); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : sc_cv_have_prototype_lib_strdup=yes else sc_cv_have_prototype_lib_strdup=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext; CFLAGS="$CFLAGS1" fi if test $sc_cv_have_prototype_lib_strdup = yes; then $as_echo "#define HAVE_PROTOTYPE_LIB_strdup 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_have_prototype_lib_strdup" >&5 $as_echo "$sc_cv_have_prototype_lib_strdup" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strerror prototype" >&5 $as_echo_n "checking for strerror prototype... " >&6; } if ${sc_cv_have_prototype_lib_strerror+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN -Wall $CFLAGS1"; cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { return(&strerror==(void *)&strerror); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : sc_cv_have_prototype_lib_strerror=yes else sc_cv_have_prototype_lib_strerror=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext; CFLAGS="$CFLAGS1" fi if test $sc_cv_have_prototype_lib_strerror = yes; then $as_echo "#define HAVE_PROTOTYPE_LIB_strerror 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_have_prototype_lib_strerror" >&5 $as_echo "$sc_cv_have_prototype_lib_strerror" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strstr prototype" >&5 $as_echo_n "checking for strstr prototype... " >&6; } if ${sc_cv_have_prototype_lib_strstr+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN -Wall $CFLAGS1"; cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { return(&strstr==(void *)&strstr); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : sc_cv_have_prototype_lib_strstr=yes else sc_cv_have_prototype_lib_strstr=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext; CFLAGS="$CFLAGS1" fi if test $sc_cv_have_prototype_lib_strstr = yes; then $as_echo "#define HAVE_PROTOTYPE_LIB_strstr 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_have_prototype_lib_strstr" >&5 $as_echo "$sc_cv_have_prototype_lib_strstr" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getipnodebyname prototype" >&5 $as_echo_n "checking for getipnodebyname prototype... " >&6; } if ${sc_cv_have_prototype_lib_getipnodebyname+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN -Wall $CFLAGS1"; cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { return(&getipnodebyname==(void *)&getipnodebyname); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : sc_cv_have_prototype_lib_getipnodebyname=yes else sc_cv_have_prototype_lib_getipnodebyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext; CFLAGS="$CFLAGS1" fi if test $sc_cv_have_prototype_lib_getipnodebyname = yes; then $as_echo "#define HAVE_PROTOTYPE_LIB_getipnodebyname 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_have_prototype_lib_getipnodebyname" >&5 $as_echo "$sc_cv_have_prototype_lib_getipnodebyname" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for memrchr prototype" >&5 $as_echo_n "checking for memrchr prototype... " >&6; } if ${sc_cv_have_prototype_lib_memrchr+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN -Wall $CFLAGS1"; cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { return(&memrchr==(void *)&memrchr); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : sc_cv_have_prototype_lib_memrchr=yes else sc_cv_have_prototype_lib_memrchr=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext; CFLAGS="$CFLAGS1" fi if test $sc_cv_have_prototype_lib_memrchr = yes; then $as_echo "#define HAVE_PROTOTYPE_LIB_memrchr 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_have_prototype_lib_memrchr" >&5 $as_echo "$sc_cv_have_prototype_lib_memrchr" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for if_indextoname prototype" >&5 $as_echo_n "checking for if_indextoname prototype... " >&6; } if ${sc_cv_have_prototype_lib_if_indextoname+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN -Wall $CFLAGS1"; cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { return(&if_indextoname==(void *)&if_indextoname); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : sc_cv_have_prototype_lib_if_indextoname=yes else sc_cv_have_prototype_lib_if_indextoname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext; CFLAGS="$CFLAGS1" fi if test $sc_cv_have_prototype_lib_if_indextoname = yes; then $as_echo "#define HAVE_PROTOTYPE_LIB_if_indextoname 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_have_prototype_lib_if_indextoname" >&5 $as_echo "$sc_cv_have_prototype_lib_if_indextoname" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ptsname prototype" >&5 $as_echo_n "checking for ptsname prototype... " >&6; } if ${sc_cv_have_prototype_lib_ptsname+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN -Wall $CFLAGS1"; cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { return(&ptsname==(void *)&ptsname); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : sc_cv_have_prototype_lib_ptsname=yes else sc_cv_have_prototype_lib_ptsname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext; CFLAGS="$CFLAGS1" fi if test $sc_cv_have_prototype_lib_ptsname = yes; then $as_echo "#define HAVE_PROTOTYPE_LIB_ptsname 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_have_prototype_lib_ptsname" >&5 $as_echo "$sc_cv_have_prototype_lib_ptsname" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long" >&5 $as_echo_n "checking for long long... " >&6; } if ${sc_cv_type_longlong+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { long long s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_longlong=yes else sc_cv_type_longlong=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_type_longlong = yes; then $as_echo "#define HAVE_TYPE_LONGLONG 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_longlong" >&5 $as_echo "$sc_cv_type_longlong" >&6; } ac_fn_c_check_type "$LINENO" "sig_atomic_t" "ac_cv_type_sig_atomic_t" "#include \"sysincludes.h\" " if test "x$ac_cv_type_sig_atomic_t" = xyes; then : $as_echo "#define HAVE_TYPE_SIG_ATOMIC_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bool" >&5 $as_echo_n "checking for bool... " >&6; } if ${sc_cv_type_bool+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_STDBOOL_H #include #endif int main () { bool b; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_bool=yes else sc_cv_type_bool=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_type_bool = yes; then $as_echo "#define HAVE_TYPE_BOOL 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_bool" >&5 $as_echo "$sc_cv_type_bool" >&6; } # following builtin macro does not check unistd.h and sys/socket.h where # socklen_t might be defined #AC_CHECK_TYPE(socklen_t, int) # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5 $as_echo_n "checking for socklen_t... " >&6; } if ${sc_cv_type_socklen+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { socklen_t s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_socklen=yes else sc_cv_type_socklen=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_type_socklen = yes; then $as_echo "#define HAVE_TYPE_SOCKLEN 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_socklen" >&5 $as_echo "$sc_cv_type_socklen" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat64" >&5 $as_echo_n "checking for struct stat64... " >&6; } if ${sc_cv_type_stat64+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64=yes else sc_cv_type_stat64=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_type_stat64 = yes; then $as_echo "#define HAVE_TYPE_STAT64 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat64" >&5 $as_echo "$sc_cv_type_stat64" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t" >&5 $as_echo_n "checking for off64_t... " >&6; } if ${sc_cv_type_off64+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { off64_t s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off64=yes else sc_cv_type_off64=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_type_off64 = yes; then $as_echo "#define HAVE_TYPE_OFF64 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_off64" >&5 $as_echo "$sc_cv_type_off64" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sighandler_t" >&5 $as_echo_n "checking for sighandler_t... " >&6; } if ${sc_cv_type_sighandler+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { sighandler_t s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_sighandler=yes else sc_cv_type_sighandler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_type_sighandler = yes; then $as_echo "#define HAVE_TYPE_SIGHANDLER 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_socklen" >&5 $as_echo "$sc_cv_type_socklen" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint8_t" >&5 $as_echo_n "checking for uint8_t... " >&6; } if ${sc_cv_type_uint8+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if HAVE_STDINT_H #include #endif /* Tru64 has uint8_t etc from netdb.h */ #if HAVE_NETDB_H #include #endif #include int main () { uint8_t s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_uint8=yes else sc_cv_type_uint8=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_type_uint8 = yes; then $as_echo "#define HAVE_TYPE_UINT8 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_uint8" >&5 $as_echo "$sc_cv_type_uint8" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint16_t" >&5 $as_echo_n "checking for uint16_t... " >&6; } if ${sc_cv_type_uint16+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if HAVE_STDINT_H #include #endif /* Tru64 has uint16_t etc from netdb.h */ #if HAVE_NETDB_H #include #endif #include int main () { uint16_t s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_uint16=yes else sc_cv_type_uint16=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_type_uint16 = yes; then $as_echo "#define HAVE_TYPE_UINT16 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_uint16" >&5 $as_echo "$sc_cv_type_uint16" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint32_t" >&5 $as_echo_n "checking for uint32_t... " >&6; } if ${sc_cv_type_uint32+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if HAVE_STDINT_H #include #endif /* Tru64 has uint32_t etc from netdb.h */ #if HAVE_NETDB_H #include #endif #include int main () { uint32_t s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_uint32=yes else sc_cv_type_uint32=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_type_uint32 = yes; then $as_echo "#define HAVE_TYPE_UINT32 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_uint32" >&5 $as_echo "$sc_cv_type_uint32" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint64_t" >&5 $as_echo_n "checking for uint64_t... " >&6; } if ${sc_cv_type_uint64+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if HAVE_STDINT_H #include #endif /* Tru64 has uint32_t etc from netdb.h */ #if HAVE_NETDB_H #include #endif #include int main () { uint64_t s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_uint64=yes else sc_cv_type_uint64=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_type_uint64 = yes; then $as_echo "#define HAVE_TYPE_UINT64 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_uint64" >&5 $as_echo "$sc_cv_type_uint64" >&6; } ### AIX 4.1 needs _XOPEN_EXTENDED_SOURCE for syslog headers, # but then gets problems with 3rd arg of getsockaddr... #AC_MSG_CHECKING(for _XOPEN_EXTENDED_SOURCE requirement) #CFLAGS="-Werror -Wall" #AC_TRY_COMPILE([#include ], #[syslog(0," ");], #[AC_MSG_RESULT(no)], #[AC_MSG_RESULT(required); AC_DEFINE(_XOPEN_EXTENDED_SOURCE)]) ### fds_bits { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fdset->fds_bits" >&5 $as_echo_n "checking for fdset->fds_bits... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if HAVE_SYS_SELECT_H #include #endif int main () { fd_set s; s.fds_bits[0]=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; $as_echo "#define HAVE_FDS_BITS 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sa_family_t" >&5 $as_echo_n "checking for sa_family_t... " >&6; } if ${sc_cv_type_sa_family_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { sa_family_t s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_sa_family_t=yes else sc_cv_type_sa_family_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_type_sa_family_t = yes; then $as_echo "#define HAVE_TYPE_SA_FAMILY_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_sa_family_t" >&5 $as_echo "$sc_cv_type_sa_family_t" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct sock_extended_err" >&5 $as_echo_n "checking for struct sock_extended_err... " >&6; } if ${sc_cv_struct_sock_extended_err+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if TIME_WITH_SYS_TIME #include #endif #if HAVE_LINUX_ERRQUEUE_H #include #endif int main () { struct sock_extended_err s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_sock_extended_err=yes else sc_cv_struct_sock_extended_err=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_sock_extended_err = yes; then $as_echo "#define HAVE_STRUCT_SOCK_EXTENDED_ERR 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_sock_extended_err" >&5 $as_echo "$sc_cv_struct_sock_extended_err" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct sigaction.sa_sigaction" >&5 $as_echo_n "checking for struct sigaction.sa_sigaction... " >&6; } if ${sc_cv_struct_sigaction_sa_sigaction+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct sigaction s;s.sa_sigaction=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_sigaction_sa_sigaction=yes else sc_cv_struct_sigaction_sa_sigaction=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_sigaction_sa_sigaction = yes; then $as_echo "#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_sigaction_sa_sigaction" >&5 $as_echo "$sc_cv_struct_sigaction_sa_sigaction" >&6; } ### struct termios .c_ispeed { $as_echo "$as_me:${as_lineno-$LINENO}: checking for termios.c_ispeed" >&5 $as_echo_n "checking for termios.c_ispeed... " >&6; } if ${sc_cv_termios_ispeed+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct termios t; t.c_ispeed=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_termios_ispeed=yes else sc_cv_termios_ispeed=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_termios_ispeed = yes; then $as_echo "#define HAVE_TERMIOS_ISPEED 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_termios_ispeed" >&5 $as_echo "$sc_cv_termios_ispeed" >&6; } if test $sc_cv_termios_ispeed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for offset of c_ispeed in struct termios" >&5 $as_echo_n "checking for offset of c_ispeed in struct termios... " >&6; } LIBS1="$LIBS"; LIBS="" # avoid libwrap allow_severity undefined if ${ac_cv_ispeed_offset+:} false; then : $as_echo_n "(cached) " >&6 else conftestspeedoff="conftestspeedoff.out" if test "$cross_compiling" = yes; then : ac_cv_ispeed_offset=-1 #! else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include int main(){ struct termios t; FILE *f; if ((f=fopen("$conftestspeedoff","w"))==NULL){ fprintf(stderr,"\\"$conftestspeedoff\\": %s\n",strerror(errno)); exit(-1); } fprintf(f, "%d", ((char*)&t.c_ispeed-(char*)&t)/sizeof(speed_t)); exit(0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_ispeed_offset=`cat $conftestspeedoff` else ac_cv_ispeed_offset=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi LIBS="$LIBS1" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_ispeed_offset" >&5 $as_echo "$ac_cv_ispeed_offset" >&6; } if test $ac_cv_ispeed_offset -ge 0; then cat >>confdefs.h <<_ACEOF #define ISPEED_OFFSET $ac_cv_ispeed_offset _ACEOF fi fi # there is another issue with termios: OSR requires "#define _SVID3 ..." # for reasonable termios support. We check this situation using IMAXBEL { $as_echo "$as_me:${as_lineno-$LINENO}: checking if _SVID3 is helpful" >&5 $as_echo_n "checking if _SVID3 is helpful... " >&6; } if ${ac_cv_svid3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int i=IMAXBEL ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_svid3=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _SVID3 1 #include int main () { int i=IMAXBEL ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_svid3=yes else ac_cv_svid3=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_svid3 = yes; then $as_echo "#define _SVID3 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_svid3" >&5 $as_echo "$ac_cv_svid3" >&6; } # Openindiana needs _XPG4_2 for CMSG stuff { $as_echo "$as_me:${as_lineno-$LINENO}: checking if _XPG4_2 is helpful" >&5 $as_echo_n "checking if _XPG4_2 is helpful... " >&6; } if ${ac_cv_xpg4_2+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int i=CMSG_DATA(0) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_xpg4_2=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _XPG4_2 1 #include int main () { int i=CMSG_DATA(0) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_xpg4_2=yes else ac_cv_xpg4_2=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi if test $ac_cv_xpg4_2 = yes; then $as_echo "#define _XPG4_2 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_xpg4_2" >&5 $as_echo "$ac_cv_xpg4_2" >&6; } # When on Openindiana _XPG4_2 is defined (see above) # we also need to define __EXTENSIONS__ for basic stuff. # Note that is important on Openindiana # but does not exist on Linux if test "$ac_cv_xpg4_2" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if __EXTENSIONS__ is helpful" >&5 $as_echo_n "checking if __EXTENSIONS__ is helpful... " >&6; } if ${ac_cv___extensions__+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { procset_t *s=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv___extensions__=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define __EXTENSIONS__ 1 #include int main () { procset_t *s=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv___extensions__=yes else ac_cv___extensions__=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv___extensions__ = yes; then $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___extensions__" >&5 $as_echo "$ac_cv___extensions__" >&6; } fi # When on Openindiana __EXTENSIONS__ is defined (see above) # _POSIX_PTHREAD_SEMANTICS must be defined for standard ctime_r() if test "$ac_cv___extensions__" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if _POSIX_PTHREAD_SEMANTICS is helpful" >&5 $as_echo_n "checking if _POSIX_PTHREAD_SEMANTICS is helpful... " >&6; } if ${ac_cv__posix_pthread_semantics+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *s = ctime_r(0,0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv__posix_pthread_semantics=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _POSIX_PTHREAD_SEMANTICS 1 #include int main () { char *s = ctime_r(0,0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv__posix_pthread_semantics=yes else ac_cv__posix_pthread_semantics=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv__posix_pthread_semantics = yes; then $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv__posix_pthread_semantics" >&5 $as_echo "$ac_cv__posix_pthread_semantics" >&6; } fi # struct timespec { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct timespec" >&5 $as_echo_n "checking for struct timespec... " >&6; } if ${sc_cv_struct_timespec+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if HAVE_SYS_TIME_H #include #endif int main () { struct timespec s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_timespec=yes else sc_cv_struct_timespec=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_timespec = yes; then $as_echo "#define HAVE_STRUCT_TIMESPEC 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_timespec" >&5 $as_echo "$sc_cv_struct_timespec" >&6; } # struct linger; FreeBSD requires sys/types.h for sys/socket.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct linger" >&5 $as_echo_n "checking for struct linger... " >&6; } if ${sc_cv_struct_linger+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct linger s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_linger=yes else sc_cv_struct_linger=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_linger = yes; then $as_echo "#define HAVE_STRUCT_LINGER 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_linger" >&5 $as_echo "$sc_cv_struct_linger" >&6; } # struct ip_mreq (for multicasting options) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct ip_mreq" >&5 $as_echo_n "checking for struct ip_mreq... " >&6; } if ${sc_cv_struct_ip_mreq+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct ip_mreq s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_ip_mreq=yes else sc_cv_struct_ip_mreq=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_ip_mreq = yes; then $as_echo "#define HAVE_STRUCT_IP_MREQ 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_ip_mreq" >&5 $as_echo "$sc_cv_struct_ip_mreq" >&6; } # struct ip_mreqn (for multicasting options) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct ip_mreqn" >&5 $as_echo_n "checking for struct ip_mreqn... " >&6; } if ${sc_cv_struct_ip_mreqn+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct ip_mreqn s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_ip_mreqn=yes else sc_cv_struct_ip_mreqn=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_ip_mreqn = yes; then $as_echo "#define HAVE_STRUCT_IP_MREQN 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_ip_mreqn" >&5 $as_echo "$sc_cv_struct_ip_mreqn" >&6; } # struct ipv6_mreq (for multicasting options) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct ipv6_mreq" >&5 $as_echo_n "checking for struct ipv6_mreq... " >&6; } if ${sc_cv_struct_ipv6_mreq+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct ipv6_mreq s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_ipv6_mreq=yes else sc_cv_struct_ipv6_mreq=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_ipv6_mreq = yes; then $as_echo "#define HAVE_STRUCT_IPV6_MREQ 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_ipv6_mreq" >&5 $as_echo "$sc_cv_struct_ipv6_mreq" >&6; } # struct ifreq (for network interfaces) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct ifreq" >&5 $as_echo_n "checking for struct ifreq... " >&6; } if ${sc_cv_struct_ifreq+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct ifreq s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_ifreq=yes else sc_cv_struct_ifreq=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_ifreq = yes; then $as_echo "#define HAVE_STRUCT_IFREQ 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_ifreq" >&5 $as_echo "$sc_cv_struct_ifreq" >&6; } # struct ifreq.ifr_index # on most systems that have struct ifreq { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct ifreq.ifr_index" >&5 $as_echo_n "checking for struct ifreq.ifr_index... " >&6; } if ${sc_cv_struct_ifreq_ifr_index+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct ifreq ir;ir.ifr_index=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_ifreq_ifr_index=yes else sc_cv_struct_ifreq_ifr_index=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_ifreq_ifr_index = yes; then $as_echo "#define HAVE_STRUCT_IFREQ_IFR_INDEX 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_ifreq_ifr_index" >&5 $as_echo "$sc_cv_struct_ifreq_ifr_index" >&6; } # struct ifreq.ifr_ifindex # Linux has ifr_ifindex instead of ifr_index { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct ifreq.ifr_ifindex" >&5 $as_echo_n "checking for struct ifreq.ifr_ifindex... " >&6; } if ${sc_cv_struct_ifreq_ifr_ifindex+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct ifreq ir;ir.ifr_ifindex=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_ifreq_ifr_ifindex=yes else sc_cv_struct_ifreq_ifr_ifindex=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_ifreq_ifr_ifindex = yes; then $as_echo "#define HAVE_STRUCT_IFREQ_IFR_IFINDEX 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_ifreq_ifr_ifindex" >&5 $as_echo "$sc_cv_struct_ifreq_ifr_ifindex" >&6; } # some systems have a sa_len field in struct sockaddr and we need to support it # so we can compare sockaddrs simply with memcmp { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct sockaddr.sa_len" >&5 $as_echo_n "checking for struct sockaddr.sa_len... " >&6; } if ${sc_cv_struct_sockaddr_salen+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct sockaddr sa;sa.sa_len=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_sockaddr_salen=yes else sc_cv_struct_sockaddr_salen=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_sockaddr_salen = yes; then $as_echo "#define HAVE_STRUCT_SOCKADDR_SALEN 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_sockaddr_salen" >&5 $as_echo "$sc_cv_struct_sockaddr_salen" >&6; } ### IP6 sockaddr_in6 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for component names of sockaddr_in6" >&5 $as_echo_n "checking for component names of sockaddr_in6... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct sockaddr_in6 sa6;sa6.sin6_addr.s6_addr[0]=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: s6_addr" >&5 $as_echo "s6_addr" >&6; }; $as_echo "#define HAVE_IP6_SOCKADDR 0" >>confdefs.h else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct sockaddr_in6 sa6;sa6.sin6_addr.u6_addr.u6_addr16[0]=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: u6_addr.u6_addr16" >&5 $as_echo "u6_addr.u6_addr16" >&6; }; $as_echo "#define HAVE_IP6_SOCKADDR 1" >>confdefs.h else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct sockaddr_in6 sa6;sa6.sin6_addr.u6_addr16[0]=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: u6_addr16" >&5 $as_echo "u6_addr16" >&6; }; $as_echo "#define HAVE_IP6_SOCKADDR 2" >>confdefs.h else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct sockaddr_in6 sa6;sa6.sin6_addr.in6_u.u6_addr16[0]=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: in6_u.u6_addr16" >&5 $as_echo "in6_u.u6_addr16" >&6; }; $as_echo "#define HAVE_IP6_SOCKADDR 3" >>confdefs.h else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct sockaddr_in6 sa6;sa6.sin6_addr._S6_un._S6_u32[0]=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: _S6_un._S6_u32" >&5 $as_echo "_S6_un._S6_u32" >&6; }; $as_echo "#define HAVE_IP6_SOCKADDR 4" >>confdefs.h else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct sockaddr_in6 sa6;sa6.sin6_addr.__u6_addr.__u6_addr32[0]=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: __u6_addr.__u6_addr32" >&5 $as_echo "__u6_addr.__u6_addr32" >&6; }; $as_echo "#define HAVE_IP6_SOCKADDR 5" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none or unknown" >&5 $as_echo "none or unknown" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct iovec" >&5 $as_echo_n "checking for struct iovec... " >&6; } if ${sc_cv_struct_iovec+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct iovec s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_iovec=yes else sc_cv_struct_iovec=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_iovec = yes; then $as_echo "#define HAVE_STRUCT_IOVEC 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_iovec" >&5 $as_echo "$sc_cv_struct_iovec" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct msghdr.msg_control" >&5 $as_echo_n "checking for struct msghdr.msg_control... " >&6; } if ${sc_cv_struct_msghdr_msgcontrol+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct msghdr s;s.msg_control=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_msghdr_msgcontrol=yes else sc_cv_struct_msghdr_msgcontrol=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_msghdr_msgcontrol = yes; then $as_echo "#define HAVE_STRUCT_MSGHDR_MSGCONTROL 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_msghdr_msgcontrol" >&5 $as_echo "$sc_cv_struct_msghdr_msgcontrol" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct msghdr.msg_controllen" >&5 $as_echo_n "checking for struct msghdr.msg_controllen... " >&6; } if ${sc_cv_struct_msghdr_msgcontrollen+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct msghdr s;s.msg_controllen=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_msghdr_msgcontrollen=yes else sc_cv_struct_msghdr_msgcontrollen=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_msghdr_msgcontrollen = yes; then $as_echo "#define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_msghdr_msgcontrollen" >&5 $as_echo "$sc_cv_struct_msghdr_msgcontrollen" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct msghdr.msgflags" >&5 $as_echo_n "checking for struct msghdr.msgflags... " >&6; } if ${sc_cv_struct_msghdr_msgflags+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct msghdr s;s.msg_flags=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_msghdr_msgflags=yes else sc_cv_struct_msghdr_msgflags=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_msghdr_msgflags = yes; then $as_echo "#define HAVE_STRUCT_MSGHDR_MSGFLAGS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_msghdr_msgflags" >&5 $as_echo "$sc_cv_struct_msghdr_msgflags" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct cmsghdr" >&5 $as_echo_n "checking for struct cmsghdr... " >&6; } if ${sc_cv_struct_cmsghdr+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct cmsghdr s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_cmsghdr=yes else sc_cv_struct_cmsghdr=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_cmsghdr = yes; then $as_echo "#define HAVE_STRUCT_CMSGHDR 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_cmsghdr" >&5 $as_echo "$sc_cv_struct_cmsghdr" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct in_pktinfo" >&5 $as_echo_n "checking for struct in_pktinfo... " >&6; } if ${sc_cv_struct_in_pktinfo+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct in_pktinfo s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_in_pktinfo=yes else sc_cv_struct_in_pktinfo=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_in_pktinfo = yes; then $as_echo "#define HAVE_STRUCT_IN_PKTINFO 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_in_pktinfo" >&5 $as_echo "$sc_cv_struct_in_pktinfo" >&6; } if test $sc_cv_struct_in_pktinfo = 'yes'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ipi_spec_dst in struct in_pktinfo" >&5 $as_echo_n "checking for ipi_spec_dst in struct in_pktinfo... " >&6; } if ${sc_cv_pktinfo_ipi_spec_dst+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct in_pktinfo s; s.ipi_spec_dst ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_pktinfo_ipi_spec_dst=yes else sc_cv_pktinfo_ipi_spec_dst=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_pktinfo_ipi_spec_dst = yes; then $as_echo "#define HAVE_PKTINFO_IPI_SPEC_DST 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_pktinfo_ipi_spec_dst" >&5 $as_echo "$sc_cv_pktinfo_ipi_spec_dst" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct in6_pktinfo" >&5 $as_echo_n "checking for struct in6_pktinfo... " >&6; } if ${sc_cv_struct_in6_pktinfo+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { struct in6_pktinfo s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_in6_pktinfo=yes else sc_cv_struct_in6_pktinfo=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_in6_pktinfo = yes; then $as_echo "#define HAVE_STRUCT_IN6_PKTINFO 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_in6_pktinfo" >&5 $as_echo "$sc_cv_struct_in6_pktinfo" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct ip.ip_hl" >&5 $as_echo_n "checking for struct ip.ip_hl... " >&6; } if ${sc_cv_struct_ip_ip_hl+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { struct ip s;s.ip_hl=0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_struct_ip_ip_hl=yes else sc_cv_struct_ip_ip_hl=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_struct_ip_ip_hl = yes; then $as_echo "#define HAVE_STRUCT_IP_IP_HL 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_struct_ip_ip_hl" >&5 $as_echo "$sc_cv_struct_ip_ip_hl" >&6; } ac_fn_c_check_func "$LINENO" "sigaction" "ac_cv_func_sigaction" if test "x$ac_cv_func_sigaction" = xyes; then : $as_echo "#define HAVE_SIGACTION 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "stat64" "ac_cv_func_stat64" if test "x$ac_cv_func_stat64" = xyes; then : $as_echo "#define HAVE_STAT64 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "fstat64" "ac_cv_func_fstat64" if test "x$ac_cv_func_fstat64" = xyes; then : $as_echo "#define HAVE_FSTAT64 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "lstat64" "ac_cv_func_lstat64" if test "x$ac_cv_func_lstat64" = xyes; then : $as_echo "#define HAVE_LSTAT64 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "lseek64" "ac_cv_func_lseek64" if test "x$ac_cv_func_lseek64" = xyes; then : $as_echo "#define HAVE_LSEEK64 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "truncate64" "ac_cv_func_truncate64" if test "x$ac_cv_func_truncate64" = xyes; then : $as_echo "#define HAVE_TRUNCATE64 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "ftruncate64" "ac_cv_func_ftruncate64" if test "x$ac_cv_func_ftruncate64" = xyes; then : $as_echo "#define HAVE_FTRUNCATE64 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strtoll" "ac_cv_func_strtoll" if test "x$ac_cv_func_strtoll" = xyes; then : $as_echo "#define HAVE_STRTOLL 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "hstrerror" "ac_cv_func_hstrerror" if test "x$ac_cv_func_hstrerror" = xyes; then : $as_echo "#define HAVE_HSTRERROR 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "inet_ntop" "ac_cv_func_inet_ntop" if test "x$ac_cv_func_inet_ntop" = xyes; then : $as_echo "#define HAVE_INET_NTOP 1" >>confdefs.h fi #if test "$ac_cv_func_hstrerror" = "yes"; then # AC_MSG_CHECKING(if _XOPEN_SOURCE_EXTENDED is helpful) # AC_CACHE_VAL(ac_cv_xopen_source_extended, # [AC_TRY_COMPILE([#include ], # [hstrerror()], # [ac_cv_xopen_source_extended=no], # [AC_TRY_COMPILE([#define _XOPEN_SOURCE_EXTENDED 1 ## include ], # [hstrerror()], # [ac_cv_xopen_source_extended=yes], # [ac_cv_xopen_source_extended=no] # )] # )]) # if test $ac_cv_xopen_source_extended = yes; then # AC_DEFINE(_XOPEN_SOURCE_EXTENDED) # fi # AC_MSG_RESULT($ac_cv_xopen_source_extended) #fi # MacOS ac_fn_c_check_func "$LINENO" "openpty" "ac_cv_func_openpty" if test "x$ac_cv_func_openpty" = xyes; then : $as_echo "#define HAVE_OPENPTY 1" >>confdefs.h fi # AIX { $as_echo "$as_me:${as_lineno-$LINENO}: checking for openpty in -lbsd" >&5 $as_echo_n "checking for openpty in -lbsd... " >&6; } if ${ac_cv_lib_bsd_openpty+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char openpty (); int main () { return openpty (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_bsd_openpty=yes else ac_cv_lib_bsd_openpty=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_openpty" >&5 $as_echo "$ac_cv_lib_bsd_openpty" >&6; } if test "x$ac_cv_lib_bsd_openpty" = xyes; then : LIBS="-lbsd $LIBS"; $as_echo "#define HAVE_OPENPTY 1" >>confdefs.h fi # Linux 2.4 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for openpty in -lutil" >&5 $as_echo_n "checking for openpty in -lutil... " >&6; } if ${ac_cv_lib_util_openpty+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lutil $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char openpty (); int main () { return openpty (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_util_openpty=yes else ac_cv_lib_util_openpty=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_openpty" >&5 $as_echo "$ac_cv_lib_util_openpty" >&6; } if test "x$ac_cv_lib_util_openpty" = xyes; then : LIBS="-lutil $LIBS"; $as_echo "#define HAVE_OPENPTY 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 $as_echo_n "checking for clock_gettime in -lrt... " >&6; } if ${ac_cv_lib_rt_clock_gettime+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char clock_gettime (); int main () { return clock_gettime (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_clock_gettime=yes else ac_cv_lib_rt_clock_gettime=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 $as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then : LIBS="-lrt $LIBS"; $as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h fi # with Linux it's in libc, with AIX in libbsd ac_fn_c_check_func "$LINENO" "flock" "ac_cv_func_flock" if test "x$ac_cv_func_flock" = xyes; then : $as_echo "#define HAVE_FLOCK 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5 $as_echo_n "checking for flock in -lbsd... " >&6; } if ${ac_cv_lib_bsd_flock+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char flock (); int main () { return flock (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_bsd_flock=yes else ac_cv_lib_bsd_flock=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_flock" >&5 $as_echo "$ac_cv_lib_bsd_flock" >&6; } if test "x$ac_cv_lib_bsd_flock" = xyes; then : LIBS="-lbsd $LIBS" fi fi ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv" if test "x$ac_cv_func_setenv" = xyes; then : $as_echo "#define HAVE_SETENV 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setenv in -lisode" >&5 $as_echo_n "checking for setenv in -lisode... " >&6; } if ${ac_cv_lib_isode_setenv+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lisode $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char setenv (); int main () { return setenv (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_isode_setenv=yes else ac_cv_lib_isode_setenv=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_isode_setenv" >&5 $as_echo "$ac_cv_lib_isode_setenv" >&6; } if test "x$ac_cv_lib_isode_setenv" = xyes; then : LIBS="-lisode $LIBS" fi fi ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv" if test "x$ac_cv_func_unsetenv" = xyes; then : $as_echo "#define HAVE_UNSETENV 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "SSLv2_client_method" "ac_cv_func_SSLv2_client_method" if test "x$ac_cv_func_SSLv2_client_method" = xyes; then : $as_echo "#define HAVE_SSLv2_client_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSLv2_client_method in -lcrypt" >&5 $as_echo_n "checking for SSLv2_client_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_SSLv2_client_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SSLv2_client_method (); int main () { return SSLv2_client_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_SSLv2_client_method=yes else ac_cv_lib_crypt_SSLv2_client_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_SSLv2_client_method" >&5 $as_echo "$ac_cv_lib_crypt_SSLv2_client_method" >&6; } if test "x$ac_cv_lib_crypt_SSLv2_client_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi ac_fn_c_check_func "$LINENO" "SSLv2_server_method" "ac_cv_func_SSLv2_server_method" if test "x$ac_cv_func_SSLv2_server_method" = xyes; then : $as_echo "#define HAVE_SSLv2_server_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSLv2_server_method in -lcrypt" >&5 $as_echo_n "checking for SSLv2_server_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_SSLv2_server_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SSLv2_server_method (); int main () { return SSLv2_server_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_SSLv2_server_method=yes else ac_cv_lib_crypt_SSLv2_server_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_SSLv2_server_method" >&5 $as_echo "$ac_cv_lib_crypt_SSLv2_server_method" >&6; } if test "x$ac_cv_lib_crypt_SSLv2_server_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi ac_fn_c_check_func "$LINENO" "SSL_CTX_set_default_verify_paths" "ac_cv_func_SSL_CTX_set_default_verify_paths" if test "x$ac_cv_func_SSL_CTX_set_default_verify_paths" = xyes; then : $as_echo "#define HAVE_SSL_CTX_set_default_verify_paths 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "SSLv3_client_method" "ac_cv_func_SSLv3_client_method" if test "x$ac_cv_func_SSLv3_client_method" = xyes; then : $as_echo "#define HAVE_SSLv3_client_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSLv3_client_method in -lcrypt" >&5 $as_echo_n "checking for SSLv3_client_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_SSLv3_client_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SSLv3_client_method (); int main () { return SSLv3_client_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_SSLv3_client_method=yes else ac_cv_lib_crypt_SSLv3_client_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_SSLv3_client_method" >&5 $as_echo "$ac_cv_lib_crypt_SSLv3_client_method" >&6; } if test "x$ac_cv_lib_crypt_SSLv3_client_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi ac_fn_c_check_func "$LINENO" "SSLv3_server_method" "ac_cv_func_SSLv3_server_method" if test "x$ac_cv_func_SSLv3_server_method" = xyes; then : $as_echo "#define HAVE_SSLv3_server_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSLv3_server_method in -lcrypt" >&5 $as_echo_n "checking for SSLv3_server_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_SSLv3_server_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SSLv3_server_method (); int main () { return SSLv3_server_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_SSLv3_server_method=yes else ac_cv_lib_crypt_SSLv3_server_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_SSLv3_server_method" >&5 $as_echo "$ac_cv_lib_crypt_SSLv3_server_method" >&6; } if test "x$ac_cv_lib_crypt_SSLv3_server_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi ac_fn_c_check_func "$LINENO" "SSLv23_client_method" "ac_cv_func_SSLv23_client_method" if test "x$ac_cv_func_SSLv23_client_method" = xyes; then : $as_echo "#define HAVE_SSLv23_client_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSLv23_client_method in -lcrypt" >&5 $as_echo_n "checking for SSLv23_client_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_SSLv23_client_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SSLv23_client_method (); int main () { return SSLv23_client_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_SSLv23_client_method=yes else ac_cv_lib_crypt_SSLv23_client_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_SSLv23_client_method" >&5 $as_echo "$ac_cv_lib_crypt_SSLv23_client_method" >&6; } if test "x$ac_cv_lib_crypt_SSLv23_client_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi ac_fn_c_check_func "$LINENO" "SSLv23_server_method" "ac_cv_func_SSLv23_server_method" if test "x$ac_cv_func_SSLv23_server_method" = xyes; then : $as_echo "#define HAVE_SSLv23_server_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSLv23_server_method in -lcrypt" >&5 $as_echo_n "checking for SSLv23_server_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_SSLv23_server_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SSLv23_server_method (); int main () { return SSLv23_server_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_SSLv23_server_method=yes else ac_cv_lib_crypt_SSLv23_server_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_SSLv23_server_method" >&5 $as_echo "$ac_cv_lib_crypt_SSLv23_server_method" >&6; } if test "x$ac_cv_lib_crypt_SSLv23_server_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi ac_fn_c_check_func "$LINENO" "TLSv1_client_method" "ac_cv_func_TLSv1_client_method" if test "x$ac_cv_func_TLSv1_client_method" = xyes; then : $as_echo "#define HAVE_TLSv1_client_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TLSv1_client_method in -lcrypt" >&5 $as_echo_n "checking for TLSv1_client_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_TLSv1_client_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char TLSv1_client_method (); int main () { return TLSv1_client_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_TLSv1_client_method=yes else ac_cv_lib_crypt_TLSv1_client_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_TLSv1_client_method" >&5 $as_echo "$ac_cv_lib_crypt_TLSv1_client_method" >&6; } if test "x$ac_cv_lib_crypt_TLSv1_client_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi ac_fn_c_check_func "$LINENO" "TLSv1_server_method" "ac_cv_func_TLSv1_server_method" if test "x$ac_cv_func_TLSv1_server_method" = xyes; then : $as_echo "#define HAVE_TLSv1_server_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TLSv1_server_method in -lcrypt" >&5 $as_echo_n "checking for TLSv1_server_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_TLSv1_server_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char TLSv1_server_method (); int main () { return TLSv1_server_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_TLSv1_server_method=yes else ac_cv_lib_crypt_TLSv1_server_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_TLSv1_server_method" >&5 $as_echo "$ac_cv_lib_crypt_TLSv1_server_method" >&6; } if test "x$ac_cv_lib_crypt_TLSv1_server_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi ac_fn_c_check_func "$LINENO" "TLSv1_1_client_method" "ac_cv_func_TLSv1_1_client_method" if test "x$ac_cv_func_TLSv1_1_client_method" = xyes; then : $as_echo "#define HAVE_TLSv1_1_client_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TLSv1_1_client_method in -lcrypt" >&5 $as_echo_n "checking for TLSv1_1_client_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_TLSv1_1_client_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char TLSv1_1_client_method (); int main () { return TLSv1_1_client_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_TLSv1_1_client_method=yes else ac_cv_lib_crypt_TLSv1_1_client_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_TLSv1_1_client_method" >&5 $as_echo "$ac_cv_lib_crypt_TLSv1_1_client_method" >&6; } if test "x$ac_cv_lib_crypt_TLSv1_1_client_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi ac_fn_c_check_func "$LINENO" "TLSv1_1_server_method" "ac_cv_func_TLSv1_1_server_method" if test "x$ac_cv_func_TLSv1_1_server_method" = xyes; then : $as_echo "#define HAVE_TLSv1_1_server_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TLSv1_1_server_method in -lcrypt" >&5 $as_echo_n "checking for TLSv1_1_server_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_TLSv1_1_server_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char TLSv1_1_server_method (); int main () { return TLSv1_1_server_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_TLSv1_1_server_method=yes else ac_cv_lib_crypt_TLSv1_1_server_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_TLSv1_1_server_method" >&5 $as_echo "$ac_cv_lib_crypt_TLSv1_1_server_method" >&6; } if test "x$ac_cv_lib_crypt_TLSv1_1_server_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi ac_fn_c_check_func "$LINENO" "TLSv1_2_client_method" "ac_cv_func_TLSv1_2_client_method" if test "x$ac_cv_func_TLSv1_2_client_method" = xyes; then : $as_echo "#define HAVE_TLSv1_2_client_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TLSv1_2_client_method in -lcrypt" >&5 $as_echo_n "checking for TLSv1_2_client_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_TLSv1_2_client_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char TLSv1_2_client_method (); int main () { return TLSv1_2_client_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_TLSv1_2_client_method=yes else ac_cv_lib_crypt_TLSv1_2_client_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_TLSv1_2_client_method" >&5 $as_echo "$ac_cv_lib_crypt_TLSv1_2_client_method" >&6; } if test "x$ac_cv_lib_crypt_TLSv1_2_client_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi ac_fn_c_check_func "$LINENO" "TLSv1_2_server_method" "ac_cv_func_TLSv1_2_server_method" if test "x$ac_cv_func_TLSv1_2_server_method" = xyes; then : $as_echo "#define HAVE_TLSv1_2_server_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TLSv1_2_server_method in -lcrypt" >&5 $as_echo_n "checking for TLSv1_2_server_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_TLSv1_2_server_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char TLSv1_2_server_method (); int main () { return TLSv1_2_server_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_TLSv1_2_server_method=yes else ac_cv_lib_crypt_TLSv1_2_server_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_TLSv1_2_server_method" >&5 $as_echo "$ac_cv_lib_crypt_TLSv1_2_server_method" >&6; } if test "x$ac_cv_lib_crypt_TLSv1_2_server_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi ac_fn_c_check_func "$LINENO" "DTLSv1_client_method" "ac_cv_func_DTLSv1_client_method" if test "x$ac_cv_func_DTLSv1_client_method" = xyes; then : $as_echo "#define HAVE_DTLSv1_client_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DTLSv1_client_method in -lcrypt" >&5 $as_echo_n "checking for DTLSv1_client_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_DTLSv1_client_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char DTLSv1_client_method (); int main () { return DTLSv1_client_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_DTLSv1_client_method=yes else ac_cv_lib_crypt_DTLSv1_client_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_DTLSv1_client_method" >&5 $as_echo "$ac_cv_lib_crypt_DTLSv1_client_method" >&6; } if test "x$ac_cv_lib_crypt_DTLSv1_client_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi ac_fn_c_check_func "$LINENO" "DTLSv1_server_method" "ac_cv_func_DTLSv1_server_method" if test "x$ac_cv_func_DTLSv1_server_method" = xyes; then : $as_echo "#define HAVE_DTLSv1_server_method 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DTLSv1_server_method in -lcrypt" >&5 $as_echo_n "checking for DTLSv1_server_method in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_DTLSv1_server_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char DTLSv1_server_method (); int main () { return DTLSv1_server_method (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_DTLSv1_server_method=yes else ac_cv_lib_crypt_DTLSv1_server_method=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_DTLSv1_server_method" >&5 $as_echo "$ac_cv_lib_crypt_DTLSv1_server_method" >&6; } if test "x$ac_cv_lib_crypt_DTLSv1_server_method" = xyes; then : LIBS=-lcrypt $LIBS fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if snprintf conforms to C99" >&5 $as_echo_n "checking if snprintf conforms to C99... " >&6; } if ${ac_cv_have_c99_snprintf+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_have_c99_snprintf=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main(void){ char s[2]; exit(snprintf(s,2,"ab")!=2); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_have_c99_snprintf=yes else ac_cv_have_c99_snprintf=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi if test $ac_cv_have_c99_snprintf = yes; then $as_echo "#define HAVE_C99_SNPRINTF 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_c99_snprintf" >&5 $as_echo "$ac_cv_have_c99_snprintf" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if printf has Z modifier" >&5 $as_echo_n "checking if printf has Z modifier... " >&6; } if ${ac_cv_have_z_modifier+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cc" = gcc; then if test "$cross_compiling" = yes; then : ac_cv_have_z_modifier=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main(void){ char s[16]; sprintf(s,"%Zu",1); exit(strcmp(s,"1")); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_have_z_modifier=yes else ac_cv_have_z_modifier=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else ac_cv_have_z_modifier=no fi fi if test $ac_cv_have_z_modifier = yes; then $as_echo "#define HAVE_FORMAT_Z 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_z_modifier" >&5 $as_echo "$ac_cv_have_z_modifier" >&6; } ## NOTE: some platforms only need one '\' to escape '"' in string constant { $as_echo "$as_me:${as_lineno-$LINENO}: checking shift offset of CRDLY" >&5 $as_echo_n "checking shift offset of CRDLY... " >&6; } if ${sc_cv_sys_crdly_shift+:} false; then : $as_echo_n "(cached) " >&6 else LIBS1="$LIBS"; LIBS="" # avoid libwrap allow_severity undefined conftestoffset="conftestoffset.out" if test "$cross_compiling" = yes; then : sc_cv_sys_crdly_shift=-1 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include int main(){ unsigned int i,n=CRDLY; FILE *f; if ((f=fopen("$conftestoffset","w"))==NULL){ fprintf(stderr,"\\"$conftestoffset\\": %s\n",strerror(errno)); exit(-1); } if (n==0) {fprintf(stderr,"CRDLY is 0 (impossible!)\n"); exit(1);} i=0; while (!(n&1)) { n>>=1; ++i; } if (3<&5 $as_echo "$sc_cv_sys_crdly_shift" >&6; } cat >>confdefs.h <<_ACEOF #define CRDLY_SHIFT ${sc_cv_sys_crdly_shift} _ACEOF if test "sc_cv_sys_crdly_shift" = -1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: please determine CRDLY_SHIFT manually" >&5 $as_echo "$as_me: WARNING: please determine CRDLY_SHIFT manually" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking shift offset of TABDLY" >&5 $as_echo_n "checking shift offset of TABDLY... " >&6; } if ${sc_cv_sys_tabdly_shift+:} false; then : $as_echo_n "(cached) " >&6 else LIBS1="$LIBS"; LIBS="" # avoid libwrap allow_severity undefined conftestoffset="conftestoffset.out" if test "$cross_compiling" = yes; then : sc_cv_sys_tabdly_shift=-1 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include int main(){ unsigned int i,n=TABDLY; FILE *f; if ((f=fopen("$conftestoffset","w"))==NULL){ fprintf(stderr,"\\"$conftestoffset\\": %s\n",strerror(errno)); exit(-1); } if (n==0) {fprintf(stderr,"TABDLY is 0 (impossible!)\n"); exit(1);} i=0; while (!(n&1)) { n>>=1; ++i; } if (3<&5 $as_echo "$sc_cv_sys_tabdly_shift" >&6; } cat >>confdefs.h <<_ACEOF #define TABDLY_SHIFT ${sc_cv_sys_tabdly_shift} _ACEOF if test "sc_cv_sys_tabdly_shift" = -1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: please determine TABDLY_SHIFT manually" >&5 $as_echo "$as_me: WARNING: please determine TABDLY_SHIFT manually" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking shift offset of CSIZE" >&5 $as_echo_n "checking shift offset of CSIZE... " >&6; } if ${sc_cv_sys_csize_shift+:} false; then : $as_echo_n "(cached) " >&6 else LIBS1="$LIBS"; LIBS="" # avoid libwrap allow_severity undefined conftestoffset="conftestoffset.out" if test "$cross_compiling" = yes; then : sc_cv_sys_csize_shift=-1 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include int main(){ unsigned int i,n=CSIZE; FILE *f; if ((f=fopen("$conftestoffset","w"))==NULL){ fprintf(stderr,"\\"$conftestoffset\\": %s\n",strerror(errno)); exit(-1); } if (n==0) {fprintf(stderr,"CSIZE is 0 (impossible!)\n"); exit(1);} i=0; while (!(n&1)) { n>>=1; ++i; } if (3<&5 $as_echo "$sc_cv_sys_csize_shift" >&6; } cat >>confdefs.h <<_ACEOF #define CSIZE_SHIFT ${sc_cv_sys_csize_shift} _ACEOF if test "sc_cv_sys_csize_shift" = -1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: please determine CSIZE_SHIFT manually" >&5 $as_echo "$as_me: WARNING: please determine CSIZE_SHIFT manually" >&2;} fi CHANCE_TO_TYPECHECK=1 CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int u; int v; exit(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else CHANCE_TO_TYPECHECK=0 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" if test "$CHANCE_TO_TYPECHECK" -ne 0; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int u; unsigned int v; exit(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else CHANCE_TO_TYPECHECK=0 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int u; unsigned int v; exit(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : CHANCE_TO_TYPECHECK=0 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: using compile -Werror method to find basic types" >&5 $as_echo "$as_me: using compile -Werror method to find basic types" >&6;} else { $as_echo "$as_me:${as_lineno-$LINENO}: using code run method to find basic types" >&5 $as_echo "$as_me: using code run method to find basic types" >&6;} fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of size_t" >&5 $as_echo_n "checking for equivalent simple type of size_t... " >&6; } if ${sc_cv_type_sizet_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { size_t u; short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_sizet_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { size_t u; unsigned short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_sizet_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { size_t u; int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_sizet_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { size_t u; unsigned int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_sizet_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { size_t u; long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_sizet_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { size_t u; unsigned long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_sizet_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { size_t u; long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_sizet_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { size_t u; unsigned long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_sizet_basic="8 /* unsigned long long */" else sc_cv_type_sizet_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_sizet_basic" >&5 $as_echo "$sc_cv_type_sizet_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_SIZE_T ${sc_cv_type_sizet_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of size_t" >&5 $as_echo_n "checking for equivalent simple type of size_t... " >&6; } if ${sc_cv_type_sizet_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { return!(sizeof(size_t)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { size_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_sizet_basic="1 /* short */" else sc_cv_type_sizet_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { return!(sizeof(size_t)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { size_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_sizet_basic="3 /* int */" else sc_cv_type_sizet_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { return !(sizeof(size_t)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { size_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_sizet_basic="5 /* long */" else sc_cv_type_sizet_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { return !(sizeof(size_t)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { size_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_sizet_basic="7 /* long long */" else sc_cv_type_sizet_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_sizet_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_sizet_basic" >&5 $as_echo "$sc_cv_type_sizet_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_SIZE_T ${sc_cv_type_sizet_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of mode_t" >&5 $as_echo_n "checking for equivalent simple type of mode_t... " >&6; } if ${sc_cv_type_modet_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { mode_t u; short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_modet_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { mode_t u; unsigned short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_modet_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { mode_t u; int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_modet_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { mode_t u; unsigned int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_modet_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { mode_t u; long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_modet_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { mode_t u; unsigned long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_modet_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { mode_t u; long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_modet_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { mode_t u; unsigned long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_modet_basic="8 /* unsigned long long */" else sc_cv_type_modet_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_modet_basic" >&5 $as_echo "$sc_cv_type_modet_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_MODE_T ${sc_cv_type_modet_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of mode_t" >&5 $as_echo_n "checking for equivalent simple type of mode_t... " >&6; } if ${sc_cv_type_modet_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { return!(sizeof(mode_t)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { mode_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_modet_basic="1 /* short */" else sc_cv_type_modet_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { return!(sizeof(mode_t)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { mode_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_modet_basic="3 /* int */" else sc_cv_type_modet_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { return !(sizeof(mode_t)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { mode_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_modet_basic="5 /* long */" else sc_cv_type_modet_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { return !(sizeof(mode_t)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { mode_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_modet_basic="7 /* long long */" else sc_cv_type_modet_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_modet_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_modet_basic" >&5 $as_echo "$sc_cv_type_modet_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_MODE_T ${sc_cv_type_modet_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of pid_t" >&5 $as_echo_n "checking for equivalent simple type of pid_t... " >&6; } if ${sc_cv_type_pidt_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { pid_t u; short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_pidt_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { pid_t u; unsigned short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_pidt_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { pid_t u; int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_pidt_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { pid_t u; unsigned int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_pidt_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { pid_t u; long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_pidt_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { pid_t u; unsigned long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_pidt_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { pid_t u; long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_pidt_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { pid_t u; unsigned long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_pidt_basic="8 /* unsigned long long */" else sc_cv_type_pidt_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_pidt_basic" >&5 $as_echo "$sc_cv_type_pidt_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_PID_T ${sc_cv_type_pidt_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of pid_t" >&5 $as_echo_n "checking for equivalent simple type of pid_t... " >&6; } if ${sc_cv_type_pidt_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return!(sizeof(pid_t)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { pid_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_pidt_basic="1 /* short */" else sc_cv_type_pidt_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return!(sizeof(pid_t)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { pid_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_pidt_basic="3 /* int */" else sc_cv_type_pidt_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return !(sizeof(pid_t)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { pid_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_pidt_basic="5 /* long */" else sc_cv_type_pidt_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return !(sizeof(pid_t)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { pid_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_pidt_basic="7 /* long long */" else sc_cv_type_pidt_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_pidt_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_pidt_basic" >&5 $as_echo "$sc_cv_type_pidt_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_PID_T ${sc_cv_type_pidt_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of uid_t" >&5 $as_echo_n "checking for equivalent simple type of uid_t... " >&6; } if ${sc_cv_type_uidt_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { uid_t u; short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_uidt_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { uid_t u; unsigned short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_uidt_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { uid_t u; int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_uidt_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { uid_t u; unsigned int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_uidt_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { uid_t u; long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_uidt_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { uid_t u; unsigned long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_uidt_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { uid_t u; long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_uidt_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { uid_t u; unsigned long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_uidt_basic="8 /* unsigned long long */" else sc_cv_type_uidt_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_uidt_basic" >&5 $as_echo "$sc_cv_type_uidt_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_UID_T ${sc_cv_type_uidt_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of uid_t" >&5 $as_echo_n "checking for equivalent simple type of uid_t... " >&6; } if ${sc_cv_type_uidt_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return!(sizeof(uid_t)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { uid_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_uidt_basic="1 /* short */" else sc_cv_type_uidt_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return!(sizeof(uid_t)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { uid_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_uidt_basic="3 /* int */" else sc_cv_type_uidt_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return !(sizeof(uid_t)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { uid_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_uidt_basic="5 /* long */" else sc_cv_type_uidt_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return !(sizeof(uid_t)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { uid_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_uidt_basic="7 /* long long */" else sc_cv_type_uidt_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_uidt_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_uidt_basic" >&5 $as_echo "$sc_cv_type_uidt_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_UID_T ${sc_cv_type_uidt_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of gid_t" >&5 $as_echo_n "checking for equivalent simple type of gid_t... " >&6; } if ${sc_cv_type_gidt_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { gid_t u; short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_gidt_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { gid_t u; unsigned short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_gidt_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { gid_t u; int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_gidt_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { gid_t u; unsigned int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_gidt_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { gid_t u; long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_gidt_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { gid_t u; unsigned long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_gidt_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { gid_t u; long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_gidt_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { gid_t u; unsigned long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_gidt_basic="8 /* unsigned long long */" else sc_cv_type_gidt_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_gidt_basic" >&5 $as_echo "$sc_cv_type_gidt_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_GID_T ${sc_cv_type_gidt_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of gid_t" >&5 $as_echo_n "checking for equivalent simple type of gid_t... " >&6; } if ${sc_cv_type_gidt_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return!(sizeof(gid_t)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { gid_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_gidt_basic="1 /* short */" else sc_cv_type_gidt_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return!(sizeof(gid_t)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { gid_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_gidt_basic="3 /* int */" else sc_cv_type_gidt_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return !(sizeof(gid_t)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { gid_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_gidt_basic="5 /* long */" else sc_cv_type_gidt_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return !(sizeof(gid_t)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { gid_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_gidt_basic="7 /* long long */" else sc_cv_type_gidt_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_gidt_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_gidt_basic" >&5 $as_echo "$sc_cv_type_gidt_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_GID_T ${sc_cv_type_gidt_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of time_t" >&5 $as_echo_n "checking for equivalent simple type of time_t... " >&6; } if ${sc_cv_type_timet_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { time_t u; short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_timet_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { time_t u; unsigned short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_timet_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { time_t u; int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_timet_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { time_t u; unsigned int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_timet_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { time_t u; long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_timet_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { time_t u; unsigned long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_timet_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { time_t u; long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_timet_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { time_t u; unsigned long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_timet_basic="8 /* unsigned long long */" else sc_cv_type_timet_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_timet_basic" >&5 $as_echo "$sc_cv_type_timet_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_TIME_T ${sc_cv_type_timet_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of time_t" >&5 $as_echo_n "checking for equivalent simple type of time_t... " >&6; } if ${sc_cv_type_timet_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { return!(sizeof(time_t)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { time_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_timet_basic="1 /* short */" else sc_cv_type_timet_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { return!(sizeof(time_t)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { time_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_timet_basic="3 /* int */" else sc_cv_type_timet_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { return !(sizeof(time_t)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { time_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_timet_basic="5 /* long */" else sc_cv_type_timet_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { return !(sizeof(time_t)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { time_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_timet_basic="7 /* long long */" else sc_cv_type_timet_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_timet_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_timet_basic" >&5 $as_echo "$sc_cv_type_timet_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_TIME_T ${sc_cv_type_timet_basic} _ACEOF fi # this is questionable, might fail on some systems if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of socklen_t" >&5 $as_echo_n "checking for equivalent simple type of socklen_t... " >&6; } if ${sc_cv_type_socklent_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { socklen_t u; short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_socklent_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { socklen_t u; unsigned short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_socklent_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { socklen_t u; int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_socklent_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { socklen_t u; unsigned int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_socklent_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { socklen_t u; long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_socklent_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { socklen_t u; unsigned long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_socklent_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { socklen_t u; long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_socklent_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { socklen_t u; unsigned long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_socklent_basic="8 /* unsigned long long */" else sc_cv_type_socklent_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_socklent_basic" >&5 $as_echo "$sc_cv_type_socklent_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_SOCKLEN_T ${sc_cv_type_socklent_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of socklen_t" >&5 $as_echo_n "checking for equivalent simple type of socklen_t... " >&6; } if ${sc_cv_type_socklent_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { return!(sizeof(socklen_t)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { socklen_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_socklent_basic="1 /* short */" else sc_cv_type_socklent_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { return!(sizeof(socklen_t)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { socklen_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_socklent_basic="3 /* int */" else sc_cv_type_socklent_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { return !(sizeof(socklen_t)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { socklen_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_socklent_basic="5 /* long */" else sc_cv_type_socklent_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { return !(sizeof(socklen_t)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { socklen_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_socklent_basic="7 /* long long */" else sc_cv_type_socklent_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_socklent_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_socklent_basic" >&5 $as_echo "$sc_cv_type_socklent_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_SOCKLEN_T ${sc_cv_type_socklent_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of off_t" >&5 $as_echo_n "checking for equivalent simple type of off_t... " >&6; } if ${sc_cv_type_off_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off_t u; short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off_t u; unsigned short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off_t u; int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off_t u; unsigned int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off_t u; long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off_t u; unsigned long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off_t u; long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off_t u; unsigned long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off_basic="8 /* unsigned long long */" else sc_cv_type_off_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_off_basic" >&5 $as_echo "$sc_cv_type_off_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_OFF_T ${sc_cv_type_off_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of off_t" >&5 $as_echo_n "checking for equivalent simple type of off_t... " >&6; } if ${sc_cv_type_off_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return!(sizeof(off_t)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { off_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_off_basic="1 /* short */" else sc_cv_type_off_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return!(sizeof(off_t)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { off_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_off_basic="3 /* int */" else sc_cv_type_off_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return !(sizeof(off_t)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { off_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_off_basic="5 /* long */" else sc_cv_type_off_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return !(sizeof(off_t)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { off_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_off_basic="7 /* long long */" else sc_cv_type_off_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_off_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_off_basic" >&5 $as_echo "$sc_cv_type_off_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_OFF_T ${sc_cv_type_off_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of off64_t" >&5 $as_echo_n "checking for equivalent simple type of off64_t... " >&6; } if ${sc_cv_type_off64_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off64_t u; short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off64_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off64_t u; unsigned short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off64_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off64_t u; int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off64_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off64_t u; unsigned int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off64_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off64_t u; long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off64_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off64_t u; unsigned long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off64_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off64_t u; long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off64_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off64_t u; unsigned long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_off64_basic="8 /* unsigned long long */" else sc_cv_type_off64_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_off64_basic" >&5 $as_echo "$sc_cv_type_off64_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_OFF64_T ${sc_cv_type_off64_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of off64_t" >&5 $as_echo_n "checking for equivalent simple type of off64_t... " >&6; } if ${sc_cv_type_off64_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return!(sizeof(off64_t)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { off64_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_off64_basic="1 /* short */" else sc_cv_type_off64_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return!(sizeof(off64_t)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { off64_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_off64_basic="3 /* int */" else sc_cv_type_off64_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return !(sizeof(off64_t)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { off64_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_off64_basic="5 /* long */" else sc_cv_type_off64_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { return !(sizeof(off64_t)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { off64_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_off64_basic="7 /* long long */" else sc_cv_type_off64_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_off64_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_off64_basic" >&5 $as_echo "$sc_cv_type_off64_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_OFF64_T ${sc_cv_type_off64_basic} _ACEOF fi # oh god, __dev_t in Linux 2.4 is struct{int[2];}, not handled here yet. if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of dev_t" >&5 $as_echo_n "checking for equivalent simple type of dev_t... " >&6; } if ${sc_cv_type_dev_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { dev_t u; short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_dev_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { dev_t u; unsigned short v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_dev_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { dev_t u; int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_dev_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { dev_t u; unsigned int v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_dev_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { dev_t u; long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_dev_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { dev_t u; unsigned long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_dev_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { dev_t u; long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_dev_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { dev_t u; unsigned long long v; return(&u==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_dev_basic="8 /* unsigned long long */" else sc_cv_type_dev_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_dev_basic" >&5 $as_echo "$sc_cv_type_dev_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_DEV_T ${sc_cv_type_dev_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for equivalent simple type of dev_t" >&5 $as_echo_n "checking for equivalent simple type of dev_t... " >&6; } if ${sc_cv_type_dev_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { return!(sizeof(dev_t)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { dev_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_dev_basic="1 /* short */" else sc_cv_type_dev_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { return!(sizeof(dev_t)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { dev_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_dev_basic="3 /* int */" else sc_cv_type_dev_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { return !(sizeof(dev_t)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { dev_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_dev_basic="5 /* long */" else sc_cv_type_dev_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { return !(sizeof(dev_t)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { dev_t x=-1; return !(x<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_dev_basic="7 /* long long */" else sc_cv_type_dev_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_dev_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_dev_basic" >&5 $as_echo "$sc_cv_type_dev_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_BASIC_DEV_T ${sc_cv_type_dev_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat.st_ino" >&5 $as_echo_n "checking for basic type of struct stat.st_ino... " >&6; } if ${sc_cv_type_stat_stino_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u;short v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stino_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned short v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stino_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; int v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stino_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned int v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stino_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; long v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stino_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned long v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stino_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; long long v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stino_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned long long v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stino_basic="8 /* unsigned long long */" else sc_cv_type_stat_stino_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat_stino_basic" >&5 $as_echo "$sc_cv_type_stat_stino_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST_INO ${sc_cv_type_stat_stino_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat.st_ino" >&5 $as_echo_n "checking for basic type of struct stat.st_ino... " >&6; } if ${sc_cv_type_stat_stino_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return!(sizeof(x.st_ino)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_ino=-1; return !(x.st_ino<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stino_basic="1 /* short */" else sc_cv_type_stat_stino_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return!(sizeof(x.st_ino)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_ino=-1; return !(x.st_ino<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stino_basic="3 /* int */" else sc_cv_type_stat_stino_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return !(sizeof(x.st_ino)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_ino=-1; return !(x.st_ino<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stino_basic="5 /* long */" else sc_cv_type_stat_stino_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return !(sizeof(x.st_ino)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { x struct stat; x.st_ino=-1; return !(x.st_ino<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stino_basic="7 /* long long */" else sc_cv_type_stat_stino_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_stat_stino_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat_stino_basic" >&5 $as_echo "$sc_cv_type_stat_stino_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST_INO ${sc_cv_type_stat_stino_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat.st_nlink" >&5 $as_echo_n "checking for basic type of struct stat.st_nlink... " >&6; } if ${sc_cv_type_stat_stnlink_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u;short v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stnlink_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned short v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stnlink_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; int v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stnlink_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned int v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stnlink_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; long v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stnlink_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned long v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stnlink_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; long long v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stnlink_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned long long v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stnlink_basic="8 /* unsigned long long */" else sc_cv_type_stat_stnlink_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat_stnlink_basic" >&5 $as_echo "$sc_cv_type_stat_stnlink_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST_NLINK ${sc_cv_type_stat_stnlink_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat.st_nlink" >&5 $as_echo_n "checking for basic type of struct stat.st_nlink... " >&6; } if ${sc_cv_type_stat_stnlink_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return!(sizeof(x.st_nlink)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_nlink=-1; return !(x.st_nlink<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stnlink_basic="1 /* short */" else sc_cv_type_stat_stnlink_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return!(sizeof(x.st_nlink)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_nlink=-1; return !(x.st_nlink<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stnlink_basic="3 /* int */" else sc_cv_type_stat_stnlink_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return !(sizeof(x.st_nlink)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_nlink=-1; return !(x.st_nlink<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stnlink_basic="5 /* long */" else sc_cv_type_stat_stnlink_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return !(sizeof(x.st_nlink)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { x struct stat; x.st_nlink=-1; return !(x.st_nlink<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stnlink_basic="7 /* long long */" else sc_cv_type_stat_stnlink_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_stat_stnlink_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat_stnlink_basic" >&5 $as_echo "$sc_cv_type_stat_stnlink_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST_NLINK ${sc_cv_type_stat_stnlink_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat.st_size" >&5 $as_echo_n "checking for basic type of struct stat.st_size... " >&6; } if ${sc_cv_type_stat_stsize_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u;short v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stsize_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned short v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stsize_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; int v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stsize_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned int v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stsize_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; long v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stsize_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned long v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stsize_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; long long v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stsize_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned long long v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stsize_basic="8 /* unsigned long long */" else sc_cv_type_stat_stsize_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat_stsize_basic" >&5 $as_echo "$sc_cv_type_stat_stsize_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST_SIZE ${sc_cv_type_stat_stsize_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat.st_size" >&5 $as_echo_n "checking for basic type of struct stat.st_size... " >&6; } if ${sc_cv_type_stat_stsize_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return!(sizeof(x.st_size)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_size=-1; return !(x.st_size<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stsize_basic="1 /* short */" else sc_cv_type_stat_stsize_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return!(sizeof(x.st_size)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_size=-1; return !(x.st_size<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stsize_basic="3 /* int */" else sc_cv_type_stat_stsize_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return !(sizeof(x.st_size)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_size=-1; return !(x.st_size<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stsize_basic="5 /* long */" else sc_cv_type_stat_stsize_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return !(sizeof(x.st_size)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { x struct stat; x.st_size=-1; return !(x.st_size<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stsize_basic="7 /* long long */" else sc_cv_type_stat_stsize_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_stat_stsize_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat_stsize_basic" >&5 $as_echo "$sc_cv_type_stat_stsize_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST_SIZE ${sc_cv_type_stat_stsize_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat.st_blksize" >&5 $as_echo_n "checking for basic type of struct stat.st_blksize... " >&6; } if ${sc_cv_type_stat_stblksize_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u;short v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblksize_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned short v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblksize_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; int v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblksize_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned int v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblksize_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; long v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblksize_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned long v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblksize_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; long long v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblksize_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned long long v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblksize_basic="8 /* unsigned long long */" else sc_cv_type_stat_stblksize_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat_stblksize_basic" >&5 $as_echo "$sc_cv_type_stat_stblksize_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST_BLKSIZE ${sc_cv_type_stat_stblksize_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat.st_blksize" >&5 $as_echo_n "checking for basic type of struct stat.st_blksize... " >&6; } if ${sc_cv_type_stat_stblksize_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return!(sizeof(x.st_blksize)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_blksize=-1; return !(x.st_blksize<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stblksize_basic="1 /* short */" else sc_cv_type_stat_stblksize_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return!(sizeof(x.st_blksize)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_blksize=-1; return !(x.st_blksize<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stblksize_basic="3 /* int */" else sc_cv_type_stat_stblksize_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return !(sizeof(x.st_blksize)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_blksize=-1; return !(x.st_blksize<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stblksize_basic="5 /* long */" else sc_cv_type_stat_stblksize_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return !(sizeof(x.st_blksize)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { x struct stat; x.st_blksize=-1; return !(x.st_blksize<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stblksize_basic="7 /* long long */" else sc_cv_type_stat_stblksize_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_stat_stblksize_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat_stblksize_basic" >&5 $as_echo "$sc_cv_type_stat_stblksize_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST_BLKSIZE ${sc_cv_type_stat_stblksize_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat.st_blocks" >&5 $as_echo_n "checking for basic type of struct stat.st_blocks... " >&6; } if ${sc_cv_type_stat_stblocks_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u;short v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblocks_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned short v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblocks_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; int v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblocks_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned int v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblocks_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; long v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblocks_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned long v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblocks_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; long long v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblocks_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat u; unsigned long long v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat_stblocks_basic="8 /* unsigned long long */" else sc_cv_type_stat_stblocks_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat_stblocks_basic" >&5 $as_echo "$sc_cv_type_stat_stblocks_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST_BLOCKS ${sc_cv_type_stat_stblocks_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat.st_blocks" >&5 $as_echo_n "checking for basic type of struct stat.st_blocks... " >&6; } if ${sc_cv_type_stat_stblocks_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return!(sizeof(x.st_blocks)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_blocks=-1; return !(x.st_blocks<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stblocks_basic="1 /* short */" else sc_cv_type_stat_stblocks_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return!(sizeof(x.st_blocks)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_blocks=-1; return !(x.st_blocks<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stblocks_basic="3 /* int */" else sc_cv_type_stat_stblocks_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return !(sizeof(x.st_blocks)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; x.st_blocks=-1; return !(x.st_blocks<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stblocks_basic="5 /* long */" else sc_cv_type_stat_stblocks_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat x; return !(sizeof(x.st_blocks)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { x struct stat; x.st_blocks=-1; return !(x.st_blocks<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat_stblocks_basic="7 /* long long */" else sc_cv_type_stat_stblocks_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_stat_stblocks_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat_stblocks_basic" >&5 $as_echo "$sc_cv_type_stat_stblocks_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST_BLOCKS ${sc_cv_type_stat_stblocks_basic} _ACEOF fi # if test "$ac_cv_func_stat64" = yes; then if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat64.st_dev" >&5 $as_echo_n "checking for basic type of struct stat64.st_dev... " >&6; } if ${sc_cv_type_stat64_stdev_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u;short v; return(&u.st_dev==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stdev_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned short v; return(&u.st_dev==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stdev_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; int v; return(&u.st_dev==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stdev_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned int v; return(&u.st_dev==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stdev_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; long v; return(&u.st_dev==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stdev_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned long v; return(&u.st_dev==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stdev_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; long long v; return(&u.st_dev==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stdev_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned long long v; return(&u.st_dev==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stdev_basic="8 /* unsigned long long */" else sc_cv_type_stat64_stdev_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat64_stdev_basic" >&5 $as_echo "$sc_cv_type_stat64_stdev_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST64_DEV ${sc_cv_type_stat64_stdev_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat64.st_dev" >&5 $as_echo_n "checking for basic type of struct stat64.st_dev... " >&6; } if ${sc_cv_type_stat64_stdev_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return!(sizeof(x.st_dev)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_dev=-1; return !(x.st_dev<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stdev_basic="1 /* short */" else sc_cv_type_stat64_stdev_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return!(sizeof(x.st_dev)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_dev=-1; return !(x.st_dev<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stdev_basic="3 /* int */" else sc_cv_type_stat64_stdev_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return !(sizeof(x.st_dev)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_dev=-1; return !(x.st_dev<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stdev_basic="5 /* long */" else sc_cv_type_stat64_stdev_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return !(sizeof(x.st_dev)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { x struct stat64; x.st_dev=-1; return !(x.st_dev<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stdev_basic="7 /* long long */" else sc_cv_type_stat64_stdev_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_stat64_stdev_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat64_stdev_basic" >&5 $as_echo "$sc_cv_type_stat64_stdev_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST64_DEV ${sc_cv_type_stat64_stdev_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat64.st_ino" >&5 $as_echo_n "checking for basic type of struct stat64.st_ino... " >&6; } if ${sc_cv_type_stat64_stino_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u;short v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stino_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned short v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stino_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; int v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stino_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned int v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stino_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; long v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stino_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned long v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stino_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; long long v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stino_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned long long v; return(&u.st_ino==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stino_basic="8 /* unsigned long long */" else sc_cv_type_stat64_stino_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat64_stino_basic" >&5 $as_echo "$sc_cv_type_stat64_stino_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST64_INO ${sc_cv_type_stat64_stino_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat64.st_ino" >&5 $as_echo_n "checking for basic type of struct stat64.st_ino... " >&6; } if ${sc_cv_type_stat64_stino_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return!(sizeof(x.st_ino)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_ino=-1; return !(x.st_ino<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stino_basic="1 /* short */" else sc_cv_type_stat64_stino_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return!(sizeof(x.st_ino)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_ino=-1; return !(x.st_ino<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stino_basic="3 /* int */" else sc_cv_type_stat64_stino_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return !(sizeof(x.st_ino)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_ino=-1; return !(x.st_ino<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stino_basic="5 /* long */" else sc_cv_type_stat64_stino_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return !(sizeof(x.st_ino)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { x struct stat64; x.st_ino=-1; return !(x.st_ino<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stino_basic="7 /* long long */" else sc_cv_type_stat64_stino_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_stat64_stino_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat64_stino_basic" >&5 $as_echo "$sc_cv_type_stat64_stino_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST64_INO ${sc_cv_type_stat64_stino_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat64.st_nlink" >&5 $as_echo_n "checking for basic type of struct stat64.st_nlink... " >&6; } if ${sc_cv_type_stat64_stnlink_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u;short v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stnlink_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned short v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stnlink_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; int v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stnlink_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned int v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stnlink_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; long v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stnlink_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned long v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stnlink_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; long long v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stnlink_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned long long v; return(&u.st_nlink==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stnlink_basic="8 /* unsigned long long */" else sc_cv_type_stat64_stnlink_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat64_stnlink_basic" >&5 $as_echo "$sc_cv_type_stat64_stnlink_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST64_NLINK ${sc_cv_type_stat64_stnlink_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat64.st_nlink" >&5 $as_echo_n "checking for basic type of struct stat64.st_nlink... " >&6; } if ${sc_cv_type_stat64_stnlink_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return!(sizeof(x.st_nlink)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_nlink=-1; return !(x.st_nlink<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stnlink_basic="1 /* short */" else sc_cv_type_stat64_stnlink_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return!(sizeof(x.st_nlink)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_nlink=-1; return !(x.st_nlink<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stnlink_basic="3 /* int */" else sc_cv_type_stat64_stnlink_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return !(sizeof(x.st_nlink)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_nlink=-1; return !(x.st_nlink<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stnlink_basic="5 /* long */" else sc_cv_type_stat64_stnlink_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return !(sizeof(x.st_nlink)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { x struct stat64; x.st_nlink=-1; return !(x.st_nlink<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stnlink_basic="7 /* long long */" else sc_cv_type_stat64_stnlink_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_stat64_stnlink_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat64_stnlink_basic" >&5 $as_echo "$sc_cv_type_stat64_stnlink_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST64_NLINK ${sc_cv_type_stat64_stnlink_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat64.st_size" >&5 $as_echo_n "checking for basic type of struct stat64.st_size... " >&6; } if ${sc_cv_type_stat64_stsize_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u;short v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stsize_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned short v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stsize_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; int v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stsize_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned int v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stsize_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; long v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stsize_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned long v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stsize_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; long long v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stsize_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned long long v; return(&u.st_size==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stsize_basic="8 /* unsigned long long */" else sc_cv_type_stat64_stsize_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat64_stsize_basic" >&5 $as_echo "$sc_cv_type_stat64_stsize_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST64_SIZE ${sc_cv_type_stat64_stsize_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat64.st_size" >&5 $as_echo_n "checking for basic type of struct stat64.st_size... " >&6; } if ${sc_cv_type_stat64_stsize_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return!(sizeof(x.st_size)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_size=-1; return !(x.st_size<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stsize_basic="1 /* short */" else sc_cv_type_stat64_stsize_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return!(sizeof(x.st_size)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_size=-1; return !(x.st_size<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stsize_basic="3 /* int */" else sc_cv_type_stat64_stsize_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return !(sizeof(x.st_size)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_size=-1; return !(x.st_size<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stsize_basic="5 /* long */" else sc_cv_type_stat64_stsize_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return !(sizeof(x.st_size)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { x struct stat64; x.st_size=-1; return !(x.st_size<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stsize_basic="7 /* long long */" else sc_cv_type_stat64_stsize_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_stat64_stsize_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat64_stsize_basic" >&5 $as_echo "$sc_cv_type_stat64_stsize_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST64_SIZE ${sc_cv_type_stat64_stsize_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat64.st_blksize" >&5 $as_echo_n "checking for basic type of struct stat64.st_blksize... " >&6; } if ${sc_cv_type_stat64_stblksize_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u;short v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblksize_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned short v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblksize_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; int v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblksize_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned int v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblksize_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; long v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblksize_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned long v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblksize_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; long long v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblksize_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned long long v; return(&u.st_blksize==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblksize_basic="8 /* unsigned long long */" else sc_cv_type_stat64_stblksize_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat64_stblksize_basic" >&5 $as_echo "$sc_cv_type_stat64_stblksize_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST64_BLKSIZE ${sc_cv_type_stat64_stblksize_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat64.st_blksize" >&5 $as_echo_n "checking for basic type of struct stat64.st_blksize... " >&6; } if ${sc_cv_type_stat64_stblksize_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return!(sizeof(x.st_blksize)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_blksize=-1; return !(x.st_blksize<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stblksize_basic="1 /* short */" else sc_cv_type_stat64_stblksize_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return!(sizeof(x.st_blksize)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_blksize=-1; return !(x.st_blksize<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stblksize_basic="3 /* int */" else sc_cv_type_stat64_stblksize_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return !(sizeof(x.st_blksize)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_blksize=-1; return !(x.st_blksize<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stblksize_basic="5 /* long */" else sc_cv_type_stat64_stblksize_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return !(sizeof(x.st_blksize)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { x struct stat64; x.st_blksize=-1; return !(x.st_blksize<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stblksize_basic="7 /* long long */" else sc_cv_type_stat64_stblksize_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_stat64_stblksize_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat64_stblksize_basic" >&5 $as_echo "$sc_cv_type_stat64_stblksize_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST64_BLKSIZE ${sc_cv_type_stat64_stblksize_basic} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat64.st_blocks" >&5 $as_echo_n "checking for basic type of struct stat64.st_blocks... " >&6; } if ${sc_cv_type_stat64_stblocks_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u;short v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblocks_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned short v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblocks_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; int v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblocks_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned int v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblocks_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; long v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblocks_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned long v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblocks_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; long long v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblocks_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct stat64 u; unsigned long long v; return(&u.st_blocks==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_stat64_stblocks_basic="8 /* unsigned long long */" else sc_cv_type_stat64_stblocks_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat64_stblocks_basic" >&5 $as_echo "$sc_cv_type_stat64_stblocks_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST64_BLOCKS ${sc_cv_type_stat64_stblocks_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct stat64.st_blocks" >&5 $as_echo_n "checking for basic type of struct stat64.st_blocks... " >&6; } if ${sc_cv_type_stat64_stblocks_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return!(sizeof(x.st_blocks)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_blocks=-1; return !(x.st_blocks<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stblocks_basic="1 /* short */" else sc_cv_type_stat64_stblocks_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return!(sizeof(x.st_blocks)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_blocks=-1; return !(x.st_blocks<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stblocks_basic="3 /* int */" else sc_cv_type_stat64_stblocks_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return !(sizeof(x.st_blocks)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; x.st_blocks=-1; return !(x.st_blocks<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stblocks_basic="5 /* long */" else sc_cv_type_stat64_stblocks_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct stat64 x; return !(sizeof(x.st_blocks)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { x struct stat64; x.st_blocks=-1; return !(x.st_blocks<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_stat64_stblocks_basic="7 /* long long */" else sc_cv_type_stat64_stblocks_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_stat64_stblocks_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_stat64_stblocks_basic" >&5 $as_echo "$sc_cv_type_stat64_stblocks_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_ST64_BLOCKS ${sc_cv_type_stat64_stblocks_basic} _ACEOF fi fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct timeval.tv_usec" >&5 $as_echo_n "checking for basic type of struct timeval.tv_usec... " >&6; } if ${sc_cv_type_struct_timeval_tv_usec+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct timeval u;short v; return(&u.tv_usec==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_struct_timeval_tv_usec="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct timeval u; unsigned short v; return(&u.tv_usec==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_struct_timeval_tv_usec="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct timeval u; int v; return(&u.tv_usec==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_struct_timeval_tv_usec="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct timeval u; unsigned int v; return(&u.tv_usec==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_struct_timeval_tv_usec="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct timeval u; long v; return(&u.tv_usec==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_struct_timeval_tv_usec="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct timeval u; unsigned long v; return(&u.tv_usec==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_struct_timeval_tv_usec="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct timeval u; long long v; return(&u.tv_usec==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_struct_timeval_tv_usec="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct timeval u; unsigned long long v; return(&u.tv_usec==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_struct_timeval_tv_usec="8 /* unsigned long long */" else sc_cv_type_struct_timeval_tv_usec="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_struct_timeval_tv_usec" >&5 $as_echo "$sc_cv_type_struct_timeval_tv_usec" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC ${sc_cv_type_struct_timeval_tv_usec} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct timeval.tv_usec" >&5 $as_echo_n "checking for basic type of struct timeval.tv_usec... " >&6; } if ${sc_cv_type_struct_timeval_tv_usec+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct timeval x; return!(sizeof(x.tv_usec)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct timeval x; x.tv_usec=-1; return !(x.tv_usec<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_struct_timeval_tv_usec="1 /* short */" else sc_cv_type_struct_timeval_tv_usec="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct timeval x; return!(sizeof(x.tv_usec)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct timeval x; x.tv_usec=-1; return !(x.tv_usec<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_struct_timeval_tv_usec="3 /* int */" else sc_cv_type_struct_timeval_tv_usec="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct timeval x; return !(sizeof(x.tv_usec)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct timeval x; x.tv_usec=-1; return !(x.tv_usec<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_struct_timeval_tv_usec="5 /* long */" else sc_cv_type_struct_timeval_tv_usec="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { struct timeval x; return !(sizeof(x.tv_usec)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { x struct timeval; x.tv_usec=-1; return !(x.tv_usec<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_struct_timeval_tv_usec="7 /* long long */" else sc_cv_type_struct_timeval_tv_usec="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_struct_timeval_tv_usec="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_struct_timeval_tv_usec" >&5 $as_echo "$sc_cv_type_struct_timeval_tv_usec" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC ${sc_cv_type_struct_timeval_tv_usec} _ACEOF fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct rlimit.rlim_max" >&5 $as_echo_n "checking for basic type of struct rlimit.rlim_max... " >&6; } if ${sc_cv_type_rlimit_rlimmax_basic+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct rlimit u;short v; return(&u.rlim_max==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_rlimit_rlimmax_basic="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct rlimit u; unsigned short v; return(&u.rlim_max==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_rlimit_rlimmax_basic="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct rlimit u; int v; return(&u.rlim_max==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_rlimit_rlimmax_basic="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct rlimit u; unsigned int v; return(&u.rlim_max==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_rlimit_rlimmax_basic="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct rlimit u; long v; return(&u.rlim_max==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_rlimit_rlimmax_basic="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct rlimit u; unsigned long v; return(&u.rlim_max==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_rlimit_rlimmax_basic="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct rlimit u; long long v; return(&u.rlim_max==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_rlimit_rlimmax_basic="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct rlimit u; unsigned long long v; return(&u.rlim_max==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_type_rlimit_rlimmax_basic="8 /* unsigned long long */" else sc_cv_type_rlimit_rlimmax_basic="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_rlimit_rlimmax_basic" >&5 $as_echo "$sc_cv_type_rlimit_rlimmax_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_RLIM_MAX ${sc_cv_type_rlimit_rlimmax_basic} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct rlimit.rlim_max" >&5 $as_echo_n "checking for basic type of struct rlimit.rlim_max... " >&6; } if ${sc_cv_type_rlimit_rlimmax_basic+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { struct rlimit x; return!(sizeof(x.rlim_max)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { struct rlimit x; x.rlim_max=-1; return !(x.rlim_max<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_rlimit_rlimmax_basic="1 /* short */" else sc_cv_type_rlimit_rlimmax_basic="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { struct rlimit x; return!(sizeof(x.rlim_max)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { struct rlimit x; x.rlim_max=-1; return !(x.rlim_max<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_rlimit_rlimmax_basic="3 /* int */" else sc_cv_type_rlimit_rlimmax_basic="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { struct rlimit x; return !(sizeof(x.rlim_max)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { struct rlimit x; x.rlim_max=-1; return !(x.rlim_max<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_rlimit_rlimmax_basic="5 /* long */" else sc_cv_type_rlimit_rlimmax_basic="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { struct rlimit x; return !(sizeof(x.rlim_max)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main() { x struct rlimit; x.rlim_max=-1; return !(x.rlim_max<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_type_rlimit_rlimmax_basic="7 /* long long */" else sc_cv_type_rlimit_rlimmax_basic="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_type_rlimit_rlimmax_basic="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_type_rlimit_rlimmax_basic" >&5 $as_echo "$sc_cv_type_rlimit_rlimmax_basic" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_RLIM_MAX ${sc_cv_type_rlimit_rlimmax_basic} _ACEOF fi # Fedora-19 doc says it is socklen_t which is equivalent to unsigned int, but it is equivalent to size_t (x86_64) if test "$CHANCE_TO_TYPECHECK" -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct cmsghdr.cmsg_len" >&5 $as_echo_n "checking for basic type of struct cmsghdr.cmsg_len... " >&6; } if ${sc_cv_typeof_struct_cmsghdr_cmsg_len+:} false; then : $as_echo_n "(cached) " >&6 else CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { struct cmsghdr u;short v; return(&u.cmsg_len==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_typeof_struct_cmsghdr_cmsg_len="1 /* short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { struct cmsghdr u; unsigned short v; return(&u.cmsg_len==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_typeof_struct_cmsghdr_cmsg_len="2 /* unsigned short */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { struct cmsghdr u; int v; return(&u.cmsg_len==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_typeof_struct_cmsghdr_cmsg_len="3 /* int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { struct cmsghdr u; unsigned int v; return(&u.cmsg_len==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_typeof_struct_cmsghdr_cmsg_len="4 /* unsigned int */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { struct cmsghdr u; long v; return(&u.cmsg_len==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_typeof_struct_cmsghdr_cmsg_len="5 /* long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { struct cmsghdr u; unsigned long v; return(&u.cmsg_len==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_typeof_struct_cmsghdr_cmsg_len="6 /* unsigned long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { struct cmsghdr u; long long v; return(&u.cmsg_len==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_typeof_struct_cmsghdr_cmsg_len="7 /* long long */" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main () { struct cmsghdr u; unsigned long long v; return(&u.cmsg_len==&v); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_typeof_struct_cmsghdr_cmsg_len="8 /* unsigned long long */" else sc_cv_typeof_struct_cmsghdr_cmsg_len="0 /* unknown, taking default */" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$CFLAGS1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_typeof_struct_cmsghdr_cmsg_len" >&5 $as_echo "$sc_cv_typeof_struct_cmsghdr_cmsg_len" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN ${sc_cv_typeof_struct_cmsghdr_cmsg_len} _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for basic type of struct cmsghdr.cmsg_len" >&5 $as_echo_n "checking for basic type of struct cmsghdr.cmsg_len... " >&6; } if ${sc_cv_typeof_struct_cmsghdr_cmsg_len+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main() { struct cmsghdr x; return!(sizeof(x.cmsg_len)==sizeof(short));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as short if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main() { struct cmsghdr x; x.cmsg_len=-1; return !(x.cmsg_len<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_typeof_struct_cmsghdr_cmsg_len="1 /* short */" else sc_cv_typeof_struct_cmsghdr_cmsg_len="2 /* unsigned short */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from short, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main() { struct cmsghdr x; return!(sizeof(x.cmsg_len)==sizeof(int));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as int if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main() { struct cmsghdr x; x.cmsg_len=-1; return !(x.cmsg_len<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_typeof_struct_cmsghdr_cmsg_len="3 /* int */" else sc_cv_typeof_struct_cmsghdr_cmsg_len="4 /* unsigned int */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from int, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main() { struct cmsghdr x; return !(sizeof(x.cmsg_len)==sizeof(long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main() { struct cmsghdr x; x.cmsg_len=-1; return !(x.cmsg_len<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_typeof_struct_cmsghdr_cmsg_len="5 /* long */" else sc_cv_typeof_struct_cmsghdr_cmsg_len="6 /* unsigned long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # length differs from long, try others if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main() { struct cmsghdr x; return !(sizeof(x.cmsg_len)==sizeof(long long));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : # same length as long long if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "sysincludes.h" int main() { x struct cmsghdr; x.cmsg_len=-1; return !(x.cmsg_len<0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : sc_cv_typeof_struct_cmsghdr_cmsg_len="7 /* long long */" else sc_cv_typeof_struct_cmsghdr_cmsg_len="8 /* unsigned long long */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else sc_cv_typeof_struct_cmsghdr_cmsg_len="0 /* unknown */" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_typeof_struct_cmsghdr_cmsg_len" >&5 $as_echo "$sc_cv_typeof_struct_cmsghdr_cmsg_len" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN ${sc_cv_typeof_struct_cmsghdr_cmsg_len} _ACEOF fi ### snprintf, vsnprintf { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/ptmx" >&5 $as_echo_n "checking for /dev/ptmx... " >&6; } if test -c /dev/ptmx; then $as_echo "#define HAVE_DEV_PTMX 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/ptc" >&5 $as_echo_n "checking for /dev/ptc... " >&6; } if test -c /dev/ptc; then $as_echo "#define HAVE_DEV_PTC 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /proc" >&5 $as_echo_n "checking for /proc... " >&6; } if test -d /proc; then $as_echo "#define HAVE_PROC_DIR 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /proc/*/fd" >&5 $as_echo_n "checking for /proc/*/fd... " >&6; } if test -d /proc/$$/fd; then $as_echo "#define HAVE_PROC_DIR_FD 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # on some platforms, raw linking with libwrap fails because allow_severity and # deny_severity are not explicitely defined. Thus we put the libwrap part to # the end { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include libwrap support" >&5 $as_echo_n "checking whether to include libwrap support... " >&6; } # Check whether --enable-libwrap was given. if test "${enable_libwrap+set}" = set; then : enableval=$enable_libwrap; case "$enableval" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; WITH_LIBWRAP= ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_LIBWRAP=1 ;; esac else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; WITH_LIBWRAP=1 fi # # check if we find the components of libwrap ("tcpd" "tcpwrappers") if test -n "$WITH_LIBWRAP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for components of libwrap" >&5 $as_echo_n "checking for components of libwrap... " >&6; } # first, we need to find the include file if ${sc_cv_have_tcpd_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { ; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_have_tcpd_h=yes; LIBWRAP_ROOT="" else sc_cv_have_tcpd_h=no for D in "/sw" "/usr/local" "/opt/freeware" "/usr/sfw"; do I="$D/include" i="$I/tcpd.h" if test -r "$i"; then #V_INCL="$V_INCL -I$I" CPPFLAGS="$CPPFLAGS -I$I" { $as_echo "$as_me:${as_lineno-$LINENO}: found $i" >&5 $as_echo "$as_me: found $i" >&6;} sc_cv_have_tcpd_h=yes; LIBWRAP_ROOT="$D" break; fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "$sc_cv_have_tcpd_h" = "yes"; then $as_echo "#define HAVE_TCPD_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checked for tcpd.h... $sc_cv_have_tcpd_h" >&5 $as_echo "$as_me: checked for tcpd.h... $sc_cv_have_tcpd_h" >&6;} fi # end checking for tcpd.h if test -n "$WITH_LIBWRAP" -a "$sc_cv_have_tcpd_h" = yes; then # next, we search for the wrap library (libwrap.*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libwrap" >&5 $as_echo_n "checking for libwrap... " >&6; } if ${sc_cv_have_libwrap+:} false; then : $as_echo_n "(cached) " >&6 else LIBS0="$LIBS" if test -n "$LIBWRAP_ROOT"; then L="$LIBWRAP_ROOT/lib"; LIBS="-L$L -lwrap $LIBS" else LIBS="-lwrap $LIBS" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int allow_severity,deny_severity; int main () { hosts_access(0) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : sc_cv_have_libwrap='yes' else sc_cv_have_libwrap='no' LIBS="$LIBS -lnsl" # RedHat73 cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int allow_severity,deny_severity; int main () { hosts_access(0) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : sc_cv_have_libwrap='yes' else sc_cv_have_libwrap='no' fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$sc_cv_have_libwrap" != 'yes'; then LIBS="$LIBS0" fi fi if test "$sc_cv_have_libwrap" = 'yes'; then $as_echo "#define HAVE_LIBWRAP 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_have_libwrap" >&5 $as_echo "$sc_cv_have_libwrap" >&6; } fi # if test -n "$WITH_LIBWRAP"; then if test "$sc_cv_have_tcpd_h" = "yes" -a "$sc_cv_have_libwrap" = "yes"; then $as_echo "#define WITH_LIBWRAP 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: not all components of tcp wrappers found, disabling it" >&5 $as_echo "$as_me: WARNING: not all components of tcp wrappers found, disabling it" >&2;}; fi fi # check of hosts_allow_table if test -n "$WITH_LIBWRAP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hosts_allow_table" >&5 $as_echo_n "checking for hosts_allow_table... " >&6; } if ${sc_cv_have_hosts_allow_table+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { hosts_allow_table=""; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_have_hosts_allow_table=yes else sc_cv_have_hosts_allow_table=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_have_hosts_allow_table = yes; then $as_echo "#define HAVE_HOSTS_ALLOW_TABLE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_have_hosts_allow_table" >&5 $as_echo "$sc_cv_have_hosts_allow_table" >&6; } fi # test -n "$WITH_LIBWRAP" if test "$GCC" = yes; then CFLAGS="$CFLAGS" fi # FIPS support requires compiling with fipsld. # fipsld requires the FIPSLD_CC variable to be set to the original CC. # This check must be done after all other checks that require compiling # so that fipsld is not used by the configure script itself. if test -n "$WITH_FIPS"; then if test "$sc_cv_have_openssl_fips_h" = 'yes' -a "$sc_cv_have_libcrypto" = 'yes'; then FIPSLD_CC=$CC if test "${FIPSLD+set}" != set ; then FIPSLD=fipsld fi CC="FIPSLD_CC=$CC $FIPSLD" fi fi # autoconf does not seem to provide AC_CHECK_VAR or so # thus we have to check by foot { $as_echo "$as_me:${as_lineno-$LINENO}: checking for declaration of environ" >&5 $as_echo_n "checking for declaration of environ... " >&6; } if ${sc_cv_decl_environ+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char **s = environ; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_decl_environ=yes else sc_cv_decl_environ=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_decl_environ = yes; then $as_echo "#define HAVE_DECL_ENVIRON 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_decl_environ" >&5 $as_echo "$sc_cv_decl_environ" >&6; } # on some systems environ exists but not the declaration { $as_echo "$as_me:${as_lineno-$LINENO}: checking for var environ" >&5 $as_echo_n "checking for var environ... " >&6; } if ${sc_cv_var_environ+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { extern char **environ; char **s = environ; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sc_cv_var_environ=yes else sc_cv_var_environ=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $sc_cv_var_environ = yes; then $as_echo "#define HAVE_VAR_ENVIRON 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sc_cv_var_environ" >&5 $as_echo "$sc_cv_var_environ" >&6; } # allow BUILD_DATE to be externally set for build reproducibility if test "$BUILD_DATE"; then cat >>confdefs.h <<_ACEOF #define BUILD_DATE "$BUILD_DATE" _ACEOF else $as_echo "#define BUILD_DATE __DATE__\" \"__TIME__" >>confdefs.h fi ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi socat-1.7.3.1/xio-interface.c0000644000201000020100000000527612161506654015501 0ustar gerhardgerhard/* source: xio-interface.c */ /* Copyright Gerhard Rieger 2010 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of raw socket type */ #include "xiosysincludes.h" #if WITH_INTERFACE #include "xioopen.h" #include "xio-socket.h" #include "xio-interface.h" static int xioopen_interface(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int pf, int dummy2, int dummy3); const struct addrdesc xioaddr_interface= { "interface", 3, xioopen_interface, GROUP_FD|GROUP_SOCKET, PF_PACKET, 0, 0 HELP(":") }; static int _xioopen_interface(const char *ifname, struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int pf) { xiosingle_t *xfd = &xxfd->stream; union sockaddr_union us = {{0}}; socklen_t uslen; int socktype = SOCK_RAW; unsigned int ifidx; bool needbind = false; char *bindstring = NULL; struct sockaddr_ll sall = { 0 }; if (ifindex(ifname, &ifidx, -1) < 0) { Error1("unknown interface \"%s\"", ifname); ifidx = 0; /* desparate attempt to continue */ } xfd->howtoend = END_SHUTDOWN; 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(-1, opts, PH_INIT); xfd->salen = sizeof(xfd->peersa); if (pf == PF_UNSPEC) { pf = xfd->peersa.soa.sa_family; } xfd->dtype = XIODATA_RECVFROM_SKIPIP; if (retropt_string(opts, OPT_BIND, &bindstring)) { needbind = true; } /*!!! parse by ':' */ us.ll.sll_family = pf; us.ll.sll_protocol = htons(ETH_P_ALL); us.ll.sll_ifindex = ifidx; uslen = sizeof(sall); needbind = true; xfd->peersa = (union sockaddr_union)us; return _xioopen_dgram_sendto(needbind?&us:NULL, uslen, opts, xioflags, xfd, groups, pf, socktype, 0); } static int xioopen_interface(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int pf, int dummy2, int dummy3) { xiosingle_t *xfd = &xxfd->stream; int result; if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); return STAT_NORETRY; } if ((result = _xioopen_interface(argv[1], opts, xioflags, xxfd, groups, pf)) != STAT_OK) { return result; } xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; if (pf == PF_INET) { xfd->dtype |= XIOREAD_RECV_SKIPIP; } xfd->para.socket.la.soa.sa_family = xfd->peersa.soa.sa_family; _xio_openlate(xfd, opts); return STAT_OK; } #endif /* WITH_INTERFACE */ socat-1.7.3.1/xio-socks.h0000644000201000020100000000221511453022152014643 0ustar gerhardgerhard/* source: xio-socks.h */ /* Copyright Gerhard Rieger 2001-2004 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_socks_h_included #define __xio_socks_h_included 1 struct socks4 { uint8_t version; uint8_t action; uint16_t port; uint32_t dest; char userid[1]; /* just to have access via this struct */ } ; #define SIZEOF_STRUCT_SOCKS4 8 extern const struct optdesc opt_socksport; extern const struct optdesc opt_socksuser; extern const struct addrdesc addr_socks4_connect; extern const struct addrdesc addr_socks4a_connect; extern int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen); extern int _xioopen_socks4_connect0(struct single *xfd, const char *hostname, /* socks target host */ int socks4a, struct socks4 *sockhead, ssize_t *headlen, /* get available space, return used length*/ int level); extern int _xioopen_socks4_connect(struct single *xfd, struct socks4 *sockhead, size_t headlen, int level); #endif /* !defined(__xio_socks_h_included) */ socat-1.7.3.1/xio-streams.h0000644000201000020100000000166011453022152015202 0ustar gerhardgerhard/* source: xio-streams.h */ /* Copyright Gerhard Rieger 2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* when including this file select one part that you need by defining the appropriate CPP define: (none): standard define, variable, and function declarations ENABLE_OPTCODE: option codes for use in enum e_optcode ENABLE_OFUNC: option functions for use in enum e_func */ #ifdef ENABLE_OPTCODE #if 0 enum { /* make syntax feature of editors cooperative */ #endif OPT_STREAMS_I_POP_ALL, /* with POSIX STREAMS */ OPT_STREAMS_I_PUSH, /* with POSIX STREAMS */ #if 0 } ; #endif #elif defined(ENABLE_OFUNC) #if 0 enum { /* make syntax feature of editors cooperative */ #endif OFUNC_STREAMS_I_POP_ALL, OFUNC_STREAMS_I_PUSH, #if 0 } ; #endif #else /* normal declarations */ extern const struct optdesc opt_streams_i_pop_all; extern const struct optdesc opt_streams_i_push; #endif socat-1.7.3.1/xioconfig.h0000644000201000020100000000457512455415362014740 0ustar gerhardgerhard/* source: xioconfig.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xioconfig_h_included #define __xioconfig_h_included 1 /* ensure some dependencies between configure WITH defines. must be included past config.h */ #if WITH_STDIO || WITH_FDNUM # define WITH_FD 1 #endif #if WITH_FILE || WITH_GOPEN || WITH_CREAT || WITH_PIPE # define WITH_OPEN 1 #endif #if WITH_OPEN || WITH_PIPE || WITH_UNIX || WITH_PTY # define WITH_NAMED 1 #endif #if WITH_TERMIOS || WITH_PTY || WITH_READLINE # define _WITH_TERMIOS 1 #endif #if WITH_SOCKS4A # define WITH_SOCKS4 1 #endif #if WITH_SOCKS4 || WITH_PROXY # define WITH_TCP 1 # define WITH_IP4 1 /* currently this socks implementation does not work with IP6 */ #endif #if WITH_OPENSSL # define WITH_TCP 1 # define WITH_IP4 1 #endif #if WITH_IP6 # if !defined(HAVE_NETINET_IP6_H) # undef WITH_IP6 # endif #endif #if !WITH_IP4 && !WITH_IP6 # if WITH_TCP || WITH_UDP || WITH_RAWIP # define WITH_IP4 1 # endif #endif #if WITH_UNIX || WITH_IP4 || WITH_IP6 || WITH_SOCKS4 || WITH_RAWIP || WITH_GENERICSOCKET # define _WITH_SOCKET 1 #else # undef _WITH_SOCKET #endif #if !_WITH_SOCKET # undef WITH_LISTEN #endif #if !WITH_LISTEN # undef WITH_LIBWRAP #endif #if WITH_GENERICSOCKET || WITH_TUN # define _WITH_SOCKET 1 #endif #if WITH_IP4 || WITH_TUN # define _WITH_IP4 1 #endif #if WITH_IP6 || WITH_TUN # define _WITH_IP6 1 #endif #if WITH_NAMED || WITH_TUN # define _WITH_NAMED 1 #endif #if WITH_FILE || WITH_TUN # define _WITH_FILE 1 #endif #if HAVE_DEV_PTMX && HAVE_GRANTPT && HAVE_UNLOCKPT && HAVE_PROTOTYPE_LIB_ptsname #else # undef HAVE_DEV_PTMX #endif #if HAVE_DEV_PTC /* && HAVE_GRANTPT && HAVE_UNLOCKPT && HAVE_PROTOTYPE_LIB_ptsname */ #else # undef HAVE_DEV_PTC #endif /* MacOS does not seem to have any pty implementation */ #if WITH_PTY && (HAVE_DEV_PTC || HAVE_DEV_PTMX || HAVE_OPENPTY) # define HAVE_PTY 1 #else # undef HAVE_PTY #endif #ifndef HAVE_TYPE_SOCKLEN typedef int socklen_t; #endif /* !defined(HAVE_TYPE_SOCKLEN) */ #ifndef HAVE_TYPE_UINT8 typedef unsigned char uint8_t; #endif #ifndef HAVE_TYPE_UINT16 typedef unsigned short uint16_t; #endif #ifndef HAVE_TYPE_UINT32 typedef unsigned int uint32_t; #endif #ifndef HAVE_TYPE_SA_FAMILY_T typedef uint16_t sa_family_t; #endif #endif /* !defined(__xioconfig_h_included) */ socat-1.7.3.1/xio-ip4.c0000644000201000020100000001106712455415361014230 0ustar gerhardgerhard/* source: xio-ip4.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for IP4 related functions */ #include "xiosysincludes.h" #if WITH_IP4 #include "xioopen.h" #include "xio-socket.h" #include "xio-ip.h" #include "xio-ip4.h" int xioparsenetwork_ip4(const char *rangename, struct xiorange *range) { struct hostent *maskaddr; struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr; struct in_addr *netmask_in = &range->netmask.ip4.sin_addr; char *rangename1; /* a copy of rangename with writing allowed */ char *delimpos; /* absolute address of delimiter */ unsigned int bits; /* netmask bits */ if ((rangename1 = strdup(rangename)) == NULL) { Error1("strdup(\"%s\"): out of memory", rangename); return STAT_RETRYLATER; } if (delimpos = strchr(rangename1, '/')) { char *endptr; bits = strtoul(delimpos+1, &endptr, 10); if (! ((*(delimpos+1) != '\0') && (*endptr == '\0'))) { Error1("not a valid netmask in \"%s\"", rangename); bits = 32; /* most secure selection */ } else if (bits > 32) { Error1("netmask \"%s\" is too large", rangename); bits = 32; } if (bits <= 0) { netmask_in->s_addr = 0; } else { netmask_in->s_addr = htonl((0xffffffff << (32-bits))); } } else if (delimpos = strchr(rangename1, ':')) { if ((maskaddr = Gethostbyname(delimpos+1)) == NULL) { /* note: cast is req on AIX: */ Error2("gethostbyname(\"%s\"): %s", delimpos+1, h_errno == NETDB_INTERNAL ? strerror(errno) : (char *)hstrerror(h_errno)); return STAT_NORETRY; } netmask_in->s_addr = *(uint32_t *)maskaddr->h_addr_list[0]; } else { Error1("xioparsenetwork_ip4(\"%s\",,): missing netmask delimiter", rangename); free(rangename1); return STAT_NORETRY; } { struct hostent *nameaddr; *delimpos = 0; if ((nameaddr = Gethostbyname(rangename1)) == NULL) { /* note: cast is req on AIX: */ Error2("gethostbyname(\"%s\"): %s", rangename1, h_errno == NETDB_INTERNAL ? strerror(errno) : (char *)hstrerror(h_errno)); free(rangename1); return STAT_NORETRY; } netaddr_in->s_addr = *(uint32_t *)nameaddr->h_addr_list[0]; } free(rangename1); return STAT_OK; } /* check if peer address is within permitted range. return >= 0 if so. */ int xiocheckrange_ip4(struct sockaddr_in *pa, struct xiorange *range) { struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr; struct in_addr *netmask_in = &range->netmask.ip4.sin_addr; char addrbuf[256], maskbuf[256]; char peername[256]; /* is provided client address valid? */ if (pa->sin_addr.s_addr == 0) { Warn("invalid client address 0.0.0.0"); return -1; } /* client address restriction */ Debug2("permitted client subnet: %s:%s", inet4addr_info(ntohl(netaddr_in->s_addr), addrbuf, sizeof(addrbuf)), inet4addr_info(ntohl(netmask_in->s_addr), maskbuf, sizeof(maskbuf))); Debug1("client address is 0x%08x", ntohl(pa->sin_addr.s_addr)); Debug1("masked address is 0x%08x", ntohl(pa->sin_addr.s_addr & netmask_in->s_addr)); if ((pa->sin_addr.s_addr & netmask_in->s_addr) != netaddr_in->s_addr) { Debug1("client address %s is not permitted", sockaddr_inet4_info(pa, peername, sizeof(peername))); return -1; } return 0; } /* returns information that can be used for constructing an environment variable describing the socket address. if idx is 0, this function writes "ADDR" into namebuff and the IP address into valuebuff, and returns 1 (which means that one more info is there). if idx is 1, it writes "PORT" into namebuff and the port number into valuebuff, and returns 0 (no more info) namelen and valuelen contain the max. allowed length of output chars in the respective buffer. on error this function returns -1. */ int xiosetsockaddrenv_ip4(int idx, char *namebuff, size_t namelen, char *valuebuff, size_t valuelen, struct sockaddr_in *sa, int ipproto) { switch (idx) { case 0: strcpy(namebuff, "ADDR"); inet4addr_info(ntohl(sa->sin_addr.s_addr), valuebuff, valuelen); switch (ipproto) { case IPPROTO_TCP: case IPPROTO_UDP: #ifdef IPPROTO_SCTP case IPPROTO_SCTP: #endif return 1; /* there is port information to also be retrieved */ default: return 0; /* no port info coming */ } case 1: strcpy(namebuff, "PORT"); snprintf(valuebuff, valuelen, "%u", ntohs(sa->sin_port)); return 0; } return -1; } #endif /* WITH_IP4 */ socat-1.7.3.1/xio-ext2.h0000644000201000020100000000142711453022152014407 0ustar gerhardgerhard/* source: xio-ext2.h */ /* Copyright Gerhard Rieger 2006 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ext2_h_included #define __xio_ext2_h_included 1 extern const struct optdesc opt_ext2_secrm; extern const struct optdesc opt_ext2_unrm; extern const struct optdesc opt_ext2_compr; extern const struct optdesc opt_ext2_sync; extern const struct optdesc opt_ext2_immutable; extern const struct optdesc opt_ext2_append; extern const struct optdesc opt_ext2_nodump; extern const struct optdesc opt_ext2_noatime; extern const struct optdesc opt_ext2_journal_data; extern const struct optdesc opt_ext2_notail; extern const struct optdesc opt_ext2_dirsync; extern const struct optdesc opt_ext2_topdir; #endif /* !defined(__xio_ext2_h_included) */ socat-1.7.3.1/xiosignal.c0000644000201000020100000000614312460670272014733 0ustar gerhardgerhard/* source: xiosignal.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains code for handling signals (except SIGCHLD) */ #include "config.h" #include "xioconfig.h" /* what features are enabled */ #include "sysincludes.h" #include "mytypes.h" #include "compat.h" #include "error.h" #include "sycls.h" #define SOCAT_MAXPIDS 4 struct socat_sig_desc { int sig_use; pid_t sig_pids[SOCAT_MAXPIDS]; } ; #if 0 size_t socat_sigint_use; /* how many pids are set in following array */ static pid_t socat_sigint_pids[SOCAT_MAXPIDS]; size_t socat_sigquit_use; /* how many pids are set in following array */ static pid_t socat_sigquit_pids[SOCAT_MAXPIDS]; #else static struct socat_sig_desc socat_sighup; static struct socat_sig_desc socat_sigint; static struct socat_sig_desc socat_sigquit; #endif /* is async-signal-safe */ static struct socat_sig_desc *socat_get_sig_desc(int signum) { struct socat_sig_desc *sigdesc; switch (signum) { case SIGHUP: sigdesc = &socat_sighup; break; case SIGINT: sigdesc = &socat_sigint; break; case SIGQUIT: sigdesc = &socat_sigquit; break; default: sigdesc = NULL; break; } return sigdesc; } /* a signal handler that possibly passes the signal to sub processes */ void socatsignalpass(int sig) { int i; struct socat_sig_desc *sigdesc; int _errno; _errno = errno; diag_in_handler = 1; Notice1("socatsignalpass(%d)", sig); if ((sigdesc = socat_get_sig_desc(sig)) == NULL) { /* is async-signal-safe */ diag_in_handler = 0; errno = _errno; return; } for (i=0; isig_use; ++i) { if (sigdesc->sig_pids[i]) { if (Kill(sigdesc->sig_pids[i], sig) < 0) { Warn2("kill("F_pid", %d): %m", sigdesc->sig_pids[i], sig); } } } #if !HAVE_SIGACTION Signal(sig, socatsignalpass); #endif /* !HAVE_SIGACTION */ Debug("socatsignalpass() ->"); diag_in_handler = 0; errno = _errno; } /* register the sub process pid for passing of signals of type signum. Only for SIGHUP, SIGINT, and SIGQUIT! returns 0 on success or <0 if an error occurred */ int xio_opt_signal(pid_t pid, int signum) { struct socat_sig_desc *sigdesc; if ((sigdesc = socat_get_sig_desc(signum)) == NULL) { Error("sub process registered for unsupported signal"); return -1; } if (sigdesc->sig_use >= SOCAT_MAXPIDS) { Error1("too many sub processes registered for signal %d", signum); return -1; } if (sigdesc->sig_use == 0) { /* the special signal handler has not been registered yet - do it now */ #if HAVE_SIGACTION struct sigaction act; memset(&act, 0, sizeof(struct sigaction)); act.sa_flags = 0/*|SA_RESTART*/; act.sa_handler = socatsignalpass; sigfillset(&act.sa_mask); if (Sigaction(signum, &act, NULL) < 0) { /*! man does not say that errno is defined */ Warn3("sigaction(%d, %p, NULL): %s", signum, &act, strerror(errno)); } #else Signal(signum, socatsignalpass); #endif /* !HAVE_SIGACTION */ } sigdesc->sig_pids[sigdesc->sig_use++] = pid; return 0; } socat-1.7.3.1/readline.sh0000755000201000020100000000122711453022152014677 0ustar gerhardgerhard#! /bin/bash # source: readline.sh # Copyright Gerhard Rieger 2003-2004 # Published under the GNU General Public License V.2, see file COPYING # this is an attempt for a socat based readline wrapper # usage: readline.sh withhistfile=1 while true; do case "X$1" in X-nh|X-nohist*) withhistfile=; shift; continue ;; *) break;; esac done PROGRAM="$@" if [ "$withhistfile" ]; then HISTFILE="$HOME/.$1_history" HISTOPT=",history=$HISTFILE" else HISTOPT= fi mkdir -p /tmp/$USER || exit 1 # # exec socat -d readline"$HISTOPT",noecho='[Pp]assword:' exec:"$PROGRAM",sigint,pty,setsid,ctty,raw,echo=0,stderr 2>/tmp/$USER/stderr2 socat-1.7.3.1/xio-pipe.h0000644000201000020100000000053411453022152014460 0ustar gerhardgerhard/* source: xio-pipe.h */ /* Copyright Gerhard Rieger 2001 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_pipe_h_included #define __xio_pipe_h_included 1 const extern struct addrdesc addr_pipe; extern int xioopen_fifo_unnamed(char *arg, xiofile_t *sock); #endif /* !defined(__xio_pipe_h_included) */ socat-1.7.3.1/hostan.h0000644000201000020100000000042011453022152014214 0ustar gerhardgerhard/* source: hostan.h */ /* Copyright Gerhard Rieger 2006 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __hostan_h_included #define __hostan_h_included 1 extern int hostan(FILE *outfile); #endif /* !defined(__hostan_h_included) */ socat-1.7.3.1/configure.in0000644000201000020100000020054212460670272015102 0ustar gerhardgerharddnl source: configure.in dnl Copyright Gerhard Rieger dnl Published under the GNU General Public License V.2, see file COPYING dnl Process this file with autoconf to produce a configure script. AC_INIT(socat.c) AC_CONFIG_HEADER(config.h) if test -f /usr/xpg4/bin/fgrep; then FGREP=/usr/xpg4/bin/fgrep # Solaris else FGREP=fgrep fi # find out which defines gcc passes to cpp, so makedepend does not run into # (harmless) "error architecture not supported" AC_MSG_CHECKING(which defines needed for makedepend) __cpp_defs=`gcc -v -E - &1 |$FGREP -e '/cpp ' -e '/cc1 '` SYSDEFS=`aa=; for a in $__cpp_defs do case "$a" in -D*) aa="$aa $a";; esac; done; echo "$aa"` AC_SUBST(SYSDEFS) AC_MSG_RESULT($SYSDEFS) # this must come before AC_PROG_CC if test -z "$CFLAGS"; then # if CFLAGS is not set, we preset it to -O # with this setting, we prevent autoconf from defaulting to "-g -O2" export CFLAGS=-O fi dnl Checks for programs. AC_PROG_INSTALL(install) AC_PROG_CC AC_PROG_RANLIB AC_SUBST(AR) AC_CHECK_PROG(AR, ar, ar, gar) # # we need to explicitely call this here; otherwise, with --disable-libwrap we # fail AC_LANG_COMPILER_REQUIRE() if test "$GCC" = yes; then CFLAGS="$CFLAGS -D_GNU_SOURCE -Wall -Wno-parentheses" ERRONWARN="-Werror -O0" elif test "$CC" = "clang"; then CFLAGS="$CFLAGS -D_GNU_SOURCE -Wall -Wno-parentheses" ERRONWARN="-Werror -O0" #elif Sun Studio # ERRONWARN="-errwarn" else ERRONWARN= fi export CFLAGS dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(stdbool.h) AC_CHECK_HEADERS(inttypes.h) AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(fcntl.h limits.h strings.h sys/param.h sys/ioctl.h sys/time.h syslog.h unistd.h) AC_CHECK_HEADERS(pwd.h grp.h stdint.h sys/types.h poll.h sys/poll.h sys/socket.h sys/uio.h sys/stat.h netdb.h sys/un.h) AC_CHECK_HEADERS(pty.h) AC_CHECK_HEADERS(netinet/in.h netinet/in_systm.h) AC_CHECK_HEADERS(netinet/ip.h, [], [], [AC_INCLUDES_DEFAULT #if HAVE_NETINET_IN_H && HAVE_NETINET_IN_SYSTM_H #include #include #endif]) # Solaris prerequisites for netinet/ip.h AC_CHECK_HEADERS(netinet/tcp.h) AC_CHECK_HEADER(net/if.h, AC_DEFINE(HAVE_NET_IF_H), [], [AC_INCLUDES_DEFAULT #if HAVE_SYS_SOCKET_H #include #endif]) # Mac OS X requires including sys/socket.h AC_CHECK_HEADERS(arpa/nameser.h) AC_HEADER_RESOLV() AC_CHECK_HEADERS(termios.h linux/if_tun.h) AC_CHECK_HEADERS(net/if_dl.h) AC_CHECK_HEADERS(linux/types.h) AC_CHECK_HEADER(linux/errqueue.h, AC_DEFINE(HAVE_LINUX_ERRQUEUE_H), [], [#include #include ]) AC_CHECK_HEADERS(sys/utsname.h sys/select.h sys/file.h) AC_CHECK_HEADERS(util.h bsd/libutil.h libutil.h sys/stropts.h regex.h) AC_CHECK_HEADERS(linux/fs.h linux/ext2_fs.h) dnl Checks for setgrent, getgrent and endgrent. AC_CHECK_FUNCS(setgrent getgrent endgrent) dnl Checks for getgrouplist() /* BSD */ AC_CHECK_FUNCS(getgrouplist) AC_CHECK_FUNCS(cfmakeraw) dnl Link libresolv if necessary (for Mac OS X) AC_SEARCH_LIBS([res_9_init], [resolv]) dnl Check for extra socket library (for Solaris) AC_CHECK_FUNC(hstrerror, , AC_CHECK_LIB(resolv, hstrerror, [LIBS="$LIBS -lresolv"; AC_DEFINE(HAVE_HSTRERROR)])) AC_CHECK_FUNC(gethostent, , AC_CHECK_LIB(nsl, gethostent)) AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt)) dnl Check for function prototype and in lib dnl arg1: function name dnl arg2: required include files beyond sysincludes.h define(AC_CHECK_PROTOTYPE_LIB,[ AC_MSG_CHECKING(for $1 prototype) AC_CACHE_VAL(sc_cv_have_prototype_lib_$1, [CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN -Wall $CFLAGS1"; AC_TRY_LINK([#include "sysincludes.h" $2],[return(&$1==(void *)&$1);], [sc_cv_have_prototype_lib_$1=yes], [sc_cv_have_prototype_lib_$1=no]); CFLAGS="$CFLAGS1"]) if test $sc_cv_have_prototype_lib_$1 = yes; then AC_DEFINE(HAVE_PROTOTYPE_LIB_$1) fi AC_MSG_RESULT($sc_cv_have_prototype_lib_$1) ]) dnl Check for hstrerror prototype AC_MSG_CHECKING(for hstrerror prototype) AC_CACHE_VAL(sc_cv_have_prototype_hstrerror, [CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')"; AC_TRY_COMPILE([#include ],[hstrerror();], [sc_cv_have_prototype_hstrerror=no], [sc_cv_have_prototype_hstrerror=yes]); CFLAGS="$CFLAGS1"]) if test $sc_cv_have_prototype_hstrerror = yes; then AC_DEFINE(HAVE_PROTOTYPE_HSTRERROR) fi AC_MSG_RESULT($sc_cv_have_prototype_hstrerror) AC_MSG_CHECKING(whether to include help) AC_ARG_ENABLE(help, [ --disable-help disable help], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_HELP) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_HELP) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include STDIO support) AC_ARG_ENABLE(stdio, [ --disable-stdio disable STDIO support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_STDIO) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_STDIO) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include FD-number support) AC_ARG_ENABLE(fdnum, [ --disable-fdnum disable FD-number support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_FDNUM) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_FDNUM) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include direct file support) AC_ARG_ENABLE(file, [ --disable-file disable direct file support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_FILE) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_FILE) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include direct create support) AC_ARG_ENABLE(creat, [ --disable-creat disable direct create support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_CREAT) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_CREAT) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include gopen support) AC_ARG_ENABLE(gopen, [ --disable-gopen disable open for UNIX socket support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_GOPEN) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_GOPEN) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include explicit pipe support) AC_ARG_ENABLE(pipe, [ --disable-pipe disable pipe support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_PIPE) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_PIPE) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include explicit termios support) AC_ARG_ENABLE(termios, [ --disable-termios disable termios support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_TERMIOS) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_TERMIOS) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include UNIX socket support) AC_ARG_ENABLE(unix, [ --disable-unix disable UNIX domain socket support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_UNIX) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_UNIX) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include abstract UNIX socket support) AC_ARG_ENABLE(abstract_unixsocket, [ --disable-abstract-unixsocket disable abstract UNIX domain socket support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_ABSTRACT_UNIXSOCKET) AC_MSG_RESULT(yes);; esac], [ case "`uname`" in Linux) AC_DEFINE(WITH_ABSTRACT_UNIXSOCKET) AC_MSG_RESULT(yes);; *) AC_MSG_RESULT(no);; esac]) AC_MSG_CHECKING(whether to include IPv4 support) AC_ARG_ENABLE(ip4, [ --disable-ip4 disable IPv4 support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_IP4) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_IP4) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include IPv6 support) AC_ARG_ENABLE(ip6, [ --disable-ip6 disable IPv6 support], [case "$enableval" in no) AC_MSG_RESULT(no); WITH_IP6= ;; *) AC_MSG_RESULT(yes); WITH_IP6=1 ;; esac], [ AC_MSG_RESULT(yes); WITH_IP6=1 ]) if test "$WITH_IP6"; then AC_CHECK_HEADERS([netinet/ip6.h], [AC_DEFINE(HAVE_NETINET_IP6_H) AC_DEFINE(WITH_IP6)], [AC_MSG_WARN([include file netinet/ip6.h not found, disabling IP6])], [AC_INCLUDES_DEFAULT #ifdef HAVE_NETINET_IN_H # include #endif]) AC_CHECK_HEADERS(netinet6/in6.h) # found on OpenBSD and Lion, used for IPV6_* AC_MSG_CHECKING(if __APPLE_USE_RFC_2292 is helpful) AC_CACHE_VAL(ac_cv_apple_use_rfc_2292, [AC_TRY_COMPILE(,[#ifndef IPV6_HOPOPTS murks; #endif], [ac_cv_apple_use_rfc_2292=no], [AC_TRY_COMPILE([#define __APPLE_USE_RFC_2292], [#ifndef IPV6_HOPOPTS murks; #endif], [ac_cv_apple_use_rfc_2292=yes], [ac_cv_apple_use_rfc_2292=no] )] )]) if test "$ac_cv_apple_use_rfc_2292" = yes; then AC_DEFINE(__APPLE_USE_RFC_2292) fi AC_MSG_RESULT($ac_cv_apple_use_rfc_2292) fi AC_MSG_CHECKING(whether to include raw IP support) AC_ARG_ENABLE(rawip, [ --disable-rawip disable raw IP support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_RAWIP) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_RAWIP) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include generic socket support) AC_ARG_ENABLE(genericsocket, [ --disable-genericsocket disable generic socket support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_GENERICSOCKET) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_GENERICSOCKET) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include generic network interface support) AC_ARG_ENABLE(interface, [ --disable-interface disable network interface support], [case "$enableval" in no) AC_MSG_RESULT(no); WITH_INTERFACE= ;; *) AC_MSG_RESULT(yes); WITH_INTERFACE=1 ;; esac], [AC_MSG_RESULT(yes); WITH_INTERFACE=1 ]) if test "$WITH_INTERFACE"; then AC_CHECK_HEADER(netpacket/packet.h, AC_DEFINE(HAVE_NETPACKET_PACKET_H), [WITH_INTERFACE=; AC_MSG_WARN([include file netpacket/packet.h not found, disabling interface])]) fi if test "$WITH_INTERFACE"; then AC_CHECK_HEADER(netinet/if_ether.h, AC_DEFINE(HAVE_NETINET_IF_ETHER_H), [WITH_INTERFACE=; AC_MSG_WARN([include file netinet/if_ether.h not found, disabling interface])], [AC_INCLUDES_DEFAULT #if HAVE_NET_IF_H && HAVE_NETINET_IN_H #include #include #endif]) fi if test "$WITH_INTERFACE"; then AC_DEFINE(WITH_INTERFACE) fi AC_MSG_CHECKING(whether to include TCP support) AC_ARG_ENABLE(tcp, [ --disable-tcp disable TCP support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_TCP) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_TCP) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include UDP support) AC_ARG_ENABLE(udp, [ --disable-udp disable UDP support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_UDP) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_UDP) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include SCTP support) AC_ARG_ENABLE(sctp, [ --disable-sctp disable SCTP support], [case "$enableval" in no) AC_MSG_RESULT(no); WITH_SCTP= ;; *) AC_MSG_RESULT(yes); WITH_SCTP=1 ;; esac], [AC_MSG_RESULT(yes); WITH_SCTP=1 ]) if test -n "$WITH_SCTP"; then AC_MSG_CHECKING(for IPPROTO_SCTP) AC_CACHE_VAL(sc_cv_define_ipproto_sctp, [AC_TRY_COMPILE([#include #include ], [IPPROTO_SCTP;], [sc_cv_define_ipproto_sctp=yes], [sc_cv_define_ipproto_sctp=no])]) AC_MSG_RESULT($sc_cv_define_ipproto_sctp) if test $sc_cv_define_ipproto_sctp = yes; then AC_DEFINE(WITH_SCTP) else AC_MSG_WARN([IPPROTO_SCTP undefined, disabling SCTP support]) fi fi AC_MSG_CHECKING(whether to include listen support) AC_ARG_ENABLE(listen, [ --disable-listen disable listen support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_LISTEN) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_LISTEN) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include socks4 support) AC_ARG_ENABLE(socks4, [ --disable-socks4 disable socks4 support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_SOCKS4) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_SOCKS4) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include socks4a support) AC_ARG_ENABLE(socks4a, [ --disable-socks4a disable socks4a support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_SOCKS4A) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_SOCKS4A) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include proxy connect support) AC_ARG_ENABLE(proxy, [ --disable-proxy disable proxy connect support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_PROXY) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_PROXY) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include exec support) AC_ARG_ENABLE(exec, [ --disable-exec disable exec support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_EXEC) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_EXEC) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING([whether to include system (shell) support]) AC_ARG_ENABLE(system, [ --disable-system disable system (shell) support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_SYSTEM) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_SYSTEM) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include pty address support) AC_ARG_ENABLE(pty, [ --disable-pty disable pty support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_PTY) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_PTY) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include ext2 fs attributes support) AC_ARG_ENABLE(ext2, [ --disable-ext2 disable ext2 fs attributes support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_EXT2) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_EXT2) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include readline support) AC_ARG_ENABLE(readline, [ --disable-readline disable readline support], [case "$enableval" in no) AC_MSG_RESULT(no); WITH_READLINE= ;; *) AC_MSG_RESULT(yes); WITH_READLINE=1 ;; esac], [AC_MSG_RESULT(yes); WITH_READLINE=1 ]) if test -n "$WITH_READLINE"; then CPPFLAGS_ORIG=$CPPFLAGS CFLAGS_ORIG=$CFLAGS LIBS_ORIG=$LIBS sc_usable_readline_found= for D in "" "/usr/local" "/opt/local" "/sw" "/opt/freeware" "/usr/sfw"; do if test -n "$D" ; then CPPFLAGS="$CPPFLAGS -I$D/include" CFLAGS="$CFLAGS -L$D/lib" DLOC="in location $D" else DLOC="in default location" fi AC_MSG_CHECKING(for usable readline $DLOC) # Some systems require -lcurses, some require -lncurses. # Mac OS X 10.4 (and others) ships with libedit masquerading as readline, # but it doesn't work well with socat. It can be recognized by the absence # of append_history. for L in "" "-lcurses" "-lncurses"; do LIBS="$LIBS_ORIG -lreadline $L" AC_TRY_LINK( [ #include #include #include ], [ readline(NULL); append_history(0, NULL); ], [ sc_usable_readline_found=1 break ]) done if test -n "$sc_usable_readline_found"; then AC_MSG_RESULT(yes) AC_DEFINE(HAVE_READLINE_READLINE_H,1) AC_DEFINE(HAVE_READLINE_HISTORY_H,1) AC_DEFINE(HAVE_LIBREADLINE,1) AC_DEFINE(WITH_READLINE,1) break else AC_MSG_RESULT(no) CPPFLAGS=$CPPFLAGS_ORIG CFLAGS=$CFLAGS_ORIG LIBS=$LIBS_ORIG fi done if test -z "$sc_usable_readline_found"; then AC_MSG_WARN([no suitable version of readline found; perhaps you need to install a newer version]) fi fi AC_MSG_CHECKING(whether to include openssl support) AC_ARG_ENABLE(openssl, [ --disable-openssl disable OpenSSL support], [ case "$enableval" in no) AC_MSG_RESULT(no); WITH_OPENSSL= ;; *) AC_MSG_RESULT(yes); WITH_OPENSSL=1 ;; esac], [ AC_MSG_RESULT(yes); WITH_OPENSSL=1 ]) # if test -n "$WITH_OPENSSL"; then AC_MSG_NOTICE(checking for components of OpenSSL) # first, we need to find the include file AC_CACHE_VAL(sc_cv_have_openssl_ssl_h, [AC_TRY_COMPILE([#include ],[;], [sc_cv_have_openssl_ssl_h=yes; OPENSSL_ROOT=""; ], [sc_cv_have_openssl_ssl_h=no for D in "/sw" "/usr/local" "/opt/freeware" "/usr/sfw" "/usr/local/ssl"; do I="$D/include" i="$I/openssl/ssl.h" if test -r "$i"; then #V_INCL="$V_INCL -I$I" CPPFLAGS="$CPPFLAGS -I$I" AC_MSG_NOTICE(found $i) sc_cv_have_openssl_ssl_h=yes; OPENSSL_ROOT="$D" break; fi done]) ]) if test "$sc_cv_have_openssl_ssl_h" = "yes"; then AC_DEFINE(HAVE_OPENSSL_SSL_H) fi AC_MSG_NOTICE(checked for openssl/ssl.h... $sc_cv_have_openssl_ssl_h) fi # end checking for openssl/ssl.h # if test -n "$WITH_OPENSSL" -a "$sc_cv_have_openssl_ssl_h" = 'yes'; then # next, we search for the openssl library (libssl.*) # interesting: Linux only requires -lssl, FreeBSD requires -lssl -lcrypto # Note, version OpenSSL 0.9.7j requires -lcrypto even on Linux. AC_MSG_CHECKING(for libssl) AC_CACHE_VAL(sc_cv_have_libssl, [ LIBS0="$LIBS" if test -n "$OPENSSL_ROOT"; then L="$OPENSSL_ROOT/lib"; LIBS="$LIBS -L$L -lssl" else LIBS="$LIBS -lssl" fi AC_TRY_LINK([#include ], [SSL_library_init();ERR_error_string()], [sc_cv_have_libssl='yes'], [ LIBS="$LIBS -lcrypto" AC_TRY_LINK([#include ], [SSL_library_init()], [sc_cv_have_libssl='yes'], [sc_cv_have_libssl='no']) ]) if test "$sc_cv_have_libssl" != 'yes'; then LIBS="$LIBS0" fi ] ) if test "$sc_cv_have_libssl" = 'yes'; then AC_DEFINE(HAVE_LIBSSL) fi AC_MSG_RESULT($sc_cv_have_libssl) fi # # # a possible location for openssl (on Sourceforge/Solaris) # AC_CHECK_FILE(/usr/local/ssl/lib, LIBS="$LIBS -L/usr/local/ssl/lib/") # # sometimes on Solaris: # AC_CHECK_FILE(/pkgs/lib, LIBS="$LIBS -L/pkgs/lib/") # # for AIX 5.1 with Linux toolbox: # AC_CHECK_FILE(/opt/freeware/lib, LIBS="$LIBS -L/opt/freeware/lib/") # # AC_CHECK_LIB(crypto, main) # AC_CHECK_LIB(ssl, main) # # # MacOSX has openssl includes in another directory # if test -d /sw/include/; then # V_INCL="$V_INCL -I/sw/include" # # and Solaris at sourceforge here: # elif test -d /usr/local/ssl/include/; then # V_INCL="$V_INCL -I/usr/local/ssl/include" # # and AIX 5.1 with Linux toolbox: # elif test -d /opt/freeware/include; then # V_INCL="$V_INCL -I/opt/freeware/include" # fi #fi if test -n "$WITH_OPENSSL"; then if test "$sc_cv_have_openssl_ssl_h" = "yes" -a "$sc_cv_have_libssl" = "yes"; then AC_DEFINE(WITH_OPENSSL) else AC_MSG_WARN([not all components of OpenSSL found, disabling it]); fi fi # check for fips support AC_MSG_CHECKING(whether to include openssl fips support) AC_ARG_ENABLE(fips, [ --enable-fips enable OpenSSL FIPS support], [ case "$enableval" in yes) AC_MSG_RESULT(yes); WITH_FIPS=1 ;; *) AC_MSG_RESULT(no); WITH_FIPS= ;; esac], [ AC_MSG_RESULT(no); WITH_FIPS= ]) if test -n "$WITH_FIPS"; then if test -n "$WITH_OPENSSL"; then AC_CHECK_PROG(HAVE_FIPSLD, fipsld, 1) if test "$sc_cv_have_openssl_ssl_h" != "yes" -o "$sc_cv_have_libssl" != "yes" -o ! "$HAVE_FIPSLD"; then AC_MSG_WARN([not all components of OpenSSL found, disabling FIPS]); WITH_FIPS= fi else AC_MSG_WARN([must enable OpenSSL to enable FIPS; use --enable-openssl]); fi fi if test -n "$WITH_FIPS"; then AC_MSG_CHECKING(for components of OpenSSL FIPS) # first, we need to find the include file AC_CACHE_VAL(sc_cv_have_openssl_fips_h, [AC_TRY_COMPILE([#define OPENSSL_FIPS #include #include ],[;], [sc_cv_have_openssl_fips_h=yes; ], [sv_cv_have_openssl_fips_h=no if test -n "$OPENSSL_ROOT"; then I="$OPENSSL_ROOT/include" i="$I/openssl/fips.h" if test -r "$i"; then AC_MSG_NOTICE(found $i) sc_cv_have_openssl_fips_h=yes; fi fi ] )] ) if test "$sv_cv_have_openssl_fips_h" = "yes"; then AC_DEFINE(HAVE_OPENSSL_FIPS_H) fi AC_MSG_NOTICE(checked for openssl/fips.h... $sc_cv_have_openssl_ssl_h) fi if test -n "$WITH_FIPS" -a "$sc_cv_have_openssl_fips_h" = 'yes'; then # check for the libcrypto library with fips support AC_MSG_CHECKING(for libcrypto with FIPS support) AC_CACHE_VAL(sc_cv_have_libcrypto, [ LIBS0="$LIBS" echo $LIBS | grep -q "\-lcrypto" if test $? -ne 0; then if test -n "$OPENSSL_ROOT"; then L="$OPENSSL_ROOT/lib"; LIBS="$LIBS -L$L -lcrypto" else LIBS="$LIBS -lcrypto" fi fi AC_TRY_LINK([#define OPENSSL_FIPS #include #include ], [int res = FIPS_mode_set(1);], [sc_cv_have_libcrypto='yes'], [sc_cv_have_libcrypto='no'] ) if test "$sc_cv_have_libcrypto" != 'yes'; then LIBS="$LIBS0" fi ] ) if test "$sc_cv_have_libcrypto" = 'yes'; then AC_DEFINE(HAVE_LIBCRYPTO) fi AC_MSG_RESULT($sc_cv_have_libcrypto) fi if test -n "$WITH_FIPS"; then if test "$sc_cv_have_openssl_fips_h" = 'yes' -a "$sc_cv_have_libcrypto" = 'yes'; then AC_DEFINE(WITH_FIPS) AC_DEFINE(OPENSSL_FIPS) else AC_MSG_WARN([not all components of OpenSSL FIPS found, disabling it]); fi fi AC_MSG_CHECKING(whether to include tun/tap address support) AC_ARG_ENABLE(tun, [ --disable-tun disable TUN/TAP support], [case "$enableval" in no) AC_MSG_RESULT(no); WITH_TUN= ;; *) AC_MSG_RESULT(yes); WITH_TUN=1 ;; esac], [AC_MSG_RESULT(yes); WITH_TUN=1 ]) # if ! test "$ac_cv_header_linux_if_tun_h" = 'yes'; then AC_MSG_WARN(include file linux/if_tun.h not found, disabling TUN) WITH_TUN= fi # if test -n "$WITH_TUN"; then AC_DEFINE(WITH_TUN) fi AC_MSG_CHECKING(whether to include system call tracing) AC_ARG_ENABLE(sycls, [ --disable-sycls disable system call tracing], [case "$enableval" in no) SYCLS=""; SSLCLS=""; AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_SYCLS) SYCLS="sycls.c"; SSLCLS="sslcls.c"; AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_SYCLS) SYCLS="sycls.c"; SSLCLS="sslcls.c"; AC_MSG_RESULT(yes)]) AC_SUBST(SYCLS) AC_SUBST(SSLCLS) AC_MSG_CHECKING(whether to include file descriptor analyzer) AC_ARG_ENABLE(filan, [ --disable-filan disable file descriptor analyzer], [case "$enableval" in no) FILAN=""; AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_FILAN) FILAN="filan.c"; AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_FILAN) FILAN="filan.c"; AC_MSG_RESULT(yes)]) AC_SUBST(FILAN) AC_MSG_CHECKING(whether to include retry support) AC_ARG_ENABLE(retry, [ --disable-retry disable retry support], [case "$enableval" in no) AC_MSG_RESULT(no);; *) AC_DEFINE(WITH_RETRY) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_RETRY) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(included message level) AC_ARG_ENABLE(msglevel, [ --enable-msglevel=N set max verbosity to debug,info,notice,warn,error,fatal], [case "$enableval" in debug) AC_DEFINE(WITH_MSGLEVEL,0) AC_MSG_RESULT(debug);; info) AC_DEFINE(WITH_MSGLEVEL,1) AC_MSG_RESULT(info);; notice) AC_DEFINE(WITH_MSGLEVEL,2) AC_MSG_RESULT(notice);; warn) AC_DEFINE(WITH_MSGLEVEL,3) AC_MSG_RESULT(warn);; error) AC_DEFINE(WITH_MSGLEVEL,4) AC_MSG_RESULT(error);; fatal) AC_DEFINE(WITH_MSGLEVEL,5) AC_MSG_RESULT(fatal);; *) AC_DEFINE(WITH_MSGLEVEL,0) AC_MSG_RESULT(debug);; esac], [AC_DEFINE(WITH_MSGLEVEL,0) AC_MSG_RESULT(debug)]) #AC_SUBST(V_INCL) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_UID_T AC_TYPE_MODE_T AC_TYPE_OFF_T AC_TYPE_PID_T AC_TYPE_SIZE_T AC_STRUCT_ST_BLKSIZE AC_STRUCT_ST_BLOCKS AC_STRUCT_ST_RDEV AC_HEADER_TIME dnl Check for extra realtime library (for Solaris) AC_CHECK_FUNC(nanosleep, AC_DEFINE(HAVE_NANOSLEEP), AC_CHECK_LIB(rt, nanosleep, [LIBS="-lrt $LIBS"; AC_DEFINE(HAVE_NANOSLEEP)])) #AC_CHECK_FUNC(nanosleep, , AC_CHECK_LIB(rt, nanosleep)) dnl Checks for library functions. AC_PROG_GCC_TRADITIONAL AC_FUNC_MEMCMP AC_TYPE_SIGNAL AC_FUNC_STRFTIME AC_CHECK_FUNCS(putenv select poll socket strtod strtol) AC_CHECK_FUNCS(strtoul uname getpgid getsid getaddrinfo) AC_CHECK_FUNCS(setgroups inet_aton) AC_CHECK_FUNCS() AC_CHECK_FUNCS(grantpt unlockpt) # GR AC_CHECK_FUNCS only checks linking, not prototype. This may lead to implicit # function declarations and to SIGSEGV on systems with 32bit int and 64bit pointer ################################### # check for prototype and existence of functions that return a pointer # defines in config.h: HAVE_PROTOTYPE_LIB_$1 AC_CHECK_PROTOTYPE_LIB(strdup) AC_CHECK_PROTOTYPE_LIB(strerror) AC_CHECK_PROTOTYPE_LIB(strstr) AC_CHECK_PROTOTYPE_LIB(getipnodebyname) AC_CHECK_PROTOTYPE_LIB(memrchr) AC_CHECK_PROTOTYPE_LIB(if_indextoname) AC_CHECK_PROTOTYPE_LIB(ptsname) AC_MSG_CHECKING(for long long) AC_CACHE_VAL(sc_cv_type_longlong, [AC_TRY_COMPILE([],[long long s;], [sc_cv_type_longlong=yes], [sc_cv_type_longlong=no])]) if test $sc_cv_type_longlong = yes; then AC_DEFINE(HAVE_TYPE_LONGLONG) fi AC_MSG_RESULT($sc_cv_type_longlong) AC_CHECK_TYPE(sig_atomic_t,AC_DEFINE(HAVE_TYPE_SIG_ATOMIC_T),,[#include "sysincludes.h"]) AC_MSG_CHECKING(for bool) AC_CACHE_VAL(sc_cv_type_bool, [AC_TRY_COMPILE([#ifdef HAVE_STDBOOL_H #include #endif], [bool b;], [sc_cv_type_bool=yes], [sc_cv_type_bool=no])]) if test $sc_cv_type_bool = yes; then AC_DEFINE(HAVE_TYPE_BOOL) fi AC_MSG_RESULT($sc_cv_type_bool) # following builtin macro does not check unistd.h and sys/socket.h where # socklen_t might be defined #AC_CHECK_TYPE(socklen_t, int) # AC_MSG_CHECKING(for socklen_t) AC_CACHE_VAL(sc_cv_type_socklen, [AC_TRY_COMPILE([#include #include #include ],[socklen_t s;], [sc_cv_type_socklen=yes], [sc_cv_type_socklen=no])]) if test $sc_cv_type_socklen = yes; then AC_DEFINE(HAVE_TYPE_SOCKLEN) fi AC_MSG_RESULT($sc_cv_type_socklen) AC_MSG_CHECKING(for struct stat64) AC_CACHE_VAL(sc_cv_type_stat64, [AC_TRY_COMPILE([#include ],[struct stat64 s;], [sc_cv_type_stat64=yes], [sc_cv_type_stat64=no])]) if test $sc_cv_type_stat64 = yes; then AC_DEFINE(HAVE_TYPE_STAT64) fi AC_MSG_RESULT($sc_cv_type_stat64) AC_MSG_CHECKING(for off64_t) AC_CACHE_VAL(sc_cv_type_off64, [AC_TRY_COMPILE([#include ],[off64_t s;], [sc_cv_type_off64=yes], [sc_cv_type_off64=no])]) if test $sc_cv_type_off64 = yes; then AC_DEFINE(HAVE_TYPE_OFF64) fi AC_MSG_RESULT($sc_cv_type_off64) AC_MSG_CHECKING(for sighandler_t) AC_CACHE_VAL(sc_cv_type_sighandler, [AC_TRY_COMPILE([#include ],[sighandler_t s;], [sc_cv_type_sighandler=yes], [sc_cv_type_sighandler=no])]) if test $sc_cv_type_sighandler = yes; then AC_DEFINE(HAVE_TYPE_SIGHANDLER) fi AC_MSG_RESULT($sc_cv_type_socklen) AC_MSG_CHECKING(for uint8_t) AC_CACHE_VAL(sc_cv_type_uint8, [AC_TRY_COMPILE([#include #if HAVE_STDINT_H #include #endif /* Tru64 has uint8_t etc from netdb.h */ #if HAVE_NETDB_H #include #endif #include ],[uint8_t s;], [sc_cv_type_uint8=yes], [sc_cv_type_uint8=no])]) if test $sc_cv_type_uint8 = yes; then AC_DEFINE(HAVE_TYPE_UINT8) fi AC_MSG_RESULT($sc_cv_type_uint8) AC_MSG_CHECKING(for uint16_t) AC_CACHE_VAL(sc_cv_type_uint16, [AC_TRY_COMPILE([#include #if HAVE_STDINT_H #include #endif /* Tru64 has uint16_t etc from netdb.h */ #if HAVE_NETDB_H #include #endif #include ],[uint16_t s;], [sc_cv_type_uint16=yes], [sc_cv_type_uint16=no])]) if test $sc_cv_type_uint16 = yes; then AC_DEFINE(HAVE_TYPE_UINT16) fi AC_MSG_RESULT($sc_cv_type_uint16) AC_MSG_CHECKING(for uint32_t) AC_CACHE_VAL(sc_cv_type_uint32, [AC_TRY_COMPILE([#include #if HAVE_STDINT_H #include #endif /* Tru64 has uint32_t etc from netdb.h */ #if HAVE_NETDB_H #include #endif #include ],[uint32_t s;], [sc_cv_type_uint32=yes], [sc_cv_type_uint32=no])]) if test $sc_cv_type_uint32 = yes; then AC_DEFINE(HAVE_TYPE_UINT32) fi AC_MSG_RESULT($sc_cv_type_uint32) AC_MSG_CHECKING(for uint64_t) AC_CACHE_VAL(sc_cv_type_uint64, [AC_TRY_COMPILE([#include #if HAVE_STDINT_H #include #endif /* Tru64 has uint32_t etc from netdb.h */ #if HAVE_NETDB_H #include #endif #include ],[uint64_t s;], [sc_cv_type_uint64=yes], [sc_cv_type_uint64=no])]) if test $sc_cv_type_uint64 = yes; then AC_DEFINE(HAVE_TYPE_UINT64) fi AC_MSG_RESULT($sc_cv_type_uint64) ### AIX 4.1 needs _XOPEN_EXTENDED_SOURCE for syslog headers, # but then gets problems with 3rd arg of getsockaddr... #AC_MSG_CHECKING(for _XOPEN_EXTENDED_SOURCE requirement) #CFLAGS="-Werror -Wall" #AC_TRY_COMPILE([#include ], #[syslog(0," ");], #[AC_MSG_RESULT(no)], #[AC_MSG_RESULT(required); AC_DEFINE(_XOPEN_EXTENDED_SOURCE)]) ### fds_bits AC_MSG_CHECKING(for fdset->fds_bits) AC_TRY_COMPILE([#include #if HAVE_SYS_SELECT_H #include #endif], [fd_set s; s.fds_bits[0]=0;], [AC_MSG_RESULT(yes); AC_DEFINE(HAVE_FDS_BITS)], [AC_MSG_RESULT(no);]) AC_MSG_CHECKING(for sa_family_t) AC_CACHE_VAL(sc_cv_type_sa_family_t, [AC_TRY_COMPILE([#include #include #include ],[sa_family_t s;], [sc_cv_type_sa_family_t=yes], [sc_cv_type_sa_family_t=no])]) if test $sc_cv_type_sa_family_t = yes; then AC_DEFINE(HAVE_TYPE_SA_FAMILY_T) fi AC_MSG_RESULT($sc_cv_type_sa_family_t) AC_MSG_CHECKING(for struct sock_extended_err) AC_CACHE_VAL(sc_cv_struct_sock_extended_err, [AC_TRY_COMPILE([#include #if TIME_WITH_SYS_TIME #include #endif #if HAVE_LINUX_ERRQUEUE_H #include #endif],[struct sock_extended_err s;], [sc_cv_struct_sock_extended_err=yes], [sc_cv_struct_sock_extended_err=no])]) if test $sc_cv_struct_sock_extended_err = yes; then AC_DEFINE(HAVE_STRUCT_SOCK_EXTENDED_ERR) fi AC_MSG_RESULT($sc_cv_struct_sock_extended_err) AC_MSG_CHECKING(for struct sigaction.sa_sigaction) AC_CACHE_VAL(sc_cv_struct_sigaction_sa_sigaction, [AC_TRY_COMPILE([#include ],[struct sigaction s;s.sa_sigaction=0;], [sc_cv_struct_sigaction_sa_sigaction=yes], [sc_cv_struct_sigaction_sa_sigaction=no])]) if test $sc_cv_struct_sigaction_sa_sigaction = yes; then AC_DEFINE(HAVE_STRUCT_SIGACTION_SA_SIGACTION) fi AC_MSG_RESULT($sc_cv_struct_sigaction_sa_sigaction) ### struct termios .c_ispeed AC_MSG_CHECKING(for termios.c_ispeed) AC_CACHE_VAL(sc_cv_termios_ispeed, [AC_TRY_COMPILE([#include ], [struct termios t; t.c_ispeed=0;], [sc_cv_termios_ispeed=yes], [sc_cv_termios_ispeed=no])]) if test $sc_cv_termios_ispeed = yes; then AC_DEFINE(HAVE_TERMIOS_ISPEED) fi AC_MSG_RESULT($sc_cv_termios_ispeed) if test $sc_cv_termios_ispeed = yes; then AC_MSG_CHECKING(for offset of c_ispeed in struct termios) LIBS1="$LIBS"; LIBS="" # avoid libwrap allow_severity undefined AC_CACHE_VAL(ac_cv_ispeed_offset, [conftestspeedoff="conftestspeedoff.out" AC_TRY_RUN([ #include #include #include #include #include int main(){ struct termios t; FILE *f; if ((f=fopen("$conftestspeedoff","w"))==NULL){ fprintf(stderr,"\\"$conftestspeedoff\\": %s\n",strerror(errno)); exit(-1); } fprintf(f, "%d", ((char*)&t.c_ispeed-(char*)&t)/sizeof(speed_t)); exit(0); } ], [ac_cv_ispeed_offset=`cat $conftestspeedoff`], [ac_cv_ispeed_offset=-1], [ac_cv_ispeed_offset=-1] #! )]) LIBS="$LIBS1" AC_MSG_RESULT($ac_cv_ispeed_offset) if test $ac_cv_ispeed_offset -ge 0; then AC_DEFINE_UNQUOTED(ISPEED_OFFSET, $ac_cv_ispeed_offset) fi fi # there is another issue with termios: OSR requires "#define _SVID3 ..." # for reasonable termios support. We check this situation using IMAXBEL AC_MSG_CHECKING(if _SVID3 is helpful) AC_CACHE_VAL(ac_cv_svid3, [AC_TRY_COMPILE([#include ], [int i=IMAXBEL], [ac_cv_svid3=no], [AC_TRY_COMPILE([#define _SVID3 1 #include ], [int i=IMAXBEL], [ac_cv_svid3=yes], [ac_cv_svid3=no] )] )]) if test $ac_cv_svid3 = yes; then AC_DEFINE(_SVID3) fi AC_MSG_RESULT($ac_cv_svid3) # Openindiana needs _XPG4_2 for CMSG stuff AC_MSG_CHECKING(if _XPG4_2 is helpful) AC_CACHE_VAL(ac_cv_xpg4_2, [AC_TRY_LINK([#include ], [int i=CMSG_DATA(0)], [ac_cv_xpg4_2=no], [AC_TRY_LINK([#define _XPG4_2 1 #include ], [int i=CMSG_DATA(0)], [ac_cv_xpg4_2=yes], [ac_cv_xpg4_2=no] )] )]) if test $ac_cv_xpg4_2 = yes; then AC_DEFINE(_XPG4_2) fi AC_MSG_RESULT($ac_cv_xpg4_2) # When on Openindiana _XPG4_2 is defined (see above) # we also need to define __EXTENSIONS__ for basic stuff. # Note that is important on Openindiana # but does not exist on Linux if test "$ac_cv_xpg4_2" = yes; then AC_MSG_CHECKING(if __EXTENSIONS__ is helpful) AC_CACHE_VAL(ac_cv___extensions__, [AC_TRY_COMPILE([#include ], [procset_t *s=0;], [ac_cv___extensions__=no], [AC_TRY_COMPILE([#define __EXTENSIONS__ 1 #include ], [procset_t *s=0;], [ac_cv___extensions__=yes], [ac_cv___extensions__=no] )] )]) if test $ac_cv___extensions__ = yes; then AC_DEFINE(__EXTENSIONS__) fi AC_MSG_RESULT($ac_cv___extensions__) fi # When on Openindiana __EXTENSIONS__ is defined (see above) # _POSIX_PTHREAD_SEMANTICS must be defined for standard ctime_r() if test "$ac_cv___extensions__" = yes; then AC_MSG_CHECKING(if _POSIX_PTHREAD_SEMANTICS is helpful) AC_CACHE_VAL(ac_cv__posix_pthread_semantics, [AC_TRY_COMPILE([#include ], [char *s = ctime_r(0,0);], [ac_cv__posix_pthread_semantics=no], [AC_TRY_COMPILE([#define _POSIX_PTHREAD_SEMANTICS 1 #include ], [char *s = ctime_r(0,0);], [ac_cv__posix_pthread_semantics=yes], [ac_cv__posix_pthread_semantics=no] )] )]) if test $ac_cv__posix_pthread_semantics = yes; then AC_DEFINE(_POSIX_PTHREAD_SEMANTICS) fi AC_MSG_RESULT($ac_cv__posix_pthread_semantics) fi # struct timespec AC_MSG_CHECKING(for struct timespec) AC_CACHE_VAL(sc_cv_struct_timespec, [AC_TRY_COMPILE([#include #if HAVE_SYS_TIME_H #include #endif],[struct timespec s;], [sc_cv_struct_timespec=yes], [sc_cv_struct_timespec=no])]) if test $sc_cv_struct_timespec = yes; then AC_DEFINE(HAVE_STRUCT_TIMESPEC) fi AC_MSG_RESULT($sc_cv_struct_timespec) # struct linger; FreeBSD requires sys/types.h for sys/socket.h AC_MSG_CHECKING(for struct linger) AC_CACHE_VAL(sc_cv_struct_linger, [AC_TRY_COMPILE([#include #include ],[struct linger s;], [sc_cv_struct_linger=yes], [sc_cv_struct_linger=no])]) if test $sc_cv_struct_linger = yes; then AC_DEFINE(HAVE_STRUCT_LINGER) fi AC_MSG_RESULT($sc_cv_struct_linger) # struct ip_mreq (for multicasting options) AC_MSG_CHECKING(for struct ip_mreq) AC_CACHE_VAL(sc_cv_struct_ip_mreq, [AC_TRY_COMPILE([#include #include #include ],[struct ip_mreq s;], [sc_cv_struct_ip_mreq=yes], [sc_cv_struct_ip_mreq=no])]) if test $sc_cv_struct_ip_mreq = yes; then AC_DEFINE(HAVE_STRUCT_IP_MREQ) fi AC_MSG_RESULT($sc_cv_struct_ip_mreq) # struct ip_mreqn (for multicasting options) AC_MSG_CHECKING(for struct ip_mreqn) AC_CACHE_VAL(sc_cv_struct_ip_mreqn, [AC_TRY_COMPILE([#include #include #include ],[struct ip_mreqn s;], [sc_cv_struct_ip_mreqn=yes], [sc_cv_struct_ip_mreqn=no])]) if test $sc_cv_struct_ip_mreqn = yes; then AC_DEFINE(HAVE_STRUCT_IP_MREQN) fi AC_MSG_RESULT($sc_cv_struct_ip_mreqn) # struct ipv6_mreq (for multicasting options) AC_MSG_CHECKING(for struct ipv6_mreq) AC_CACHE_VAL(sc_cv_struct_ipv6_mreq, [AC_TRY_COMPILE([#include #include #include ],[struct ipv6_mreq s;], [sc_cv_struct_ipv6_mreq=yes], [sc_cv_struct_ipv6_mreq=no])]) if test $sc_cv_struct_ipv6_mreq = yes; then AC_DEFINE(HAVE_STRUCT_IPV6_MREQ) fi AC_MSG_RESULT($sc_cv_struct_ipv6_mreq) # struct ifreq (for network interfaces) AC_MSG_CHECKING(for struct ifreq) AC_CACHE_VAL(sc_cv_struct_ifreq, [AC_TRY_COMPILE([#include #include #include ],[struct ifreq s;], [sc_cv_struct_ifreq=yes], [sc_cv_struct_ifreq=no])]) if test $sc_cv_struct_ifreq = yes; then AC_DEFINE(HAVE_STRUCT_IFREQ) fi AC_MSG_RESULT($sc_cv_struct_ifreq) # struct ifreq.ifr_index # on most systems that have struct ifreq AC_MSG_CHECKING(for struct ifreq.ifr_index) AC_CACHE_VAL(sc_cv_struct_ifreq_ifr_index, [AC_TRY_COMPILE([#include #include #include ], [struct ifreq ir;ir.ifr_index=0;], [sc_cv_struct_ifreq_ifr_index=yes], [sc_cv_struct_ifreq_ifr_index=no])]) if test $sc_cv_struct_ifreq_ifr_index = yes; then AC_DEFINE(HAVE_STRUCT_IFREQ_IFR_INDEX) fi AC_MSG_RESULT($sc_cv_struct_ifreq_ifr_index) # struct ifreq.ifr_ifindex # Linux has ifr_ifindex instead of ifr_index AC_MSG_CHECKING(for struct ifreq.ifr_ifindex) AC_CACHE_VAL(sc_cv_struct_ifreq_ifr_ifindex, [AC_TRY_COMPILE([#include #include #include ], [struct ifreq ir;ir.ifr_ifindex=0;], [sc_cv_struct_ifreq_ifr_ifindex=yes], [sc_cv_struct_ifreq_ifr_ifindex=no])]) if test $sc_cv_struct_ifreq_ifr_ifindex = yes; then AC_DEFINE(HAVE_STRUCT_IFREQ_IFR_IFINDEX) fi AC_MSG_RESULT($sc_cv_struct_ifreq_ifr_ifindex) # some systems have a sa_len field in struct sockaddr and we need to support it # so we can compare sockaddrs simply with memcmp AC_MSG_CHECKING(for struct sockaddr.sa_len) AC_CACHE_VAL(sc_cv_struct_sockaddr_salen, [AC_TRY_COMPILE([#include #include ], [struct sockaddr sa;sa.sa_len=0;], [sc_cv_struct_sockaddr_salen=yes], [sc_cv_struct_sockaddr_salen=no])]) if test $sc_cv_struct_sockaddr_salen = yes; then AC_DEFINE(HAVE_STRUCT_SOCKADDR_SALEN) fi AC_MSG_RESULT($sc_cv_struct_sockaddr_salen) ### IP6 sockaddr_in6 AC_MSG_CHECKING(for component names of sockaddr_in6) AC_TRY_COMPILE([#include #include ], [struct sockaddr_in6 sa6;sa6.sin6_addr.s6_addr[0]=0;], [AC_MSG_RESULT(s6_addr); AC_DEFINE(HAVE_IP6_SOCKADDR, 0)], [AC_TRY_COMPILE([#include #include ], [struct sockaddr_in6 sa6;sa6.sin6_addr.u6_addr.u6_addr16[0]=0;], [AC_MSG_RESULT(u6_addr.u6_addr16); AC_DEFINE(HAVE_IP6_SOCKADDR, 1)], [AC_TRY_COMPILE([#include #include ], [struct sockaddr_in6 sa6;sa6.sin6_addr.u6_addr16[0]=0;], [AC_MSG_RESULT(u6_addr16); AC_DEFINE(HAVE_IP6_SOCKADDR, 2)], [AC_TRY_COMPILE([#include #include ], [struct sockaddr_in6 sa6;sa6.sin6_addr.in6_u.u6_addr16[0]=0;], [AC_MSG_RESULT(in6_u.u6_addr16); AC_DEFINE(HAVE_IP6_SOCKADDR, 3)], [AC_TRY_COMPILE([#include #include ], [struct sockaddr_in6 sa6;sa6.sin6_addr._S6_un._S6_u32[0]=0;], [AC_MSG_RESULT(_S6_un._S6_u32); AC_DEFINE(HAVE_IP6_SOCKADDR, 4)], [AC_TRY_COMPILE([#include #include ], [struct sockaddr_in6 sa6;sa6.sin6_addr.__u6_addr.__u6_addr32[0]=0;], [AC_MSG_RESULT(__u6_addr.__u6_addr32); AC_DEFINE(HAVE_IP6_SOCKADDR, 5)], [AC_MSG_RESULT([none or unknown])] )])])])])]) dnl Check for struct iovec AC_MSG_CHECKING(for struct iovec) AC_CACHE_VAL(sc_cv_struct_iovec, [AC_TRY_COMPILE([#include ],[struct iovec s;], [sc_cv_struct_iovec=yes], [sc_cv_struct_iovec=no])]) if test $sc_cv_struct_iovec = yes; then AC_DEFINE(HAVE_STRUCT_IOVEC) fi AC_MSG_RESULT($sc_cv_struct_iovec) dnl check for msg_control in struct msghdr AC_MSG_CHECKING(for struct msghdr.msg_control) AC_CACHE_VAL(sc_cv_struct_msghdr_msgcontrol, [AC_TRY_COMPILE([#include #include ], [struct msghdr s;s.msg_control=0;], [sc_cv_struct_msghdr_msgcontrol=yes], [sc_cv_struct_msghdr_msgcontrol=no])]) if test $sc_cv_struct_msghdr_msgcontrol = yes; then AC_DEFINE(HAVE_STRUCT_MSGHDR_MSGCONTROL) fi AC_MSG_RESULT($sc_cv_struct_msghdr_msgcontrol) dnl check for msg_controllen in struct msghdr AC_MSG_CHECKING(for struct msghdr.msg_controllen) AC_CACHE_VAL(sc_cv_struct_msghdr_msgcontrollen, [AC_TRY_COMPILE([#include #include ], [struct msghdr s;s.msg_controllen=0;], [sc_cv_struct_msghdr_msgcontrollen=yes], [sc_cv_struct_msghdr_msgcontrollen=no])]) if test $sc_cv_struct_msghdr_msgcontrollen = yes; then AC_DEFINE(HAVE_STRUCT_MSGHDR_MSGCONTROLLEN) fi AC_MSG_RESULT($sc_cv_struct_msghdr_msgcontrollen) dnl check for msg_flags in struct msghdr AC_MSG_CHECKING(for struct msghdr.msgflags) AC_CACHE_VAL(sc_cv_struct_msghdr_msgflags, [AC_TRY_COMPILE([#include #include ], [struct msghdr s;s.msg_flags=0;], [sc_cv_struct_msghdr_msgflags=yes], [sc_cv_struct_msghdr_msgflags=no])]) if test $sc_cv_struct_msghdr_msgflags = yes; then AC_DEFINE(HAVE_STRUCT_MSGHDR_MSGFLAGS) fi AC_MSG_RESULT($sc_cv_struct_msghdr_msgflags) dnl check for struct cmsghdr AC_MSG_CHECKING(for struct cmsghdr) AC_CACHE_VAL(sc_cv_struct_cmsghdr, [AC_TRY_COMPILE([#include #include #include ],[struct cmsghdr s;], [sc_cv_struct_cmsghdr=yes], [sc_cv_struct_cmsghdr=no])]) if test $sc_cv_struct_cmsghdr = yes; then AC_DEFINE(HAVE_STRUCT_CMSGHDR) fi AC_MSG_RESULT($sc_cv_struct_cmsghdr) dnl check for struct in_pktinfo AC_MSG_CHECKING(for struct in_pktinfo) AC_CACHE_VAL(sc_cv_struct_in_pktinfo, [AC_TRY_COMPILE([#include #include #include ],[struct in_pktinfo s;], [sc_cv_struct_in_pktinfo=yes], [sc_cv_struct_in_pktinfo=no])]) if test $sc_cv_struct_in_pktinfo = yes; then AC_DEFINE(HAVE_STRUCT_IN_PKTINFO) fi AC_MSG_RESULT($sc_cv_struct_in_pktinfo) if test $sc_cv_struct_in_pktinfo = 'yes'; then dnl check for component ipi_spec_dst in struct in_pktinfo AC_MSG_CHECKING(for ipi_spec_dst in struct in_pktinfo) AC_CACHE_VAL(sc_cv_pktinfo_ipi_spec_dst, [AC_TRY_COMPILE([#include #include #include ],[struct in_pktinfo s; s.ipi_spec_dst], [sc_cv_pktinfo_ipi_spec_dst=yes], [sc_cv_pktinfo_ipi_spec_dst=no])]) if test $sc_cv_pktinfo_ipi_spec_dst = yes; then AC_DEFINE(HAVE_PKTINFO_IPI_SPEC_DST) fi AC_MSG_RESULT($sc_cv_pktinfo_ipi_spec_dst) fi dnl check for struct in6_pktinfo AC_MSG_CHECKING(for struct in6_pktinfo) AC_CACHE_VAL(sc_cv_struct_in6_pktinfo, [AC_TRY_COMPILE([#include "sysincludes.h"], [struct in6_pktinfo s;], [sc_cv_struct_in6_pktinfo=yes], [sc_cv_struct_in6_pktinfo=no])]) if test $sc_cv_struct_in6_pktinfo = yes; then AC_DEFINE(HAVE_STRUCT_IN6_PKTINFO) fi AC_MSG_RESULT($sc_cv_struct_in6_pktinfo) dnl check for ip_hl in struct ip AC_MSG_CHECKING(for struct ip.ip_hl) AC_CACHE_VAL(sc_cv_struct_ip_ip_hl, [AC_TRY_COMPILE([#include #include #include #include ], [struct ip s;s.ip_hl=0;], [sc_cv_struct_ip_ip_hl=yes], [sc_cv_struct_ip_ip_hl=no])]) if test $sc_cv_struct_ip_ip_hl = yes; then AC_DEFINE(HAVE_STRUCT_IP_IP_HL) fi AC_MSG_RESULT($sc_cv_struct_ip_ip_hl) dnl Library function checks dnl Check sigaction() AC_CHECK_FUNC(sigaction, AC_DEFINE(HAVE_SIGACTION)) dnl Check for 64bit versions of system calls AC_CHECK_FUNC(stat64, AC_DEFINE(HAVE_STAT64)) AC_CHECK_FUNC(fstat64, AC_DEFINE(HAVE_FSTAT64)) AC_CHECK_FUNC(lstat64, AC_DEFINE(HAVE_LSTAT64)) AC_CHECK_FUNC(lseek64, AC_DEFINE(HAVE_LSEEK64)) AC_CHECK_FUNC(truncate64, AC_DEFINE(HAVE_TRUNCATE64)) AC_CHECK_FUNC(ftruncate64, AC_DEFINE(HAVE_FTRUNCATE64)) AC_CHECK_FUNC(strtoll, AC_DEFINE(HAVE_STRTOLL)) AC_CHECK_FUNC(hstrerror, AC_DEFINE(HAVE_HSTRERROR)) AC_CHECK_FUNC(inet_ntop, AC_DEFINE(HAVE_INET_NTOP)) #if test "$ac_cv_func_hstrerror" = "yes"; then # AC_MSG_CHECKING(if _XOPEN_SOURCE_EXTENDED is helpful) # AC_CACHE_VAL(ac_cv_xopen_source_extended, # [AC_TRY_COMPILE([#include ], # [hstrerror()], # [ac_cv_xopen_source_extended=no], # [AC_TRY_COMPILE([#define _XOPEN_SOURCE_EXTENDED 1 ## include ], # [hstrerror()], # [ac_cv_xopen_source_extended=yes], # [ac_cv_xopen_source_extended=no] # )] # )]) # if test $ac_cv_xopen_source_extended = yes; then # AC_DEFINE(_XOPEN_SOURCE_EXTENDED) # fi # AC_MSG_RESULT($ac_cv_xopen_source_extended) #fi dnl Search for openpty() # MacOS AC_CHECK_FUNC(openpty, AC_DEFINE(HAVE_OPENPTY)) # AIX AC_CHECK_LIB(bsd, openpty, [LIBS="-lbsd $LIBS"; AC_DEFINE(HAVE_OPENPTY)]) # Linux 2.4 AC_CHECK_LIB(util, openpty, [LIBS="-lutil $LIBS"; AC_DEFINE(HAVE_OPENPTY)]) AC_CHECK_LIB(rt, clock_gettime, [LIBS="-lrt $LIBS"; AC_DEFINE(HAVE_CLOCK_GETTIME)]) dnl Search for flock() # with Linux it's in libc, with AIX in libbsd AC_CHECK_FUNC(flock, AC_DEFINE(HAVE_FLOCK), AC_CHECK_LIB(bsd, flock, [LIBS="-lbsd $LIBS"])) dnl Search for setenv() AC_CHECK_FUNC(setenv, AC_DEFINE(HAVE_SETENV), AC_CHECK_LIB(isode, setenv, [LIBS="-lisode $LIBS"])) dnl Search for unsetenv() AC_CHECK_FUNC(unsetenv, AC_DEFINE(HAVE_UNSETENV)) dnl Search for SSLv2_client_method, SSLv2_server_method AC_CHECK_FUNC(SSLv2_client_method, AC_DEFINE(HAVE_SSLv2_client_method), AC_CHECK_LIB(crypt, SSLv2_client_method, [LIBS=-lcrypt $LIBS])) AC_CHECK_FUNC(SSLv2_server_method, AC_DEFINE(HAVE_SSLv2_server_method), AC_CHECK_LIB(crypt, SSLv2_server_method, [LIBS=-lcrypt $LIBS])) dnl AC_CHECK_FUNC(SSL_CTX_set_default_verify_paths, AC_DEFINE(HAVE_SSL_CTX_set_default_verify_paths)) AC_CHECK_FUNC(SSLv3_client_method, AC_DEFINE(HAVE_SSLv3_client_method), AC_CHECK_LIB(crypt, SSLv3_client_method, [LIBS=-lcrypt $LIBS])) AC_CHECK_FUNC(SSLv3_server_method, AC_DEFINE(HAVE_SSLv3_server_method), AC_CHECK_LIB(crypt, SSLv3_server_method, [LIBS=-lcrypt $LIBS])) AC_CHECK_FUNC(SSLv23_client_method, AC_DEFINE(HAVE_SSLv23_client_method), AC_CHECK_LIB(crypt, SSLv23_client_method, [LIBS=-lcrypt $LIBS])) AC_CHECK_FUNC(SSLv23_server_method, AC_DEFINE(HAVE_SSLv23_server_method), AC_CHECK_LIB(crypt, SSLv23_server_method, [LIBS=-lcrypt $LIBS])) AC_CHECK_FUNC(TLSv1_client_method, AC_DEFINE(HAVE_TLSv1_client_method), AC_CHECK_LIB(crypt, TLSv1_client_method, [LIBS=-lcrypt $LIBS])) AC_CHECK_FUNC(TLSv1_server_method, AC_DEFINE(HAVE_TLSv1_server_method), AC_CHECK_LIB(crypt, TLSv1_server_method, [LIBS=-lcrypt $LIBS])) AC_CHECK_FUNC(TLSv1_1_client_method, AC_DEFINE(HAVE_TLSv1_1_client_method), AC_CHECK_LIB(crypt, TLSv1_1_client_method, [LIBS=-lcrypt $LIBS])) AC_CHECK_FUNC(TLSv1_1_server_method, AC_DEFINE(HAVE_TLSv1_1_server_method), AC_CHECK_LIB(crypt, TLSv1_1_server_method, [LIBS=-lcrypt $LIBS])) AC_CHECK_FUNC(TLSv1_2_client_method, AC_DEFINE(HAVE_TLSv1_2_client_method), AC_CHECK_LIB(crypt, TLSv1_2_client_method, [LIBS=-lcrypt $LIBS])) AC_CHECK_FUNC(TLSv1_2_server_method, AC_DEFINE(HAVE_TLSv1_2_server_method), AC_CHECK_LIB(crypt, TLSv1_2_server_method, [LIBS=-lcrypt $LIBS])) AC_CHECK_FUNC(DTLSv1_client_method, AC_DEFINE(HAVE_DTLSv1_client_method), AC_CHECK_LIB(crypt, DTLSv1_client_method, [LIBS=-lcrypt $LIBS])) AC_CHECK_FUNC(DTLSv1_server_method, AC_DEFINE(HAVE_DTLSv1_server_method), AC_CHECK_LIB(crypt, DTLSv1_server_method, [LIBS=-lcrypt $LIBS])) dnl Run time checks AC_MSG_CHECKING(if snprintf conforms to C99) AC_CACHE_VAL(ac_cv_have_c99_snprintf, [AC_TRY_RUN([ #include #include int main(void){ char s[2]; exit(snprintf(s,2,"ab")!=2); }], [ac_cv_have_c99_snprintf=yes], [ac_cv_have_c99_snprintf=no], [ac_cv_have_c99_snprintf=no])]) if test $ac_cv_have_c99_snprintf = yes; then AC_DEFINE(HAVE_C99_SNPRINTF) fi AC_MSG_RESULT($ac_cv_have_c99_snprintf) AC_MSG_CHECKING(if printf has Z modifier) AC_CACHE_VAL(ac_cv_have_z_modifier, if test "$cc" = gcc; then [AC_TRY_RUN([ #include #include int main(void){ char s[16]; sprintf(s,"%Zu",1); exit(strcmp(s,"1")); }], [ac_cv_have_z_modifier=yes], [ac_cv_have_z_modifier=no], [ac_cv_have_z_modifier=no])] else ac_cv_have_z_modifier=no fi ) if test $ac_cv_have_z_modifier = yes; then AC_DEFINE(HAVE_FORMAT_Z) fi AC_MSG_RESULT($ac_cv_have_z_modifier) dnl find the number of bits we must shift a value to match the given mask dnl (e.g., mask 0x00f0 requires shifting with 4) ## NOTE: some platforms only need one '\' to escape '"' in string constant define(AC_SHIFT_OFFSET,[ AC_CACHE_CHECK(shift offset of $1, $2, [LIBS1="$LIBS"; LIBS="" # avoid libwrap allow_severity undefined conftestoffset="conftestoffset.out" AC_TRY_RUN([ #include #include #include #include #include int main(){ unsigned int i,n=$1; FILE *f; if ((f=fopen("$conftestoffset","w"))==NULL){ fprintf(stderr,"\\"$conftestoffset\\": %s\n",strerror(errno)); exit(-1); } if (n==0) {fprintf(stderr,"$1 is 0 (impossible!)\n"); exit(1);} i=0; while (!(n&1)) { n>>=1; ++i; } if (3<],[int u; int v; exit(&u==&v);],,CHANCE_TO_TYPECHECK=0) CFLAGS="$CFLAGS1" dnl Does the test code compile without -Werror when types do not fit? if test "$CHANCE_TO_TYPECHECK" -ne 0; then AC_TRY_COMPILE([#include ],[int u; unsigned int v; exit(&u==&v);],,CHANCE_TO_TYPECHECK=0) fi dnl Does the test code fail to compile with -Werror when types do not fit? if test "$CHANCE_TO_TYPECHECK" -ne 0; then CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" AC_TRY_COMPILE([#include ],[int u; unsigned int v; exit(&u==&v);],CHANCE_TO_TYPECHECK=0,) CFLAGS="$CFLAGS1" fi if test "$CHANCE_TO_TYPECHECK" -ne 0; then AC_MSG_NOTICE(using compile -Werror method to find basic types) else AC_MSG_NOTICE(using code run method to find basic types) fi dnl see AC_BASIC_TYPE define(AC_BASIC_TYPE_GCC,[ AC_CACHE_CHECK(for equivalent simple type of $2, $4, [CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" dnl echo "echo: trying short for $2" >&2 AC_TRY_COMPILE([$1],[$2 u; short v; return(&u==&v);], [$4="1 /* short */"], [AC_TRY_COMPILE([$1],[$2 u; unsigned short v; return(&u==&v);], [$4="2 /* unsigned short */"], [AC_TRY_COMPILE([$1],[$2 u; int v; return(&u==&v);], [$4="3 /* int */"], [AC_TRY_COMPILE([$1],[$2 u; unsigned int v; return(&u==&v);], [$4="4 /* unsigned int */"], [AC_TRY_COMPILE([$1],[$2 u; long v; return(&u==&v);], [$4="5 /* long */"], [AC_TRY_COMPILE([$1],[$2 u; unsigned long v; return(&u==&v);], [$4="6 /* unsigned long */"], [AC_TRY_COMPILE([$1],[$2 u; long long v; return(&u==&v);], [$4="7 /* long long */"], [AC_TRY_COMPILE([$1],[$2 u; unsigned long long v; return(&u==&v);], [$4="8 /* unsigned long long */"], [$4="0 /* unknown, taking default */" ]) ]) ]) ]) ]) ]) ]) ]) CFLAGS="$CFLAGS1" ]) AC_DEFINE_UNQUOTED($3, ${$4}) ]) dnl see AC_BASIC_TYPE define(AC_BASIC_TYPE_OTHER,[ AC_CACHE_CHECK(for equivalent simple type of $2, $4, [AC_TRY_RUN([ $1 int main() { return!(sizeof($2)==sizeof(short));}], # same length as short AC_TRY_RUN([ $1 int main() { $2 x=-1; return !(x<0);}], [$4="1 /* short */"], [$4="2 /* unsigned short */"]), # length differs from short, try others AC_TRY_RUN([ $1 int main() { return!(sizeof($2)==sizeof(int));}], # same length as int AC_TRY_RUN([ $1 int main() { $2 x=-1; return !(x<0);}], [$4="3 /* int */"], [$4="4 /* unsigned int */"]), # length differs from int, try others AC_TRY_RUN([ $1 int main() { return !(sizeof($2)==sizeof(long));}], # same length as long AC_TRY_RUN([ $1 int main() { $2 x=-1; return !(x<0);}], [$4="5 /* long */"], [$4="6 /* unsigned long */"] ), # length differs from long, try others AC_TRY_RUN([ $1 int main() { return !(sizeof($2)==sizeof(long long));}], # same length as long long AC_TRY_RUN([ $1 int main() { $2 x=-1; return !(x<0);}], [$4="7 /* long long */"], [$4="8 /* unsigned long long */"] ), [$4="0 /* unknown */"] ) ) ) ) ]) AC_DEFINE_UNQUOTED($3, ${$4}) ]) dnl find what physical type (basic C type) is equivalent to the given type. dnl arg1: include file(s) dnl arg2: type name dnl arg3: output variable dnl arg4: cache variable (might be constructed automatically) dnl output values: 1..short, 2..unsigned short, 3..int, 4..u-int, dnl 5..long, 6..u-long; others not yet supported define(AC_BASIC_TYPE,[ if test "$CHANCE_TO_TYPECHECK" -ne 0; then AC_BASIC_TYPE_GCC([$1],[$2],[$3],[$4]) else AC_BASIC_TYPE_OTHER([$1],[$2],[$3],[$4]) fi ]) dnl See AC_TYPEOF_COMPONENT dnl This version is for compilers with -Werror or so: gcc, clang, Sun Studio? define(AC_TYPEOF_COMPONENT_GCC,[ AC_CACHE_CHECK(for basic type of $2.$3, $5, [CFLAGS1="$CFLAGS"; CFLAGS="$ERRONWARN $(echo "$CFLAGS1" | sed -e 's@-Wall@@g')" AC_TRY_COMPILE([$1],[$2 u;short v; return(&u.$3==&v);], [$5="1 /* short */"], [AC_TRY_COMPILE([$1],[$2 u; unsigned short v; return(&u.$3==&v);], [$5="2 /* unsigned short */"], [AC_TRY_COMPILE([$1],[$2 u; int v; return(&u.$3==&v);], [$5="3 /* int */"], [AC_TRY_COMPILE([$1],[$2 u; unsigned int v; return(&u.$3==&v);], [$5="4 /* unsigned int */"], [AC_TRY_COMPILE([$1],[$2 u; long v; return(&u.$3==&v);], [$5="5 /* long */"], [AC_TRY_COMPILE([$1],[$2 u; unsigned long v; return(&u.$3==&v);], [$5="6 /* unsigned long */"], [AC_TRY_COMPILE([$1],[$2 u; long long v; return(&u.$3==&v);], [$5="7 /* long long */"], [AC_TRY_COMPILE([$1],[$2 u; unsigned long long v; return(&u.$3==&v);], [$5="8 /* unsigned long long */"], [$5="0 /* unknown, taking default */" ]) ]) ]) ]) ]) ]) ]) ]) CFLAGS="$CFLAGS1" ]) AC_DEFINE_UNQUOTED($4, ${$5}) ]) dnl See AC_TYPEOF_COMPONENT dnl This version is for compilers with no -Werror or so define(AC_TYPEOF_COMPONENT_OTHER,[ AC_CACHE_CHECK(for basic type of $2.$3, $5, [AC_TRY_RUN([ $1 int main() { $2 x; return!(sizeof(x.$3)==sizeof(short));}], # same length as short AC_TRY_RUN([ $1 int main() { $2 x; x.$3=-1; return !(x.$3<0);}], [$5="1 /* short */"], [$5="2 /* unsigned short */"]), # length differs from short, try others AC_TRY_RUN([ $1 int main() { $2 x; return!(sizeof(x.$3)==sizeof(int));}], # same length as int AC_TRY_RUN([ $1 int main() { $2 x; x.$3=-1; return !(x.$3<0);}], [$5="3 /* int */"], [$5="4 /* unsigned int */"]), # length differs from int, try others AC_TRY_RUN([ $1 int main() { $2 x; return !(sizeof(x.$3)==sizeof(long));}], # same length as long AC_TRY_RUN([ $1 int main() { $2 x; x.$3=-1; return !(x.$3<0);}], [$5="5 /* long */"], [$5="6 /* unsigned long */"] ), # length differs from long, try others AC_TRY_RUN([ $1 int main() { $2 x; return !(sizeof(x.$3)==sizeof(long long));}], # same length as long long AC_TRY_RUN([ $1 int main() { x $2; x.$3=-1; return !(x.$3<0);}], [$5="7 /* long long */"], [$5="8 /* unsigned long long */"] ), [$5="0 /* unknown */"] ) ) ) ) ]) AC_DEFINE_UNQUOTED($4, ${$5}) ]) dnl find what physical type (basic C type) describes the given struct or union dnl component. dnl arg1: include file(s); must declare the structure type dnl arg2: struct name (e.g., "struct stat") dnl arg3: variable or component (e.g., "st_ino") dnl arg4: output variable, values see AC_BASIC_TYPE dnl arg5: cache variable (might be constructed automatically) define(AC_TYPEOF_COMPONENT,[ if test "$CHANCE_TO_TYPECHECK" -ne 0; then AC_TYPEOF_COMPONENT_GCC([$1],[$2],[$3],[$4],[$5]) else AC_TYPEOF_COMPONENT_OTHER([$1],[$2],[$3],[$4],[$5]) fi ]) AC_BASIC_TYPE([#include ], size_t, HAVE_BASIC_SIZE_T, sc_cv_type_sizet_basic) AC_BASIC_TYPE([#include #include #include ], mode_t, HAVE_BASIC_MODE_T, sc_cv_type_modet_basic) AC_BASIC_TYPE([#include #include ], pid_t, HAVE_BASIC_PID_T, sc_cv_type_pidt_basic) AC_BASIC_TYPE([#include #include ], uid_t, HAVE_BASIC_UID_T, sc_cv_type_uidt_basic) AC_BASIC_TYPE([#include #include ], gid_t, HAVE_BASIC_GID_T, sc_cv_type_gidt_basic) AC_BASIC_TYPE([#include ], time_t, HAVE_BASIC_TIME_T, sc_cv_type_timet_basic) # this is questionable, might fail on some systems AC_BASIC_TYPE([#include #include #include ], socklen_t, HAVE_BASIC_SOCKLEN_T, sc_cv_type_socklent_basic) AC_BASIC_TYPE([#include #include ], off_t, HAVE_BASIC_OFF_T, sc_cv_type_off_basic) AC_BASIC_TYPE([#include #include ], off64_t, HAVE_BASIC_OFF64_T, sc_cv_type_off64_basic) # oh god, __dev_t in Linux 2.4 is struct{int[2];}, not handled here yet. AC_BASIC_TYPE([#include ], dev_t, HAVE_BASIC_DEV_T, sc_cv_type_dev_basic) AC_TYPEOF_COMPONENT([#include ], struct stat, st_ino, HAVE_TYPEOF_ST_INO, sc_cv_type_stat_stino_basic) AC_TYPEOF_COMPONENT([#include ], struct stat, st_nlink, HAVE_TYPEOF_ST_NLINK, sc_cv_type_stat_stnlink_basic) AC_TYPEOF_COMPONENT([#include ], struct stat, st_size, HAVE_TYPEOF_ST_SIZE, sc_cv_type_stat_stsize_basic) AC_TYPEOF_COMPONENT([#include ], struct stat, st_blksize, HAVE_TYPEOF_ST_BLKSIZE, sc_cv_type_stat_stblksize_basic) AC_TYPEOF_COMPONENT([#include ], struct stat, st_blocks, HAVE_TYPEOF_ST_BLOCKS, sc_cv_type_stat_stblocks_basic) # if test "$ac_cv_func_stat64" = yes; then AC_TYPEOF_COMPONENT([#include ], struct stat64, st_dev, HAVE_TYPEOF_ST64_DEV, sc_cv_type_stat64_stdev_basic) AC_TYPEOF_COMPONENT([#include ], struct stat64, st_ino, HAVE_TYPEOF_ST64_INO, sc_cv_type_stat64_stino_basic) AC_TYPEOF_COMPONENT([#include ], struct stat64, st_nlink, HAVE_TYPEOF_ST64_NLINK, sc_cv_type_stat64_stnlink_basic) AC_TYPEOF_COMPONENT([#include ], struct stat64, st_size, HAVE_TYPEOF_ST64_SIZE, sc_cv_type_stat64_stsize_basic) AC_TYPEOF_COMPONENT([#include ], struct stat64, st_blksize, HAVE_TYPEOF_ST64_BLKSIZE, sc_cv_type_stat64_stblksize_basic) AC_TYPEOF_COMPONENT([#include ], struct stat64, st_blocks, HAVE_TYPEOF_ST64_BLOCKS, sc_cv_type_stat64_stblocks_basic) fi AC_TYPEOF_COMPONENT([#include ], struct timeval, tv_usec, HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC, sc_cv_type_struct_timeval_tv_usec) AC_TYPEOF_COMPONENT([#include #include #include ], struct rlimit, rlim_max, HAVE_TYPEOF_RLIM_MAX, sc_cv_type_rlimit_rlimmax_basic) # Fedora-19 doc says it is socklen_t which is equivalent to unsigned int, but it is equivalent to size_t (x86_64) AC_TYPEOF_COMPONENT([#include "sysincludes.h"], struct cmsghdr, cmsg_len, HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN, sc_cv_typeof_struct_cmsghdr_cmsg_len) ### snprintf, vsnprintf AC_MSG_CHECKING(for /dev/ptmx) if test -c /dev/ptmx; then AC_DEFINE(HAVE_DEV_PTMX, 1) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) AC_MSG_CHECKING(for /dev/ptc) if test -c /dev/ptc; then AC_DEFINE(HAVE_DEV_PTC) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi fi AC_MSG_CHECKING(for /proc) if test -d /proc; then AC_DEFINE(HAVE_PROC_DIR, 1) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi AC_MSG_CHECKING(for /proc/*/fd) if test -d /proc/$$/fd; then AC_DEFINE(HAVE_PROC_DIR_FD, 1) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl "tcpd" "tcpwrappers" # on some platforms, raw linking with libwrap fails because allow_severity and # deny_severity are not explicitely defined. Thus we put the libwrap part to # the end AC_MSG_CHECKING(whether to include libwrap support) AC_ARG_ENABLE(libwrap, [ --disable-libwrap disable libwrap support], [ case "$enableval" in no) AC_MSG_RESULT(no); WITH_LIBWRAP= ;; *) AC_MSG_RESULT(yes); WITH_LIBWRAP=1 ;; esac], [ AC_MSG_RESULT(yes); WITH_LIBWRAP=1 ]) # # check if we find the components of libwrap ("tcpd" "tcpwrappers") if test -n "$WITH_LIBWRAP"; then AC_MSG_CHECKING(for components of libwrap) # first, we need to find the include file AC_CACHE_VAL(sc_cv_have_tcpd_h, [AC_TRY_COMPILE([#include #include ],[;], [sc_cv_have_tcpd_h=yes; LIBWRAP_ROOT=""], [sc_cv_have_tcpd_h=no for D in "/sw" "/usr/local" "/opt/freeware" "/usr/sfw"; do I="$D/include" i="$I/tcpd.h" if test -r "$i"; then #V_INCL="$V_INCL -I$I" CPPFLAGS="$CPPFLAGS -I$I" AC_MSG_NOTICE(found $i) sc_cv_have_tcpd_h=yes; LIBWRAP_ROOT="$D" break; fi done]) ]) if test "$sc_cv_have_tcpd_h" = "yes"; then AC_DEFINE(HAVE_TCPD_H) fi AC_MSG_NOTICE(checked for tcpd.h... $sc_cv_have_tcpd_h) fi # end checking for tcpd.h if test -n "$WITH_LIBWRAP" -a "$sc_cv_have_tcpd_h" = yes; then # next, we search for the wrap library (libwrap.*) AC_MSG_CHECKING(for libwrap) AC_CACHE_VAL(sc_cv_have_libwrap, [ LIBS0="$LIBS" if test -n "$LIBWRAP_ROOT"; then L="$LIBWRAP_ROOT/lib"; LIBS="-L$L -lwrap $LIBS" else LIBS="-lwrap $LIBS" fi AC_TRY_LINK([#include #include int allow_severity,deny_severity;],[hosts_access(0)], [sc_cv_have_libwrap='yes'], [sc_cv_have_libwrap='no' LIBS="$LIBS -lnsl" # RedHat73 AC_TRY_LINK([#include #include int allow_severity,deny_severity;],[hosts_access(0)], [sc_cv_have_libwrap='yes'], [sc_cv_have_libwrap='no']) ] ) if test "$sc_cv_have_libwrap" != 'yes'; then LIBS="$LIBS0" fi ] ) if test "$sc_cv_have_libwrap" = 'yes'; then AC_DEFINE(HAVE_LIBWRAP) fi AC_MSG_RESULT($sc_cv_have_libwrap) fi # if test -n "$WITH_LIBWRAP"; then if test "$sc_cv_have_tcpd_h" = "yes" -a "$sc_cv_have_libwrap" = "yes"; then AC_DEFINE(WITH_LIBWRAP) else AC_MSG_WARN([not all components of tcp wrappers found, disabling it]); fi fi # check of hosts_allow_table if test -n "$WITH_LIBWRAP"; then AC_MSG_CHECKING(for hosts_allow_table) AC_CACHE_VAL(sc_cv_have_hosts_allow_table, [AC_TRY_COMPILE([#include #include ],[hosts_allow_table="";], [sc_cv_have_hosts_allow_table=yes], [sc_cv_have_hosts_allow_table=no])]) if test $sc_cv_have_hosts_allow_table = yes; then AC_DEFINE(HAVE_HOSTS_ALLOW_TABLE) fi AC_MSG_RESULT($sc_cv_have_hosts_allow_table) fi # test -n "$WITH_LIBWRAP" if test "$GCC" = yes; then CFLAGS="$CFLAGS" fi # FIPS support requires compiling with fipsld. # fipsld requires the FIPSLD_CC variable to be set to the original CC. # This check must be done after all other checks that require compiling # so that fipsld is not used by the configure script itself. if test -n "$WITH_FIPS"; then if test "$sc_cv_have_openssl_fips_h" = 'yes' -a "$sc_cv_have_libcrypto" = 'yes'; then FIPSLD_CC=$CC if test "${FIPSLD+set}" != set ; then FIPSLD=fipsld fi CC="FIPSLD_CC=$CC $FIPSLD" fi fi AC_SUBST(FIPSLD_CC) # autoconf does not seem to provide AC_CHECK_VAR or so # thus we have to check by foot AC_MSG_CHECKING(for declaration of environ) AC_CACHE_VAL(sc_cv_decl_environ, [AC_TRY_COMPILE([#include ],[char **s = environ;], [sc_cv_decl_environ=yes], [sc_cv_decl_environ=no])]) if test $sc_cv_decl_environ = yes; then AC_DEFINE(HAVE_DECL_ENVIRON) fi AC_MSG_RESULT($sc_cv_decl_environ) # on some systems environ exists but not the declaration AC_MSG_CHECKING(for var environ) AC_CACHE_VAL(sc_cv_var_environ, [AC_TRY_COMPILE([],[extern char **environ; char **s = environ;], [sc_cv_var_environ=yes], [sc_cv_var_environ=no])]) if test $sc_cv_var_environ = yes; then AC_DEFINE(HAVE_VAR_ENVIRON) fi AC_MSG_RESULT($sc_cv_var_environ) # allow BUILD_DATE to be externally set for build reproducibility if test "$BUILD_DATE"; then AC_DEFINE_UNQUOTED(BUILD_DATE, ["$BUILD_DATE"]) else AC_DEFINE(BUILD_DATE, [__DATE__" "__TIME__]) fi AC_OUTPUT(Makefile) socat-1.7.3.1/utils.h0000644000201000020100000000527012455415361014103 0ustar gerhardgerhard/* source: utils.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __utils_h_included #define __utils_h_included 1 /* a generic name table entry */ struct wordent { const char *name; void *desc; } ; #if !HAVE_PROTOTYPE_LIB_memrchr extern void *memrchr(const void *s, int c, size_t n); #endif extern void *memdup(const void *src, size_t n); #if !HAVE_SETENV extern int setenv(const char *name, const char *value, int overwrite); #endif /* !HAVE_SETENV */ extern const struct wordent *keyw(const struct wordent *keywds, const char *name, unsigned int nkeys); #define XIOSAN_ZERO_MASK 0x000f #define XIOSAN_ZERO_DEFAULT 0x0000 #define XIOSAN_ZERO_DOT 0x0001 #define XIOSAN_ZERO_BACKSLASH_OCT_3 0x0002 #define XIOSAN_ZERO_BACKSLASH_OCT_4 0x0003 #define XIOSAN_ZERO_BACKSLASHX_HEX_UP 0x0004 #define XIOSAN_ZERO_BACKSLASHX_HEX_LOW 0x0005 #define XIOSAN_ZERO_PERCENT_HEX_UP 0x0006 #define XIOSAN_ZERO_PERCENT_HEX_LOW 0x0007 #define XIOSAN_CONTROL_MASK 0x00f0 #define XIOSAN_CONTROL_DEFAULT 0x0000 #define XIOSAN_CONTROL_DOT 0x0010 #define XIOSAN_CONTROL_BACKSLASH_OCT_3 0x0020 #define XIOSAN_CONTROL_BACKSLASH_OCT_4 0x0030 #define XIOSAN_CONTROL_BACKSLASHX_HEX_UP 0x0040 #define XIOSAN_CONTROL_BACKSLASHX_HEX_LOW 0x0050 #define XIOSAN_CONTROL_PERCENT_HEX_UP 0x0060 #define XIOSAN_CONTROL_PERCENT_HEX_LOW 0x0070 #define XIOSAN_UNPRINT_MASK 0x0f00 #define XIOSAN_UNPRINT_DEFAULT 0x0000 #define XIOSAN_UNPRINT_DOT 0x0100 #define XIOSAN_UNPRINT_BACKSLASH_OCT_3 0x0200 #define XIOSAN_UNPRINT_BACKSLASH_OCT_4 0x0300 #define XIOSAN_UNPRINT_BACKSLASHX_HEX_UP 0x0400 #define XIOSAN_UNPRINT_BACKSLASHX_HEX_LOW 0x0500 #define XIOSAN_UNPRINT_PERCENT_HEX_UP 0x0600 #define XIOSAN_UNPRINT_PERCENT_HEX_LOW 0x0700 #define XIOSAN_DEFAULT_MASK 0xf000 #define XIOSAN_DEFAULT_BACKSLASH_DOT 0x1000 #define XIOSAN_DEFAULT_BACKSLASH_OCT_3 0x2000 #define XIOSAN_DEFAULT_BACKSLASH_OCT_4 0x3000 #define XIOSAN_DEFAULT_BACKSLASHX_HEX_UP 0x4000 #define XIOSAN_DEFAULT_BACKSLASHX_HEX_LOW 0x5000 #define XIOSAN_DEFAULT_PERCENT_HEX_UP 0x6000 #define XIOSAN_DEFAULT_PERCENT_HEX_LOW 0x7000 extern char *sanitize_string(const char *data, /* input data */ size_t bytes, /* length of input data, >=0 */ char *coded, /* output buffer, must be long enough */ int style); extern char *xiosubstr(char *scratch, const char *str, size_t from, size_t len); extern int xio_snprintf(char *str, size_t size, const char *format, ...); #endif /* !defined(__utils_h_included) */ socat-1.7.3.1/procan_main.c0000644000201000020100000000531012460670272015217 0ustar gerhardgerhard/* source: procan_main.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ const char copyright[] = "procan by Gerhard Rieger - send bug reports to socat@dest-unreach.org"; #include /* sig_atomic_t for error.h */ #include /* struct timespec for error.h */ #include /* strtoul() */ #include #include #include "config.h" #if HAVE_SYS_SELECT_H #include /* select(), fdset on FreeBSD */ #endif #include "mytypes.h" #include "error.h" #include "procan.h" #include "hostan.h" #define WITH_HELP 1 static void procan_usage(FILE *fd); int main(int argc, const char *argv[]) { const char **arg1; #if 0 unsigned int n = 1024; /* this is default on my Linux */ #endif diag_set('p', strchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]); arg1 = argv+1; --argc; while (arg1[0] && (arg1[0][0] == '-')) { switch (arg1[0][1]) { #if WITH_HELP case '?': case 'h': procan_usage(stdout); exit(0); #endif /* WITH_HELP */ case 'c': procan_cdefs(stdout); exit(0); #if LATER case 'V': procan_version(stdout); exit(0); case 'l': diag_set(arg1[0][2], &arg1[0][3]); break; case 'd': diag_set('d', NULL); break; #endif #if 0 case 'n': n = strtoul(&arg1[0][2], NULL, 0); break; #endif case '\0': break; default: diag_set_int('e', E_FATAL); Error1("unknown option \"%s\"", arg1[0]); #if WITH_HELP procan_usage(stderr); #endif exit(1); } if (arg1[0][1] == '\0') break; ++arg1; --argc; } if (argc != 0) { Error1("%d superfluous arguments", argc); #if WITH_HELP procan_usage(stderr); #endif exit(1); } procan(stdout); hostan(stdout); return 0; } #if WITH_HELP static void procan_usage(FILE *fd) { fputs(copyright, fd); fputc('\n', fd); fputs("Analyze system parameters of process\n", fd); fputs("Usage:\n", fd); fputs("procan [options]\n", fd); fputs(" options:\n", fd); #if LATER fputs(" -V print version information to stdout, and exit\n", fd); #endif #if WITH_HELP fputs(" -?|-h print a help text describing command line options\n", fd); #endif fputs(" -c print values of compile time C defines\n", fd); #if LATER fputs(" -d increase verbosity (use up to 4 times; 2 are recommended)\n", fd); #endif #if 0 fputs(" -ly[facility] log to syslog, using facility (default is daemon)\n", fd); fputs(" -lf log to file\n", fd); fputs(" -ls log to stderr (default if no other log)\n", fd); #endif #if 0 fputs(" -n first file descriptor number not analyzed\n", fd); #endif } #endif /* WITH_HELP */ socat-1.7.3.1/vsnprintf_r.h0000644000201000020100000000060712460670272015314 0ustar gerhardgerhard/* source: vsnprintf_r.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __vsnprintf_r_h_included #define __vsnprintf_r_h_included 1 int vsnprintf_r(char *str, size_t size, const char *format, va_list ap); int snprintf_r(char *str, size_t size, const char *format, ...); #endif /* !defined(__vsnprintf_r_h_included) */ socat-1.7.3.1/sycls.h0000644000201000020100000002356612455415361014110 0ustar gerhardgerhard/* source: sycls.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __sycls_h_included #define __sycls_h_included 1 #if WITH_SYCLS struct termios; /* prevent gcc from spitting silly warning */ struct utsname; struct flock; struct addrinfo; mode_t Umask(mode_t mask); int Open(const char *pathname, int flags, mode_t mode); int Creat(const char *pathname, mode_t mode); off_t Lseek(int fildes, off_t offset, int whence); #if HAVE_LSEEK64 off64_t Lseek64(int fildes, off64_t offset, int whence); #endif pid_t Getpid(void); pid_t Getppid(void); pid_t Getpgrp(void); int Getpgid(pid_t pid); int Setpgid(pid_t pid, pid_t pgid); int Setpgrp(void); pid_t Tcgetpgrp(int fd); int Tcsetpgrp(int fd, pid_t pgrpid); pid_t Getsid(pid_t pid); pid_t Setsid(void); uid_t Getuid(void); uid_t Geteuid(void); int Setuid(uid_t uid); gid_t Getgid(void); gid_t Getegid(void); int Setgid(gid_t gid); int Initgroups(const char *user, gid_t group); int Getgroups(int size, gid_t list[]); int Setgroups(size_t size, const gid_t *list); int Getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups); int Chdir(const char *path); int Chroot(const char *path); int Gettimeofday(struct timeval *tv, struct timezone *tz); int Mknod(const char *pathname, mode_t mode, dev_t dev); int Mkfifo(const char *pathname, mode_t mode); int Stat(const char *file_name, struct stat *buf); int Fstat(int filedes, struct stat *buf); int Lstat(const char *file_name, struct stat *buf); #if HAVE_STAT64 int Stat64(const char *file_name, struct stat64 *buf); int Fstat64(int filedes, struct stat64 *buf); int Lstat64(const char *file_name, struct stat64 *buf); #endif /* HAVE_STAT64 */ int Dup(int oldfd); int Dup2(int oldfd, int newfd); int Pipe(int filedes[2]); ssize_t Read(int fd, void *buf, size_t count); ssize_t Write(int fd, const void *buf, size_t count); int Fcntl(int fd, int cmd); int Fcntl_l(int fd, int cmd, long arg); int Fcntl_lock(int fd, int cmd, struct flock *l); int Ftruncate(int fd, off_t length); #if HAVE_FTRUNCATE64 int Ftruncate64(int fd, off64_t length); #endif /* HAVE_FTRUNCATE64 */ int Flock(int fd, int operation); int Ioctl(int d, int request, void *argp); int Ioctl_int(int d, int request, int arg); int Close(int fd); int Fchown(int fd, uid_t owner, gid_t group); int Fchmod(int fd, mode_t mode); int Unlink(const char *pathname); int Symlink(const char *oldpath, const char *newpath); int Readlink(const char *path, char *buf, size_t bufsiz); int Chown(const char *path, uid_t owner, gid_t group); int Chmod(const char *path, mode_t mode); int Poll(struct pollfd *ufds, unsigned int nfds, int timeout); int Select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); pid_t Fork(void); pid_t Waitpid(pid_t pid, int *status, int options); #ifndef HAVE_TYPE_SIGHANDLER typedef RETSIGTYPE (*sighandler_t)(int); #endif sighandler_t Signal(int signum, sighandler_t handler); int Sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); int Sigprocmask(int how, const sigset_t *set, sigset_t *oset); unsigned int Alarm(unsigned int seconds); int Kill(pid_t pid, int sig); int Link(const char *oldpath, const char *newpath); int Execvp(const char *file, char *const argv[]); int System(const char *string); int Socketpair(int d, int type, int protocol, int sv[2]); #if _WITH_SOCKET int Socket(int domain, int type, int protocol); int Bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen); int Connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen); int Listen(int s, int backlog); int Accept(int s, struct sockaddr *addr, socklen_t *addrlen); int Getsockname(int s, struct sockaddr *name, socklen_t *namelen); int Getpeername(int s, struct sockaddr *name, socklen_t *namelen); int Getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); int Setsockopt(int s, int level, int optname, const void *optval, int optlen); int Recv(int s, void *buf, size_t len, int flags); int Recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); int Recvmsg(int s, struct msghdr *msg, int flags); int Send(int s, const void *mesg, size_t len, int flags); int Sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); int Shutdown(int fd, int how); #endif /* _WITH_SOCKET */ unsigned int Sleep(unsigned int seconds); void Usleep(unsigned long usec); unsigned int Nanosleep(const struct timespec *req, struct timespec *rem); int Pause(void); struct hostent *Gethostbyname(const char *name); int Getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); struct hostent *Getipnodebyname(const char *name, int af, int flags, int *error_num); void *Malloc(size_t size); void *Calloc(size_t nmemb, size_t size); void *Realloc(void *ptr, size_t size); int Tcgetattr(int fd, struct termios *termios_p); int Tcsetattr(int fd, int optional_actions, struct termios *termios_p); char *Ttyname(int fd); int Isatty(int fd); struct winsize; /* avoid warnings */ int Openpty(int *ptyfd, int *ttyfd, char *ptyname, struct termios *termp, struct winsize *winp); char *Ptsname(int fd); int Grantpt(int fd); int Unlockpt(int fd); int Gethostname(char *name, size_t len); int Uname(struct utsname *buf); int Atexit(void (*func)(void)); void Exit(int status); void Abort(void); int Mkstemp(char *template); int Setenv(const char *name, const char *value, int overwrite); void Unsetenv(const char *name); char *Readline(const char *prompt); void Using_history(void); int Read_history(const char *filename); int Write_history(const char *filename); int Append_history(int nelements, const char *filename); int Read_history(const char *filename); void Add_history(const char *string); #else /* !WITH_SYCLS */ #define Umask(m) umask(m) #define Open(p,f,m) open(p,f,m) #define Creat(p,m) creat(p,m) #define Lseek(f,o,w) lseek(f,o,w) #define Lseek64(f,o,w) lseek64(f,o,w) #define Getpid() getpid() #define Getppid() getppid() #define Getpgrp() getpgrp() #define Getpgid(p) getpgid(p) #define Setpgid(p,g) setpgid(p,g) #define Setpgrp() setpgrp() #define Tcgetpgrp(f) tcgetpgrp(f) #define Tcsetpgrp(f,p) tcsetpgrp(f,p) #define Getsid(p) getsid(p) #define Setsid() setsid() #define Getuid() getuid() #define Geteuid() geteuid() #define Setuid(u) setuid(u) #define Getgid() getgid() #define Getegid() getegid() #define Setgid(g) setgid(g) #define Initgroups(u,g) initgroups(u,g) #define Getgroups(s,l) getgroups(s,l) #define Setgroups(s,l) setgroups(s,l) #define Getgrouplist(u,g,gs,n) getgrouplist(u,g,gs,n) #define Chdir(p) chdir(p) #define Chroot(p) chroot(p) #define Gettimeofday(tv,tz) gettimeofday(tv,tz) #define Mknod(p,m,d) mknod(p,m,d) #define Mkfifo(p,m) mkfifo(p,m) #define Stat(f,b) stat(f,b) #define Stat64(f,b) stat64(f,b) #define Fstat(f,b) fstat(f,b) #define Fstat64(f,b) fstat64(f,b) #define Lstat(f,b) lstat(f,b) #define Lstat64(f,b) lstat64(f,b) #define Dup(o) dup(o) #define Dup2(o,n) dup2(o,n) #define Pipe(f) pipe(f) #define Read(f,b,c) read(f,b,c) #define Write(f,b,c) write(f,b,c) #define Fcntl(f,c) fcntl(f,c) #define Fcntl_l(f,c,a) fcntl(f,c,a) #define Fcntl_lock(f,c,l) fcntl(f,c,l) #define Ftruncate(f,l) ftruncate(f,l) #define Ftruncate64(f,l) ftruncate64(f,l) #define Flock(f,o) flock(f,o) #define Ioctl(d,r,a) ioctl(d,r,a) #define Ioctl_int(d,r,a) ioctl(d,r,a) #define Close(f) close(f) #define Fchown(f,o,g) fchown(f,o,g) #define Fchmod(f,m) fchmod(f,m) #define Unlink(p) unlink(p) #define Symlink(op,np) symlink(op,np) #define Readlink(p,b,s) readlink(p,b,s) #define Chown(p,o,g) chown(p,o,g) #define Chmod(p,m) chmod(p,m) #define Poll(u, n, t) poll(u, n, t) #define Select(n,r,w,e,t) select(n,r,w,e,t) #define Fork() fork() #define Waitpid(p,s,o) waitpid(p,s,o) #define Signal(s,h) signal(s,h) #define Sigaction(s,a,o) sigaction(s,a,o) #define Sigprocmask(h,s,o) sigprocmask(h,s,o) #define Alarm(s) alarm(s) #define Kill(p,s) kill(p,s) #define Link(o,n) link(o,n) #define Execvp(f,a) execvp(f,a) #define System(s) system(s) #define Socketpair(d,t,p,s) socketpair(d,t,p,s) #define Socket(d,t,p) socket(d,t,p) #define Bind(s,m,a) bind(s,m,a) #define Connect(s,a,l) connect(s,a,l) #define Listen(s,b) listen(s,b) #define Accept(s,a,l) accept(s,a,l) #define Getsockname(s,n,l) getsockname(s,n,l) #define Getpeername(s,n,l) getpeername(s,n,l) #define Getsockopt(s,d,n,v,l) getsockopt(s,d,n,v,l) #define Setsockopt(s,d,n,v,l) setsockopt(s,d,n,v,l) #define Recv(s,b,l,f) recv(s,b,l,f) #define Recvfrom(s,b,bl,f,fr,fl) recvfrom(s,b,bl,f,fr,fl) #define Recvmsg(s,m,f) recvmsg(s,m,f) #define Send(s,m,l,f) send(s,m,l,f) #define Sendto(s,b,bl,f,t,tl) sendto(s,b,bl,f,t,tl) #define Shutdown(f,h) shutdown(f,h) #define Sleep(s) sleep(s) #define Usleep(u) usleep(u) #define Nanosleep(req,rem) nanosleep(req,rem) #define Pause() pause() #define Gethostbyname(n) gethostbyname(n) #define Getaddrinfo(n,s,h,r) getaddrinfo(n,s,h,r) #define Getipnodebyname(n,a,f,e) getipnodebyname(n,a,f,e) #define Malloc(s) malloc(s) #define Calloc(n,s) calloc(n,s) #define Realloc(p,s) realloc(p,s) #define Tcgetattr(f,t) tcgetattr(f,t) #define Tcsetattr(f,o,t) tcsetattr(f,o,t) #define Ttyname(f) ttyname(f) #define Isatty(f) isatty(f) #define Openpty(p,t,n,i,f) openpty(p,t,n,i,f) #define Ptsname(f) ptsname(f) #define Grantpt(f) grantpt(f) #define Unlockpt(f) unlockpt(f) #define Getpgid(p) getpgid(p) #define Gethostname(n,l) gethostname(n,l) #define Uname(b) uname(b) #define Atexit(f) atexit(f) #define Exit(s) exit(s) #define Abort() abort() #define Mkstemp(t) mkstemp(t) #define Setenv(n,v,o) setenv(n,v,o) #define Unsetenv(n) unsetenv(n) #define Readline(p) readline(p) #define Using_history() using_history() #define Read_history(f) read_history(f) #define Write_history(f) write_history(f) #define Append_history(n,f) append_history(n,f) #define Read_history(f) read_history(f) #define Add_history(s) add_history(s) #endif /* !WITH_SYCLS */ #endif /* !defined(__sycls_h_included) */ socat-1.7.3.1/procan.h0000644000201000020100000000047511453022152014214 0ustar gerhardgerhard/* source: procan.h */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __procan_h_included #define __procan_h_included 1 extern int procan(FILE *outfile); extern int procan_cdefs(FILE *outfile); #endif /* !defined(__procan_h_included) */ socat-1.7.3.1/xiomodes.h0000644000201000020100000000215411453022152014555 0ustar gerhardgerhard/* source: xiomodes.h */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xiomodes_h_included #define __xiomodes_h_included 1 #include "xiolayer.h" #include "xio-process.h" #include "xio-fd.h" #include "xio-fdnum.h" #include "xio-stdio.h" #include "xio-named.h" #include "xio-file.h" #include "xio-creat.h" #include "xio-gopen.h" #include "xio-pipe.h" #if _WITH_SOCKET #include "xio-socket.h" #include "xio-listen.h" #include "xio-unix.h" #include "xio-rawip.h" #include "xio-interface.h" #include "xio-ip.h" #if WITH_IP4 #include "xio-ip4.h" #endif /* WITH_IP4 */ #include "xio-ip6.h" #include "xio-ipapp.h" #include "xio-tcp.h" #include "xio-udp.h" #include "xio-sctp.h" #include "xio-socks.h" #include "xio-proxy.h" #endif /* _WITH_SOCKET */ #include "xio-progcall.h" #include "xio-exec.h" #include "xio-system.h" #include "xio-termios.h" #include "xio-readline.h" #include "xio-pty.h" #include "xio-openssl.h" #include "xio-tcpwrap.h" #include "xio-ext2.h" #include "xio-tun.h" #include "xio-streams.h" #endif /* !defined(__xiomodes_h_included) */ socat-1.7.3.1/mail.sh0000755000201000020100000000377012161506654014056 0ustar gerhardgerhard#! /bin/sh # source: mail.sh # Copyright Gerhard Rieger 2001-2009 # Published under the GNU General Public License V.2, see file COPYING #set -vx # This is an example for a shell script that can be fed to socat with exec. # Its clue is that it does not use stdin/stdout for communication with socat, # so you may feed the mail message via stdin to the script. The message should # contain appropriate mail headers without continuation lines. # socat establishes the connection to the SMTP server; the script performs the # SMTP dialog and afterwards transfers the message body to the server. # Lines with only a dot are not permitted - use two dots as escape. # This script supports multiline answers from server, but not much more yet. # Usage: cat message.txt |socat exec:"mail.sh target@domain.com",fdin=3,fdout=4 tcp:mail.relay.org:25,crlf while [ "$1" ]; do case "$1" in -f) shift; mailfrom="$1"; shift;; *) break;; esac done rcptto="$1" [ -z "$1" ] && rcptto="root@loopback" #server=$(expr "$rcptto" : '[^@]*@\(.*\)') [ -z "$mailfrom" ] && mailfrom="$USER@$(hostname)" # this function waits for a complete server message, checks if its status # is in the permitted range (terminates session if not), and returns. mail_chat () { local cmd="$1" local errlevel="$2"; [ -z "$errlevel" ] && errlevel=300 if [ "$cmd" ]; then echo "> $cmd" >&2; fi if [ -n "$cmd" ]; then echo "$cmd" >&4; fi while read status message <&3; ( case "$status" in [0-9][0-9][0-9]-*) exit 0;; [0-9][0-9][0-9]*) exit 1;; *) exit 1;; esac ) do :; done if [ -z "$status" ]; then echo smtp connection failed >&2; exit; fi echo "< $status $message" >&2 if [ "$status" -ge "$errlevel" ]; then echo $message >&2 echo "QUIT" >&4; exit 1 fi } # expect server greeting mail_chat mail_chat "HELO $(hostname)" mail_chat "MAIL FROM: $mailfrom" mail_chat "RCPT TO: $rcptto" mail_chat "DATA" 400 while read l; do echo "$l" >&4; done mail_chat "." mail_chat "QUIT" exit 0 socat-1.7.3.1/xio-pty.c0000644000201000020100000001663712455415361014360 0ustar gerhardgerhard/* source: xio-pty.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for creating pty addresses */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-named.h" #include "xio-termios.h" #if WITH_PTY /* here define the preferred polling intervall, in seconds */ #define PTY_INTERVALL 1,0 /* for struct timespec */ #define MAXPTYNAMELEN 64 static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); const struct addrdesc addr_pty = { "pty", 3, xioopen_pty, GROUP_NAMED|GROUP_FD|GROUP_TERMIOS|GROUP_PTY, 0, 0, 0 HELP("") }; const struct optdesc opt_symbolic_link = { "symbolic-link", "link", OPT_SYMBOLIC_LINK, GROUP_PTY, PH_LATE, TYPE_FILENAME, OFUNC_SPEC, 0, 0 }; #if HAVE_POLL const struct optdesc opt_pty_wait_slave = { "pty-wait-slave", "wait-slave", OPT_PTY_WAIT_SLAVE, GROUP_PTY, PH_EARLY, TYPE_BOOL, OFUNC_SPEC, 0, 0 }; 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, unsigned groups, int dummy1, int dummy2, int dummy3) { /* we expect the form: filename */ int ptyfd = -1, ttyfd = -1; #if defined(HAVE_DEV_PTMX) || defined(HAVE_DEV_PTC) bool useptmx = false; /* use /dev/ptmx or equivalent */ #endif #if HAVE_OPENPTY bool useopenpty = false; /* try only openpty */ #endif /* HAVE_OPENPTY */ char ptyname[MAXPTYNAMELEN]; char *tn = NULL; char *linkname = NULL; bool opt_unlink_close = true; /* remove symlink afterwards */ bool wait_slave = false; /* true would be better for many platforms, but some OSes cannot handle this, and for common default behaviour as well as backward compatibility we choose "no" as default */ struct timespec pollintv = { PTY_INTERVALL }; if (argc != 1) { Error2("%s: wrong number of parameters (%d instead of 0)", argv[0], argc-1); } xfd->stream.howtoend = END_CLOSE; if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); /* trying to set user-early, perm-early etc. here might be useless because file system entry is eventually available only past pty creation */ /* name not yet known; umask should not be handled with this function! */ /* umask does not affect resulting mode, on Linux 2.4 */ applyopts_named("", opts, PH_EARLY); /* umask! */ #if defined(HAVE_DEV_PTMX) || defined(HAVE_DEV_PTC) retropt_bool(opts, OPT_PTMX, &useptmx); #endif #if HAVE_OPENPTY retropt_bool(opts, OPT_OPENPTY, &useopenpty); #endif #if (defined(HAVE_DEV_PTMX) || defined(HAVE_DEV_PTC)) # if HAVE_OPENPTY useopenpty = !useptmx; # else /* !HAVE_OPENPTY */ useptmx = true; # endif /* !HAVE_OPENPTY */ #else # if HAVE_OPENPTY useopenpty = true; # endif /* HAVE_OPENPTY */ #endif /* ! (defined(HAVE_DEV_PTMX) || defined(HAVE_DEV_PTC)) */ #if HAVE_POLL retropt_bool(opts, OPT_PTY_WAIT_SLAVE, &wait_slave); retropt_timespec(opts, OPT_PTY_INTERVALL, &pollintv); #endif /* HAVE_POLL */ if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1; applyopts2(-1, opts, PH_INIT, PH_EARLY); applyopts(-1, opts, PH_PREBIGEN); #if defined(HAVE_DEV_PTMX) # define PTMX "/dev/ptmx" /* Linux */ #elif HAVE_DEV_PTC # define PTMX "/dev/ptc" /* AIX 4.3.3 */ #endif #if HAVE_DEV_PTMX || HAVE_DEV_PTC if (useptmx) { if ((ptyfd = Open(PTMX, O_RDWR|O_NOCTTY, 0620)) < 0) { Warn1("open(\""PTMX"\", O_RDWR|O_NOCTTY, 0620): %s", strerror(errno)); /*!*/ } else { ;/*0 Info1("open(\""PTMX"\", O_RDWR|O_NOCTTY, 0620) -> %d", ptyfd);*/ } if (ptyfd >= 0 && ttyfd < 0) { /* we used PTMX before forking */ /*0 extern char *ptsname(int);*/ #if HAVE_GRANTPT /* AIX, not Linux */ if (Grantpt(ptyfd)/*!*/ < 0) { Warn2("grantpt(%d): %s", ptyfd, strerror(errno)); } #endif /* HAVE_GRANTPT */ #if HAVE_UNLOCKPT if (Unlockpt(ptyfd)/*!*/ < 0) { Warn2("unlockpt(%d): %s", ptyfd, strerror(errno)); } #endif /* HAVE_UNLOCKPT */ #if HAVE_PROTOTYPE_LIB_ptsname /* AIX, not Linux */ if ((tn = Ptsname(ptyfd)) == NULL) { Warn2("ptsname(%d): %s", ptyfd, strerror(errno)); } else { Notice1("PTY is %s", tn); } #endif /* HAVE_PROTOTYPE_LIB_ptsname */ if (tn == NULL) { if ((tn = Ttyname(ptyfd)) == NULL) { Warn2("ttyname(%d): %s", ptyfd, strerror(errno)); } } ptyname[0] = '\0'; strncat(ptyname, tn, MAXPTYNAMELEN-1); } } #endif /* HAVE_DEV_PTMX || HAVE_DEV_PTC */ #if HAVE_OPENPTY if (ptyfd < 0) { int result; if ((result = Openpty(&ptyfd, &ttyfd, ptyname, NULL, NULL)) < 0) { Error4("openpty(%p, %p, %p, NULL, NULL): %s", &ptyfd, &ttyfd, ptyname, strerror(errno)); return -1; } Notice1("PTY is %s", ptyname); } #endif /* HAVE_OPENPTY */ if (!retropt_string(opts, OPT_SYMBOLIC_LINK, &linkname)) { if (Unlink(linkname) < 0 && errno != ENOENT) { Error2("unlink(\"%s\"): %s", linkname, strerror(errno)); } if (Symlink(ptyname, linkname) < 0) { Error3("symlink(\"%s\", \"%s\"): %s", ptyname, linkname, strerror(errno)); } if (opt_unlink_close) { if ((xfd->stream.unlink_close = strdup(linkname)) == NULL) { Error1("strdup(\"%s\"): out of memory", linkname); } xfd->stream.opt_unlink_close = true; } } applyopts_named(ptyname, opts, PH_PASTOPEN); applyopts_named(ptyname, opts, PH_FD); applyopts_cloexec(ptyfd, opts);/*!*/ xfd->stream.dtype = XIODATA_PTY; applyopts(ptyfd, opts, PH_FD); { /* special handling of user-late etc.; with standard behaviour (up to 1.7.1.1) they affected /dev/ptmx instead of /dev/pts/N */ uid_t uid = -1, gid = -1; mode_t perm; bool dont; dont = retropt_uid(opts, OPT_USER_LATE, &uid); dont &= retropt_gid(opts, OPT_GROUP_LATE, &gid); if (!dont) { if (Chown(ptyname, uid, gid) < 0) { Error4("chown(\"%s\", %d, %d): %s", ptyname, uid, gid, strerror(errno)); } } if (retropt_mode(opts, OPT_PERM_LATE, &perm) == 0) { if (Chmod(ptyname, perm) < 0) { Error3("chmod(\"%s\", %03o): %s", ptyname, perm, strerror(errno)); } } } xfd->stream.fd = ptyfd; applyopts(ptyfd, opts, PH_LATE); if (applyopts_single(&xfd->stream, opts, PH_LATE) < 0) return -1; #if HAVE_POLL /* if you can and wish: */ if (wait_slave) { /* try to wait until someone opens the slave side of the pty */ /* we want to get a HUP (hangup) condition on the pty */ #if HAVE_DEV_PTMX || HAVE_DEV_PTC if (useptmx) { ttyfd = Open(tn, O_RDWR|O_NOCTTY, 0620); Close(ttyfd); } #endif #if HAVE_OPENPTY if (useopenpty) { Close(ttyfd); } #endif /* HAVE_OPENPTY */ /* now we poll until the HUP vanishes - this indicates a slave conn. */ while (true) { struct pollfd ufd; ufd.fd = ptyfd; ufd.events = (POLLHUP); if (Poll(&ufd, 1, 0) < 0) { Error3("poll({%d, 0x%04hu,}, 1, 0): %s", ufd.fd, ufd.events, strerror(errno)); /*! close something */ return -1; } if (!(ufd.revents & POLLHUP)) { break; } Nanosleep(&pollintv, NULL); continue; } } #endif /* HAVE_POLL */ return STAT_OK; } #endif /* WITH_PTY */ socat-1.7.3.1/xio-ascii.c0000644000201000020100000001114412455415361014620 0ustar gerhardgerhard/* source: xio-ascii.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains functions for text encoding, decoding, and conversions */ #include #include #include #include "xio-ascii.h" /* for each 6 bit pattern we have an ASCII character in the arry */ const static int base64chars[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', } ; #define CHAR64(c) (base64chars[c]) char * xiob64encodeline(const char *data, /* input data */ size_t bytes, /* length of input data, >=0 */ char *coded /* output buffer, must be long enough */ ) { int c1, c2, c3; while (bytes > 0) { c1 = *data++; *coded++ = CHAR64(c1>>2); if (--bytes == 0) { *coded++ = CHAR64((c1&0x03)<<4); *coded++ = '='; *coded++ = '='; } else { c2 = *data++; *coded++ = CHAR64(((c1&0x03)<<4)|(c2>>4)); if (--bytes == 0) { *coded++ = CHAR64((c2&0x0f)<<2); *coded++ = '='; } else { c3 = *data++; --bytes; *coded++ = CHAR64(((c2&0x0f)<<2)|(c3>>6)); *coded++ = CHAR64(c3&0x3f); } } } return coded; } /* sanitize "untrusted" text, replacing special control characters with the C string version ("\x"), and replacing unprintable chars with ".". text can grow to double size, so keep output buffer long enough! returns a pointer to the first untouched byte of the output buffer. */ char *xiosanitize(const char *data, /* input data */ size_t bytes, /* length of input data, >=0 */ char *coded /* output buffer, must be long enough */ ) { int c; while (bytes > 0) { c = *(unsigned char *)data++; switch (c) { case '\0' : *coded++ = '\\'; *coded++ = '0'; break; case '\a' : *coded++ = '\\'; *coded++ = 'a'; break; case '\b' : *coded++ = '\\'; *coded++ = 'b'; break; case '\t' : *coded++ = '\\'; *coded++ = 't'; break; case '\n' : *coded++ = '\\'; *coded++ = 'n'; break; case '\v' : *coded++ = '\\'; *coded++ = 'v'; break; case '\f' : *coded++ = '\\'; *coded++ = 'f'; break; case '\r' : *coded++ = '\\'; *coded++ = 'r'; break; case '\'' : *coded++ = '\\'; *coded++ = '\''; break; case '\"' : *coded++ = '\\'; *coded++ = '"'; break; case '\\' : *coded++ = '\\'; *coded++ = '\\'; break; default: if (!isprint(c)) c = '.'; *coded++ = c; break; } --bytes; } return coded; } /* print the bytes in hex */ char * xiohexdump(const unsigned char *data, size_t bytes, char *coded) { int space = 0; while (bytes-- > 0) { if (space) { *coded++ = ' '; } coded += sprintf(coded, "%02x", *data++); space = 1; } return coded; } /* write the binary data to output buffer codbuff in human readable form. bytes gives the length of the data, codlen the available space in codbuff. coding specifies how the data is to be presented. Not much to select now. returns a pointer to the first char in codbuff that has not been overwritten; it might also point to the first char after the buffer! this function does not write a terminating \0 */ static char * _xiodump(const unsigned char *data, size_t bytes, char *codbuff, size_t codlen, int coding) { int start = 1; int space = coding & 0xff; if (bytes <= 0) { return codbuff; } if (codlen < 1) { return codbuff; } if (space == 0) space = -1; if (0) { ; /* for canonical reasons */ } else if (1) { /* simple hexadecimal output */ if (3*bytes+1 > codlen) { bytes = (codlen-1)/3; /* "truncate" data so generated text fits */ } *codbuff++ = 'x'; while (bytes-- > 0) { if (start == 0 && space == 0) { *codbuff++ = ' '; space = (coding & 0xff); } codbuff += sprintf(codbuff, "%02x", *data++); start = 0; } } return codbuff; } /* write the binary data to codbuff in human readable form. bytes gives the length of the data, codlen the available space in codbuff. coding specifies how the data is to be presented. Not much to select now. null terminates the output. returns a pointer to the output string. */ char * xiodump(const unsigned char *data, size_t bytes, char *codbuff, size_t codlen, int coding) { char *result; result = _xiodump(data, bytes, codbuff, codlen-1, coding); *result = '\0'; return codbuff; } socat-1.7.3.1/xioread.c0000644000201000020100000002714712161506654014400 0ustar gerhardgerhard/* source: xioread.c */ /* Copyright Gerhard Rieger 2001-2010 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source of the extended read function */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-termios.h" #include "xio-socket.h" #include "xio-readline.h" #include "xio-openssl.h" /* xioread() performs read() or recvfrom() If result is < 0, errno is valid */ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) { ssize_t bytes; #if WITH_IP6 && 0 int nexthead; #endif struct single *pipe; int _errno; if (file->tag == XIO_TAG_INVALID) { Error1("xioread(): invalid xiofile descriptor %p", file); errno = EINVAL; return -1; } if (file->tag == XIO_TAG_DUAL) { pipe = file->dual.stream[0]; if (pipe->tag == XIO_TAG_INVALID) { Error1("xioread(): invalid xiofile sub descriptor %p[0]", file); errno = EINVAL; return -1; } } else { pipe = &file->stream; } if (pipe->readbytes) { if (pipe->actbytes == 0) { return 0; /* EOF by count */ } if (pipe->actbytes < bufsiz) { bufsiz = pipe->actbytes; } } switch (pipe->dtype & XIODATA_READMASK) { case XIOREAD_STREAM: do { bytes = Read(pipe->fd, buff, bufsiz); } while (bytes < 0 && errno == EINTR); if (bytes < 0) { _errno = errno; switch (_errno) { #if 1 case EPIPE: case ECONNRESET: Warn4("read(%d, %p, "F_Zu"): %s", pipe->fd, buff, bufsiz, strerror(_errno)); break; #endif default: Error4("read(%d, %p, "F_Zu"): %s", pipe->fd, buff, bufsiz, strerror(_errno)); } errno = _errno; return -1; } break; case XIOREAD_PTY: do { bytes = Read(pipe->fd, buff, bufsiz); } while (bytes < 0 && errno == EINTR); if (bytes < 0) { _errno = errno; if (_errno == EIO) { Notice4("read(%d, %p, "F_Zu"): %s (probably PTY closed)", pipe->fd, buff, bufsiz, strerror(_errno)); return 0; } else { Error4("read(%d, %p, "F_Zu"): %s", pipe->fd, buff, bufsiz, strerror(_errno)); } errno = _errno; return -1; } break; #if WITH_READLINE case XIOREAD_READLINE: if ((bytes = xioread_readline(pipe, buff, bufsiz)) < 0) { return -1; } break; #endif /* WITH_READLINE */ #if WITH_OPENSSL case XIOREAD_OPENSSL: /* this function prints its error messages */ if ((bytes = xioread_openssl(pipe, buff, bufsiz)) < 0) { return -1; } break; #endif /* WITH_OPENSSL */ #if _WITH_SOCKET case XIOREAD_RECV: if (pipe->dtype & XIOREAD_RECV_FROM) { #if WITH_RAWIP || WITH_UDP || WITH_UNIX struct msghdr msgh = {0}; union sockaddr_union from = {{0}}; socklen_t fromlen = sizeof(from); char infobuff[256]; char ctrlbuff[1024]; /* ancillary messages */ msgh.msg_name = &from; msgh.msg_namelen = fromlen; #if HAVE_STRUCT_MSGHDR_MSGCONTROL msgh.msg_control = ctrlbuff; #endif #if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN msgh.msg_controllen = sizeof(ctrlbuff); #endif if (xiogetpacketsrc(pipe->fd, &msgh) < 0) { return -1; } do { bytes = Recvfrom(pipe->fd, buff, bufsiz, 0, &from.soa, &fromlen); } while (bytes < 0 && errno == EINTR); if (bytes < 0) { char infobuff[256]; _errno = errno; Error6("recvfrom(%d, %p, "F_Zu", 0, %s, {"F_socklen"}): %s", pipe->fd, buff, bufsiz, sockaddr_info(&from.soa, fromlen, infobuff, sizeof(infobuff)), fromlen, strerror(errno)); errno = _errno; return -1; } /* on packet type we also receive outgoing packets, this is not desired */ #if defined(PF_PACKET) && defined(PACKET_OUTGOING) if (from.soa.sa_family == PF_PACKET) { if ((from.ll.sll_pkttype & PACKET_OUTGOING) == 0) { errno = EAGAIN; return -1; } } #endif /* defined(PF_PACKET) && defined(PACKET_OUTGOING) */ Notice2("received packet with "F_Zu" bytes from %s", bytes, sockaddr_info(&from.soa, fromlen, infobuff, sizeof(infobuff))); if (bytes == 0) { if (!pipe->para.socket.null_eof) { errno = EAGAIN; return -1; } return bytes; } if (pipe->peersa.soa.sa_family != PF_UNSPEC) { /* a peer address is registered, so we need to check if it matches */ #if 0 /* with UNIX sockets we find inconsistent lengths */ if (fromlen != pipe->salen) { Info("recvfrom(): wrong peer address length, ignoring packet"); errno = EAGAIN; return -1; } #endif if (pipe->dtype & XIOREAD_RECV_SKIPIP) { if (pipe->peersa.soa.sa_family != from.soa.sa_family) { Info("recvfrom(): wrong peer protocol, ignoring packet"); errno = EAGAIN; return -1; } #if WITH_IP4 switch (pipe->peersa.soa.sa_family) { case PF_INET: if (pipe->peersa.ip4.sin_addr.s_addr != from.ip4.sin_addr.s_addr) { Info("recvfrom(): wrong peer address, ignoring packet"); errno = EAGAIN; return -1; } break; } #endif /* WITH_IP4 */ } else { switch (pipe->peersa.soa.sa_family) { #if 0 case PF_UNIX: if (strncmp(pipe->peersa.un.sun_path, from.un.sun_path, sizeof(from.un.sun_path))) { Info("recvfrom(): wrong peer address, ignoring packet"); errno = EAGAIN; return -1; } break; #endif #if WITH_IP6 case PF_INET6: /* e.g. Solaris recvfrom sets a __sin6_src_id component */ if (memcmp(&from.ip6.sin6_addr, &pipe->peersa.ip6.sin6_addr, sizeof(from.ip6.sin6_addr)) || from.ip6.sin6_port != pipe->peersa.ip6.sin6_port) { Info("recvfrom(): wrong peer address, ignoring packet"); errno = EAGAIN; return -1; } break; #endif /* WITH_IP6 */ default: if (memcmp(&from, &pipe->peersa, fromlen)) { Info("recvfrom(): wrong peer address, ignoring packet"); errno = EAGAIN; return -1; } } } } switch(from.soa.sa_family) { int headlen; #if WITH_IP4 case AF_INET: if (pipe->dtype & XIOREAD_RECV_SKIPIP) { /* IP4 raw sockets include the header when passing a packet to the application - we don't need it here. */ #if HAVE_STRUCT_IP_IP_HL headlen = 4*((struct ip *)buff)->ip_hl; #else /* happened on Tru64 */ headlen = 4*((struct ip *)buff)->ip_vhl; #endif if (headlen > bytes) { Warn1("xioread(%d, ...)/IP4: short packet", pipe->fd); bytes = 0; } else { memmove(buff, ((char *)buff)+headlen, bytes-headlen); bytes -= headlen; } } break; #endif #if WITH_IP6 case AF_INET6: /* does not seem to include header on Linux */ /* but sometimes on AIX */ break; #endif default: /* do nothing, for now */ break; } if (pipe->dtype & XIOREAD_RECV_ONESHOT) { #if 1 pipe->eof = 2; #else Shutdown(pipe->fd, SHUT_RD); #endif if (pipe->ppid > 0) { Kill(pipe->ppid, SIGUSR1); } } #if 0 if (fromlen != pipe->fd[0].salen) { Debug("recvfrom(): wrong peer address length, ignoring packet"); continue; } if (memcmp(&from, &pipe->fd[0].peersa.sa, fromlen)) { Debug("recvfrom(): other peer address, ignoring packet"); Debug16("peer: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", pipe->fd[0].peersa.space[0], pipe->fd[0].peersa.space[1], pipe->fd[0].peersa.space[2], pipe->fd[0].peersa.space[3], pipe->fd[0].peersa.space[4], pipe->fd[0].peersa.space[5], pipe->fd[0].peersa.space[6], pipe->fd[0].peersa.space[7], pipe->fd[0].peersa.space[8], pipe->fd[0].peersa.space[9], pipe->fd[0].peersa.space[10], pipe->fd[0].peersa.space[11], pipe->fd[0].peersa.space[12], pipe->fd[0].peersa.space[13], pipe->fd[0].peersa.space[14], pipe->fd[0].peersa.space[15]); Debug16("from: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", from.space[0], from.space[1], from.space[2], from.space[3], from.space[4], from.space[5], from.space[6], from.space[7], from.space[8], from.space[9], from.space[10], from.space[11], from.space[12], from.space[13], from.space[14], from.space[15]); continue; } #endif #else /* !WITH_RAWIP */ Fatal("address requires raw sockets, but they are not compiled in"); return -1; #endif /* !WITH_RAWIP || WITH_UDP || WITH_UNIX */ } else /* ~XIOREAD_RECV_FROM */ { union sockaddr_union from; socklen_t fromlen = sizeof(from); char infobuff[256]; struct msghdr msgh = {0}; char ctrlbuff[1024]; /* ancillary messages */ socket_init(pipe->para.socket.la.soa.sa_family, &from); /* get source address */ msgh.msg_name = &from; msgh.msg_namelen = fromlen; #if HAVE_STRUCT_MSGHDR_MSGCONTROL msgh.msg_control = ctrlbuff; #endif #if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN msgh.msg_controllen = sizeof(ctrlbuff); #endif if (xiogetpacketsrc(pipe->fd, &msgh) < 0) { return -1; } xiodopacketinfo(&msgh, true, false); if (xiocheckpeer(pipe, &from, &pipe->para.socket.la) < 0) { Recvfrom(pipe->fd, buff, bufsiz, 0, &from.soa, &fromlen); /* drop */ errno = EAGAIN; return -1; } Info1("permitting packet from %s", sockaddr_info((struct sockaddr *)&from, fromlen, infobuff, sizeof(infobuff))); do { bytes = Recvfrom(pipe->fd, buff, bufsiz, 0, &from.soa, &fromlen); } while (bytes < 0 && errno == EINTR); if (bytes < 0) { char infobuff[256]; _errno = errno; Error6("recvfrom(%d, %p, "F_Zu", 0, %s, "F_socklen"): %s", pipe->fd, buff, bufsiz, sockaddr_info(&from.soa, fromlen, infobuff, sizeof(infobuff)), fromlen, strerror(errno)); errno = _errno; return -1; } Notice2("received packet with "F_Zu" bytes from %s", bytes, sockaddr_info(&from.soa, fromlen, infobuff, sizeof(infobuff))); if (bytes == 0) { if (!pipe->para.socket.null_eof) { errno = EAGAIN; return -1; } return bytes; } switch(from.soa.sa_family) { int headlen; #if WITH_IP4 case AF_INET: if (pipe->dtype & XIOREAD_RECV_SKIPIP) { /* IP4 raw sockets include the header when passing a packet to the application - we don't need it here. */ #if HAVE_STRUCT_IP_IP_HL headlen = 4*((struct ip *)buff)->ip_hl; #else /* happened on Tru64 */ headlen = 4*((struct ip *)buff)->ip_vhl; #endif if (headlen > bytes) { Warn1("xioread(%d, ...)/IP4: short packet", pipe->fd); bytes = 0; } else { memmove(buff, ((char *)buff)+headlen, bytes-headlen); bytes -= headlen; } } break; #endif #if WITH_IP6 case AF_INET6: /* does not seem to include header... */ break; #endif default: /* do nothing, for now */ break; } } break; #endif /* _WITH_SOCKET */ default: Error("internal: undefined read operation"); errno = EINVAL; return -1; } pipe->actbytes -= bytes; return bytes; } /* this function is intended only for some special address types where the select()/poll() calls cannot strictly determine if (more) read data is available. currently this is for the OpenSSL based addresses. */ ssize_t xiopending(xiofile_t *file) { struct single *pipe; if (file->tag == XIO_TAG_INVALID) { Error1("xiopending(): invalid xiofile descriptor %p", file); errno = EINVAL; return -1; } if (file->tag == XIO_TAG_DUAL) { pipe = file->dual.stream[0]; if (pipe->tag == XIO_TAG_INVALID) { Error1("xiopending(): invalid xiofile sub descriptor %p[0]", file); errno = EINVAL; return -1; } } else { pipe = &file->stream; } switch (pipe->dtype & XIODATA_READMASK) { #if WITH_OPENSSL case XIOREAD_OPENSSL: return xiopending_openssl(pipe); #endif /* WITH_OPENSSL */ default: return 0; } } socat-1.7.3.1/snprinterr.h0000644000201000020100000000046512460670272015152 0ustar gerhardgerhard/* source: snprinterr.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __snprinterr_h_included #define __snprinterr_h_included 1 int snprinterr(char *str, size_t size, const char *format); #endif /* !defined(__snprinterr_h_included) */ socat-1.7.3.1/xioopts.h0000644000201000020100000007367512460670272014466 0ustar gerhardgerhard/* source: xioopts.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xioopts_h_included #define __xioopts_h_included 1 #define ODESC_END ((void *)0) /* indicates end of actual option array */ #define ODESC_DONE ((void *)-1) /* indicates that option has been applied */ #define ODESC_ERROR ODESC_DONE /* maybe later */ #define XIO_OFFSETOF(x) ((size_t)&((xiosingle_t *)0)->x) #define XIO_SIZEOF(x) (sizeof(((struct single *)0)->x)) /* atomic structure for use in the option search table; keep compatible with struct wordent! */ struct optname { const char *name; const struct optdesc *desc; } ; /* keep consistent with xiohelp.c:optiontypenames[] ! */ enum e_types { TYPE_CONST, /* keyword means a fix value - implies int type */ TYPE_BIN, /* raw binary data, length determined by data */ TYPE_BOOL, /* value is 0 or 1 (no-value is interpreted as 1) */ TYPE_BYTE, /* unsigned char */ TYPE_INT, /* int */ TYPE_LONG, /* long */ TYPE_STRING, /* char * */ TYPE_NAME = TYPE_STRING, TYPE_FILENAME = TYPE_STRING, TYPE_PTRDIFF, /* ptrdiff_t */ TYPE_SHORT, /* short */ TYPE_SIZE_T, /* size_t */ TYPE_SOCKADDR, /* struct sockaddr * */ TYPE_UINT, /* unsigned int */ TYPE_ULONG, /* unsigned long */ TYPE_USHORT, /* unsigned short */ TYPE_2BYTE = TYPE_USHORT, TYPE_MODET, /* representation of mode_t */ TYPE_GIDT, /* representation of gid_t */ TYPE_UIDT, /* representation of uid_t */ /*TYPE_FLAG,*/ TYPE_INT3, /* int[3] */ TYPE_TIMEVAL, /* struct timeval: {long;long;}, seconds and microsec. */ TYPE_TIMESPEC, /* struct timespec: {time_t;long;}, seconds and nanosec. */ TYPE_DOUBLE, /* double */ TYPE_STRING_NULL, /* char *; string or NULL */ TYPE_LONGLONG, /* long long */ TYPE_OFF32, /* off_t */ TYPE_OFF64, /* off64_t */ TYPE_INT_INT, /* 2 parameters: first is int, second is int */ TYPE_INT_INTP, /* 2 parameters: first is int, second is int* */ TYPE_INT_BIN, /* 2 parameters: first is int, second is binary */ TYPE_INT_STRING, /* 2 parameters: first is int, second is req string */ TYPE_INT_INT_INT, /* 3 params: first and second are int, 3rd is int */ TYPE_INT_INT_BIN, /* 3 params: first and second are int, 3rd is binary */ TYPE_INT_INT_STRING, /* 3 params: first and second are int, 3rd is string */ TYPE_IP4NAME, /* IPv4 hostname or address */ #if HAVE_STRUCT_LINGER TYPE_LINGER, /* struct linger */ #endif /* HAVE_STRUCT_LINGER */ #if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IP_MREQN TYPE_IP_MREQN, /* for struct ip_mreq or struct ip_mreqn */ #endif } ; enum e_func { OFUNC_NONE, /* no function - should not occur */ OFUNC_FLAG, /* no function, but bitposition, only with bool; arg1 is mask */ OFUNC_FLAG_PATTERN, /* no function, but bitpattern: arg1 is pattern, arg2 is mask */ OFUNC_SEEK32, /* lseek(): arg1 is whence (SEEK_SET etc.) */ OFUNC_SEEK64, /* lseek64(): arg1 is whence (SEEK_SET etc.) */ OFUNC_FCNTL, /* fcntl(, ): arg1 is cmd */ OFUNC_IOCTL, /* ioctl(): arg1 of option description is request, arg2 is int setrequest */ OFUNC_IOCTL_MASK_LONG, /* arg1 is getrequest, arg2 is setrequest: ioctl(arg1, ); |= arg3; ioctl(arg2, ); */ OFUNC_IOCTL_GENERIC, /* generic ioctl() (request on cmdline) */ OFUNC_SOCKOPT, /* setsockopt() */ OFUNC_SOCKOPT_APPEND,/* getsockopt(), append data, setsockopt() */ OFUNC_SOCKOPT_GENERIC,/* generic setsockopt() (level, optname on cmdline) */ OFUNC_FLOCK, /* flock() */ OFUNC_TERMIO, /* termio() ? */ OFUNC_SPEC, /* special, i.e. no generalizable function call */ OFUNC_OFFSET, /* put a value into xiofile struct; major is offset */ OFUNC_OFFSET_MASKS, /* !!! */ /*OFUNC_APPL,*/ /* special, i.e. application must know which f. */ OFUNC_EXT, /* with extended file descriptors only */ OFUNC_TERMIOS_FLAG, /* a flag in struct termios: major..tcflag, minor..bit */ OFUNC_TERMIOS_PATTERN, /* a multibit: major..tcflag, minor..pattern, arg3..mask */ OFUNC_TERMIOS_VALUE, /* a variable value: major..tcflag, minor..mask, arg3..shift */ OFUNC_TERMIOS_CHAR, /* a termios functional character: major..c_cc index */ OFUNC_TERMIOS_SPEED, /* termios c_ispeed etc on FreeBSD */ OFUNC_TERMIOS_SPEC, /* termios combined modes */ OFUNC_SIGNAL, /* a signal that should be passed to child process */ OFUNC_RESOLVER, /* a bit position used on _res.options */ OFUNC_IFFLAG, /* interface flag: locical-or a 1bit mask */ # define ENABLE_OFUNC # include "xio-streams.h" /* push a POSIX STREAMS module */ # undef ENABLE_OFUNC } ; /* for simpler handling of option-to-connection-type relations we define groups. to keep the search for options simple, we allow each option to belong to at most one group only. (we have a dummy GROUP_NONE for those that don't want to belong to any...) The caller of parseopts() specifies per bitpatter a set of groups where it accepts options from. */ /*- the group bits are: - 000ooooo 00000000 000000uf 0000ssss - ooooo: more detailed description to ssss (e.g., socket family) - ssss: the type of stream, as in stat.h: S_IF... - f: has a named entry in the file system - u: has user and group */ /* keep consistent with xiohelp.c:addressgroupnames[] ! */ /* a dummy group */ #define GROUP_NONE 0x00000000 #define GROUP_FD 0x00000001 /* everything applyable to a fd */ #define GROUP_FIFO 0x00000002 #define GROUP_CHR 0x00000004 #define GROUP_BLK 0x00000008 #define GROUP_REG 0x00000010 #define GROUP_FILE GROUP_REG #define GROUP_SOCKET 0x00000020 #define GROUP_READLINE 0x00000040 #define GROUP_NAMED 0x00000100 /* file system entry */ #define GROUP_OPEN 0x00000200 /* flags for open() */ #define GROUP_EXEC 0x00000400 /* program or script execution */ #define GROUP_FORK 0x00000800 /* communication with forked process */ #define GROUP_LISTEN 0x00001000 /* socket in listening mode */ /* 0x00002000 */ #define GROUP_CHILD 0x00004000 /* autonom child process */ #define GROUP_RETRY 0x00008000 /* when open/connect etc. fails */ #define GROUP_TERMIOS 0x00010000 #define GROUP_RANGE 0x00020000 /* differs from GROUP_LISTEN */ #define GROUP_PTY 0x00040000 /* address pty or exec...,pty */ #define GROUP_PARENT 0x00080000 /* for parent of communicating child */ #define GROUP_SOCK_UNIX 0x00100000 #define GROUP_SOCK_IP4 0x00200000 #define GROUP_SOCK_IP6 0x00400000 #define GROUP_SOCK_IP (GROUP_SOCK_IP4|GROUP_SOCK_IP6) #define GROUP_INTERFACE 0x00800000 #define GROUP_TUN GROUP_INTERFACE #define GROUP_IP_UDP 0x01000000 #define GROUP_IP_TCP 0x02000000 #define GROUP_IPAPP (GROUP_IP_UDP|GROUP_IP_TCP|GROUP_IP_SCTP) /* true: indicates one of UDP, TCP, SCTP */ #define GROUP_IP_SOCKS4 0x04000000 #define GROUP_OPENSSL 0x08000000 #define GROUP_PROCESS 0x10000000 /* a process related option */ #define GROUP_APPL 0x20000000 /* option handled by data loop */ #define GROUP_HTTP 0x40000000 /* any HTTP client */ #define GROUP_IP_SCTP 0x80000000 #define GROUP_ANY (GROUP_PROCESS|GROUP_APPL) #define GROUP_ALL 0xffffffff /* no IP multicasts, no error queue yet */ /* the only reason for keeping this enum sorted is to help detecting name conflicts. */ /* optcode's */ enum e_optcode { OPT_ADDRESS_FAMILY = 1, /* these are not alphabetically, I know... */ OPT_B0, /* termios.c_cflag */ OPT_B50, /* termios.c_cflag */ OPT_B75, /* termios.c_cflag */ OPT_B110, /* termios.c_cflag */ OPT_B134, /* termios.c_cflag */ OPT_B150, /* termios.c_cflag */ OPT_B200, /* termios.c_cflag */ OPT_B300, /* termios.c_cflag */ OPT_B600, /* termios.c_cflag */ OPT_B900, /* termios.c_cflag - HP-UX */ OPT_B1200, /* termios.c_cflag */ OPT_B1800, /* termios.c_cflag */ OPT_B2400, /* termios.c_cflag */ OPT_B3600, /* termios.c_cflag - HP-UX */ OPT_B4800, /* termios.c_cflag */ OPT_B7200, /* termios.c_cflag - HP-UX */ OPT_B9600, /* termios.c_cflag */ OPT_B19200, /* termios.c_cflag */ OPT_B38400, /* termios.c_cflag */ OPT_B57600, /* termios.c_cflag */ OPT_B115200, /* termios.c_cflag */ OPT_B230400, /* termios.c_cflag */ OPT_B460800, /* termios.c_cflag */ OPT_B500000, /* termios.c_cflag */ OPT_B576000, /* termios.c_cflag */ OPT_B921600, /* termios.c_cflag */ OPT_B1000000, /* termios.c_cflag */ OPT_B1152000, /* termios.c_cflag */ OPT_B1500000, /* termios.c_cflag */ OPT_B2000000, /* termios.c_cflag */ OPT_B2500000, /* termios.c_cflag */ OPT_B3000000, /* termios.c_cflag */ OPT_B3500000, /* termios.c_cflag */ OPT_B4000000, /* termios.c_cflag */ OPT_BACKLOG, OPT_BIND, /* a socket address as character string */ OPT_BRKINT, /* termios.c_iflag */ #ifdef BSDLY # ifdef BS0 OPT_BS0, /* termios.c_oflag */ # endif # ifdef BS1 OPT_BS1, /* termios.c_oflag */ # endif OPT_BSDLY, /* termios.c_oflag */ #endif OPT_CHROOT, /* chroot() past file system access */ OPT_CHROOT_EARLY, /* chroot() before file system access */ /*OPT_CIBAUD,*/ /* termios.c_cflag */ OPT_CLOCAL, /* termios.c_cflag */ OPT_CLOEXEC, OPT_CONNECT_TIMEOUT, /* socket connect */ OPT_COOL_WRITE, OPT_CR, /* customized */ #ifdef CR0 OPT_CR0, /* termios.c_oflag */ #endif #ifdef CR1 OPT_CR1, /* termios.c_oflag */ #endif #ifdef CR2 OPT_CR2, /* termios.c_oflag */ #endif #ifdef CR3 OPT_CR3, /* termios.c_oflag */ #endif #ifdef CRDLY OPT_CRDLY, /* termios.c_oflag */ #endif OPT_CREAD, /* termios.c_cflag */ OPT_CRNL, /* customized */ #ifdef CRTSCTS OPT_CRTSCTS, /* termios.c_cflag */ #endif OPT_CS5, /* termios.c_cflag */ OPT_CS6, /* termios.c_cflag */ OPT_CS7, /* termios.c_cflag */ OPT_CS8, /* termios.c_cflag */ OPT_CSIZE, /* termios.c_cflag */ OPT_CSTOPB, /* termios.c_cflag */ OPT_DASH, /* exec() */ OPT_ECHO, /* termios.c_lflag */ OPT_ECHOCTL, /* termios.c_lflag */ OPT_ECHOE, /* termios.c_lflag */ OPT_ECHOK, /* termios.c_lflag */ OPT_ECHOKE, /* termios.c_lflag */ OPT_ECHONL, /* termios.c_lflag */ #ifdef ECHOPRT OPT_ECHOPRT, /* termios.c_lflag */ #endif OPT_END_CLOSE, /* xfd.stream.howtoend = END_CLOSE */ OPT_ESCAPE, OPT_EXT2_SECRM, OPT_EXT2_UNRM, OPT_EXT2_COMPR, OPT_EXT2_SYNC, OPT_EXT2_IMMUTABLE, OPT_EXT2_APPEND, OPT_EXT2_NODUMP, OPT_EXT2_NOATIME, OPT_EXT2_JOURNAL_DATA, OPT_EXT2_NOTAIL, OPT_EXT2_DIRSYNC, OPT_EXT2_TOPDIR, OPT_FDIN, OPT_FDOUT, #ifdef FFDLY # ifdef FF0 OPT_FF0, /* termios.c_oflag */ # endif # ifdef FF1 OPT_FF1, /* termios.c_oflag */ # endif OPT_FFDLY, /* termios.c_oflag */ #endif #ifdef FIOSETOWN OPT_FIOSETOWN, /* asm/sockios.h */ #endif OPT_FLOCK_EX, /* flock(fd, LOCK_EX) */ OPT_FLOCK_EX_NB, /* flock(fd, LOCK_EX|LOCK_NB) */ OPT_FLOCK_SH, /* flock(fd, LOCK_SH) */ OPT_FLOCK_SH_NB, /* flock(fd, LOCK_SH|LOCK_NB) */ OPT_FLUSHO, /* termios.c_lflag */ /*0 OPT_FORCE,*/ OPT_FOREVER, OPT_FORK, OPT_FTRUNCATE32, /* ftruncate() */ OPT_FTRUNCATE64, /* ftruncate64() */ OPT_F_SETLKW_RD, /* fcntl with struct flock - read-lock, wait */ OPT_F_SETLKW_WR, /* fcntl with struct flock - write-lock, wait */ OPT_F_SETLK_RD, /* fcntl with struct flock - read-lock */ OPT_F_SETLK_WR, /* fcntl with struct flock - write-lock */ OPT_GROUP, OPT_GROUP_EARLY, OPT_GROUP_LATE, OPT_HISTORY_FILE, /* readline history file */ OPT_HUPCL, /* termios.c_cflag */ OPT_ICANON, /* termios.c_lflag */ OPT_ICRNL, /* termios.c_iflag */ OPT_IEXTEN, /* termios.c_lflag */ OPT_IFF_ALLMULTI, /* struct ifreq.ifr_flags */ OPT_IFF_AUTOMEDIA, /* struct ifreq.ifr_flags */ OPT_IFF_BROADCAST, /* struct ifreq.ifr_flags */ OPT_IFF_DEBUG, /* struct ifreq.ifr_flags */ /*OPT_IFF_DYNAMIC,*/ /* struct ifreq.ifr_flags */ OPT_IFF_LOOPBACK, /* struct ifreq.ifr_flags */ OPT_IFF_MASTER, /* struct ifreq.ifr_flags */ OPT_IFF_MULTICAST, /* struct ifreq.ifr_flags */ OPT_IFF_NOARP, /* struct ifreq.ifr_flags */ OPT_IFF_NOTRAILERS, /* struct ifreq.ifr_flags */ OPT_IFF_NO_PI, /* tun: IFF_NO_PI */ OPT_IFF_PORTSEL, /* struct ifreq.ifr_flags */ OPT_IFF_POINTOPOINT, /* struct ifreq.ifr_flags */ OPT_IFF_PROMISC, /* struct ifreq.ifr_flags */ OPT_IFF_RUNNING, /* struct ifreq.ifr_flags */ OPT_IFF_SLAVE, /* struct ifreq.ifr_flags */ OPT_IFF_UP, /* struct ifreq.ifr_flags */ OPT_IGNBRK, /* termios.c_iflag */ OPT_IGNCR, /* termios.c_iflag */ OPT_IGNORECR, /* HTTP */ OPT_IGNOREEOF, /* customized */ OPT_IGNPAR, /* termios.c_iflag */ OPT_IMAXBEL, /* termios.c_iflag */ OPT_INLCR, /* termios.c_iflag */ OPT_INPCK, /* termios.c_iflag */ OPT_INTERVALL, OPT_IPV6_AUTHHDR, OPT_IPV6_DSTOPTS, OPT_IPV6_FLOWINFO, OPT_IPV6_HOPLIMIT, OPT_IPV6_HOPOPTS, OPT_IPV6_JOIN_GROUP, OPT_IPV6_PKTINFO, OPT_IPV6_RECVDSTOPTS, OPT_IPV6_RECVERR, OPT_IPV6_RECVHOPLIMIT, OPT_IPV6_RECVHOPOPTS, OPT_IPV6_RECVPATHMTU, OPT_IPV6_RECVPKTINFO, OPT_IPV6_RECVRTHDR, OPT_IPV6_RECVTCLASS, OPT_IPV6_RTHDR, OPT_IPV6_TCLASS, OPT_IPV6_UNICAST_HOPS, OPT_IPV6_V6ONLY, #if 0 /* see Linux: man 7 netlink; probably not what we need yet */ OPT_IO_SIOCGIFNAME, #endif OPT_IOCTL_BIN, /* generic ioctl with binary value (pointed to) */ OPT_IOCTL_INT, /* generic ioctl with integer value */ OPT_IOCTL_INTP, /* generic ioctl with integer value (pointed to) */ OPT_IOCTL_STRING, /* generic ioctl with integer value (pointed to) */ OPT_IOCTL_VOID, /* generic ioctl without value */ OPT_IP_ADD_MEMBERSHIP, #ifdef IP_HDRINCL OPT_IP_HDRINCL, #endif #ifdef IP_FREEBIND OPT_IP_FREEBIND, #endif #ifdef IP_MTU OPT_IP_MTU, #endif #ifdef IP_MTU_DISCOVER OPT_IP_MTU_DISCOVER, #endif OPT_IP_MULTICAST_IF, OPT_IP_MULTICAST_LOOP, OPT_IP_MULTICAST_TTL, OPT_IP_OPTIONS, #ifdef IP_PKTINFO OPT_IP_PKTINFO, #endif #ifdef IP_PKTOPTIONS OPT_IP_PKTOPTIONS, #endif OPT_IP_RECVDSTADDR, #ifdef IP_RECVERR OPT_IP_RECVERR, #endif OPT_IP_RECVIF, #ifdef IP_RECVOPTS OPT_IP_RECVOPTS, #endif #ifdef IP_RECVTOS OPT_IP_RECVTOS, #endif #ifdef IP_RECVTTL OPT_IP_RECVTTL, #endif #ifdef IP_RETOPTS OPT_IP_RETOPTS, #endif #ifdef IP_ROUTER_ALERT OPT_IP_ROUTER_ALERT, #endif OPT_IP_TOS, OPT_IP_TTL, OPT_ISIG, /* termios.c_lflag */ OPT_ISPEED, /* termios.c_ispeed */ OPT_ISTRIP, /* termios.c_iflag */ #ifdef IUCLC OPT_IUCLC, /* termios.c_iflag */ #endif OPT_IXANY, /* termios.c_iflag */ OPT_IXOFF, /* termios.c_iflag */ OPT_IXON, /* termios.c_iflag */ OPT_LOCKFILE, OPT_LOWPORT, OPT_MAX_CHILDREN, #ifdef NLDLY # ifdef NL0 OPT_NL0, /* termios.c_oflag */ # endif # ifdef NL0 OPT_NL1, /* termios.c_oflag */ # endif OPT_NLDLY, /* termios.c_oflag */ #endif OPT_NOECHO, /* readline */ OPT_NOFLSH, /* termios.c_lflag */ OPT_NOFORK, /* exec, system */ OPT_NOPROMPT, /* readline */ OPT_NULL_EOF, /* receiving empty packet triggers EOF */ #ifdef OCRNL OPT_OCRNL, /* termios.c_oflag */ #endif #ifdef OFDEL OPT_OFDEL, /* termios.c_oflag */ #endif #ifdef OFILL OPT_OFILL, /* termios.c_oflag */ #endif #ifdef OLCUC OPT_OLCUC, /* termios.c_oflag */ #endif OPT_ONLCR, /* termios.c_oflag */ #ifdef ONLRET OPT_ONLRET, /* termios.c_oflag */ #endif #ifdef ONOCR OPT_ONOCR, /* termios.c_oflag */ #endif #if HAVE_OPENPTY OPT_OPENPTY, #endif OPT_OPENSSL_CAFILE, OPT_OPENSSL_CAPATH, OPT_OPENSSL_CERTIFICATE, OPT_OPENSSL_CIPHERLIST, OPT_OPENSSL_COMMONNAME, #if OPENSSL_VERSION_NUMBER >= 0x00908000L OPT_OPENSSL_COMPRESS, #endif OPT_OPENSSL_DHPARAM, OPT_OPENSSL_EGD, OPT_OPENSSL_FIPS, OPT_OPENSSL_KEY, OPT_OPENSSL_METHOD, OPT_OPENSSL_PSEUDO, OPT_OPENSSL_VERIFY, OPT_OPOST, /* termios.c_oflag */ OPT_OSPEED, /* termios.c_ospeed */ OPT_O_APPEND, #ifdef O_ASYNC OPT_O_ASYNC, #endif OPT_O_BINARY, /* Cygwin */ OPT_O_CREATE, #ifdef O_DEFER OPT_O_DEFER, #endif #ifdef O_DELAY OPT_O_DELAY, #endif #ifdef O_DIRECT OPT_O_DIRECT, #endif #ifdef O_DIRECTORY OPT_O_DIRECTORY, #endif #ifdef O_DSYNC OPT_O_DSYNC, #endif OPT_O_EXCL, #ifdef O_LARGEFILE OPT_O_LARGEFILE, #endif #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK) OPT_O_NDELAY, #endif OPT_O_NOATIME, OPT_O_NOCTTY, #ifdef O_NOFOLLOW OPT_O_NOFOLLOW, #endif OPT_O_NOINHERIT, /* Cygwin */ OPT_O_NONBLOCK, #ifdef O_NSHARE OPT_O_NSHARE, #endif #ifdef O_PRIV OPT_O_PRIV, #endif OPT_O_RDONLY, /* open() */ OPT_O_RDWR, /* open() */ #ifdef O_RSHARE OPT_O_RSHARE, #endif #ifdef O_RSYNC OPT_O_RSYNC, #endif #ifdef O_SYNC OPT_O_SYNC, #endif OPT_O_TEXT, /* Cygwin */ OPT_O_TRUNC, /* open(): O_TRUNC */ OPT_O_WRONLY, /* open() */ OPT_PARENB, /* termios.c_cflag */ OPT_PARMRK, /* termios.c_iflag */ OPT_PARODD, /* termios.c_cflag */ OPT_PATH, #ifdef PENDIN OPT_PENDIN, /* termios.c_lflag */ #endif OPT_PERM, OPT_PERM_EARLY, OPT_PERM_LATE, OPT_PIPES, /*OPT_PORT,*/ OPT_PROMPT, /* readline */ OPT_PROTOCOL, /* 6=TCP, 17=UDP */ OPT_PROTOCOL_FAMILY, /* 1=PF_UNIX, 2=PF_INET, 10=PF_INET6 */ OPT_PROXYPORT, OPT_PROXY_AUTHORIZATION, OPT_PROXY_RESOLVE, #if HAVE_DEV_PTMX || HAVE_DEV_PTC OPT_PTMX, #endif OPT_PTY, OPT_PTY_INTERVALL, OPT_PTY_WAIT_SLAVE, OPT_RANGE, /* restrict client socket address */ OPT_RAW, /* termios */ OPT_READBYTES, OPT_RES_AAONLY, /* resolver(3) */ OPT_RES_DEBUG, /* resolver(3) */ OPT_RES_DEFNAMES, /* resolver(3) */ OPT_RES_DNSRCH, /* resolver(3) */ OPT_RES_IGNTC, /* resolver(3) */ OPT_RES_PRIMARY, /* resolver(3) */ OPT_RES_RECURSE, /* resolver(3) */ OPT_RES_STAYOPEN, /* resolver(3) */ OPT_RES_USEVC, /* resolver(3) */ OPT_RETRY, OPT_SANE, /* termios */ OPT_SCTP_MAXSEG, OPT_SCTP_MAXSEG_LATE, OPT_SCTP_NODELAY, OPT_SEEK32_CUR, OPT_SEEK32_END, OPT_SEEK32_SET, OPT_SEEK64_CUR, OPT_SEEK64_END, OPT_SEEK64_SET, OPT_SETGID, OPT_SETGID_EARLY, OPT_SETPGID, OPT_SETSID, OPT_SETSOCKOPT_BIN, OPT_SETSOCKOPT_INT, OPT_SETSOCKOPT_STRING, OPT_SETUID, OPT_SETUID_EARLY, OPT_SHUT_CLOSE, OPT_SHUT_DOWN, OPT_SHUT_NONE, OPT_SHUT_NULL, /* send 0 bytes on shutdown */ OPT_SIGHUP, OPT_SIGINT, OPT_SIGQUIT, #ifdef SIOCSPGRP OPT_SIOCSPGRP, #endif #ifdef SO_ACCEPTCONN OPT_SO_ACCEPTCONN, #endif /* SO_ACCEPTCONN */ #ifdef SO_ATTACH_FILTER OPT_SO_ATTACH_FILTER, #endif #ifdef SO_AUDIT /* AIX 4.3.3 */ OPT_SO_AUDIT, #endif /* SO_AUDIT */ #ifdef SO_BINDTODEVICE OPT_SO_BINDTODEVICE, #endif OPT_SO_BROADCAST, #ifdef SO_BSDCOMPAT OPT_SO_BSDCOMPAT, #endif #ifdef SO_CKSUMRECV OPT_SO_CKSUMRECV, #endif /* SO_CKSUMRECV */ OPT_SO_DEBUG, #ifdef SO_DETACH_FILTER OPT_SO_DETACH_FILTER, #endif #ifdef SO_DGRAM_ERRIND OPT_SO_DGRAM_ERRIND, #endif #ifdef SO_DONTLINGER OPT_SO_DONTLINGER, #endif OPT_SO_DONTROUTE, OPT_SO_ERROR, OPT_SO_KEEPALIVE, #ifdef SO_KERNACCEPT /* AIX 4.3.3 */ OPT_SO_KERNACCEPT, #endif /* SO_KERNACCEPT */ OPT_SO_LINGER, #ifdef SO_NO_CHECK OPT_SO_NO_CHECK, #endif #ifdef SO_NOREUSEADDR /* AIX 4.3.3 */ OPT_SO_NOREUSEADDR, #endif /* SO_NOREUSEADDR */ OPT_SO_OOBINLINE, #ifdef SO_PASSCRED OPT_SO_PASSCRED, #endif #ifdef SO_PEERCRED OPT_SO_PEERCRED, #endif #ifdef SO_PRIORITY OPT_SO_PRIORITY, #endif OPT_SO_PROTOTYPE, OPT_SO_RCVBUF, OPT_SO_RCVBUF_LATE, #ifdef SO_RCVLOWAT OPT_SO_RCVLOWAT, #endif #ifdef SO_RCVTIMEO OPT_SO_RCVTIMEO, #endif OPT_SO_REUSEADDR, #ifdef SO_REUSEPORT OPT_SO_REUSEPORT, #endif /* defined(SO_REUSEPORT) */ #ifdef SO_SECURITY_AUTHENTICATION OPT_SO_SECURITY_AUTHENTICATION, #endif #ifdef SO_SECURITY_ENCRYPTION_NETWORK OPT_SO_SECURITY_ENCRYPTION_NETWORK, #endif #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT OPT_SO_SECURITY_ENCRYPTION_TRANSPORT, #endif OPT_SO_SNDBUF, OPT_SO_SNDBUF_LATE, #ifdef SO_SNDLOWAT OPT_SO_SNDLOWAT, #endif #ifdef SO_SNDTIMEO OPT_SO_SNDTIMEO, #endif OPT_SO_TIMESTAMP, /* Linux */ OPT_SO_TYPE, #ifdef SO_USELOOPBACK OPT_SO_USELOOPBACK, #endif /* SO_USELOOPBACK */ #ifdef SO_USE_IFBUFS OPT_SO_USE_IFBUFS, #endif /* SO_USE_IFBUFS */ #if 1 || defined(WITH_SOCKS4) OPT_SOCKSPORT, OPT_SOCKSUSER, #endif OPT_SOURCEPORT, OPT_STDERR, /* with exec, system */ # define ENABLE_OPTCODE # include "xio-streams.h" # undef ENABLE_OPTCODE OPT_SUBSTUSER_EARLY, OPT_SUBSTUSER, #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT) OPT_SUBSTUSER_DELAYED, #endif OPT_SYMBOLIC_LINK, /* with pty */ #ifdef TABDLY # ifdef TAB0 OPT_TAB0, /* termios.c_oflag */ # endif # ifdef TAB1 OPT_TAB1, /* termios.c_oflag */ # endif # ifdef TAB2 OPT_TAB2, /* termios.c_oflag */ # endif # ifdef TAB3 OPT_TAB3, /* termios.c_oflag */ # endif OPT_TABDLY, /* termios.c_oflag */ #endif OPT_TCPWRAPPERS, /* libwrap */ OPT_TCPWRAP_ETC, /* libwrap */ OPT_TCPWRAP_HOSTS_ALLOW_TABLE, /* libwrap */ OPT_TCPWRAP_HOSTS_DENY_TABLE, /* libwrap */ OPT_TCP_ABORT_THRESHOLD, /* HP-UX */ OPT_TCP_CONN_ABORT_THRESHOLD, /* HP-UX */ #ifdef TCP_CORK OPT_TCP_CORK, #endif #ifdef TCP_DEFER_ACCEPT OPT_TCP_DEFER_ACCEPT, /* Linux 2.4.0 */ #endif #ifdef TCP_INFO OPT_TCP_INFO, /* Linux 2.4.0 */ #endif #ifdef TCP_KEEPCNT OPT_TCP_KEEPCNT, /* Linux 2.4.0 */ #endif #ifdef TCP_KEEPIDLE OPT_TCP_KEEPIDLE, /* Linux 2.4.0 */ #endif OPT_TCP_KEEPINIT, /* OSF1 */ #ifdef TCP_KEEPINTVL OPT_TCP_KEEPINTVL, /* Linux 2.4.0 */ #endif #ifdef TCP_LINGER2 OPT_TCP_LINGER2, /* Linux 2.4.0 */ #endif #ifdef TCP_MAXSEG OPT_TCP_MAXSEG, OPT_TCP_MAXSEG_LATE, #endif OPT_TCP_MD5SIG, /* FreeBSD */ #ifdef TCP_NODELAY OPT_TCP_NODELAY, #endif OPT_TCP_NOOPT, /* FreeBSD */ OPT_TCP_NOPUSH, /* FreeBSD */ OPT_TCP_PAWS, /* OSF1 */ #ifdef TCP_QUICKACK OPT_TCP_QUICKACK, /* Linux 2.4 */ #endif #ifdef TCP_RFC1323 OPT_TCP_RFC1323, /* AIX 4.3.3 */ #endif OPT_TCP_SACKENA, /* OSF1 */ OPT_TCP_SACK_DISABLE, /* OpenBSD */ OPT_TCP_SIGNATURE_ENABLE, /* OpenBSD */ #ifdef TCP_STDURG OPT_TCP_STDURG, /* AIX 4.3.3; Linux: see man 7 tcp */ #endif #ifdef TCP_SYNCNT OPT_TCP_SYNCNT, /* Linux 2.4.0 */ #endif OPT_TCP_TSOPTENA, /* OSF1 */ #ifdef TCP_WINDOW_CLAMP OPT_TCP_WINDOW_CLAMP, /* Linux 2.4.0 */ #endif OPT_TERMIOS_CFMAKERAW, /* termios.cfmakeraw() */ OPT_TERMIOS_RAWER, OPT_TIOCSCTTY, OPT_TOSTOP, /* termios.c_lflag */ OPT_TUN_DEVICE, /* tun: /dev/net/tun ... */ OPT_TUN_NAME, /* tun: tun0 */ OPT_TUN_TYPE, /* tun: tun|tap */ OPT_UMASK, OPT_UNIX_TIGHTSOCKLEN, /* UNIX domain sockets */ OPT_UNLINK, OPT_UNLINK_CLOSE, OPT_UNLINK_EARLY, OPT_UNLINK_LATE, OPT_USER, OPT_USER_EARLY, OPT_USER_LATE, #ifdef VDISCARD OPT_VDISCARD, /* termios.c_cc */ #endif OPT_VDSUSP, /* termios.c_cc - HP-UX */ OPT_VEOF, /* termios.c_cc */ OPT_VEOL, /* termios.c_cc */ OPT_VEOL2, /* termios.c_cc */ OPT_VERASE, /* termios.c_cc */ OPT_VINTR, /* termios.c_cc */ OPT_VKILL, /* termios.c_cc */ OPT_VLNEXT, /* termios.c_cc */ OPT_VMIN, /* termios.c_cc */ OPT_VQUIT, /* termios.c_cc */ OPT_VREPRINT, /* termios.c_cc */ OPT_VSTART, /* termios.c_cc */ OPT_VSTOP, /* termios.c_cc */ OPT_VSUSP, /* termios.c_cc */ OPT_VSWTC, /* termios.c_cc */ OPT_VTIME, /* termios.c_cc */ #ifdef VTDLY # ifdef VT0 OPT_VT0, /* termios.c_oflag */ # endif # ifdef VT1 OPT_VT1, /* termios.c_oflag */ # endif OPT_VTDLY, /* termios.c_oflag */ #endif #ifdef VWERASE OPT_VWERASE, /* termios.c_cc */ #endif OPT_WAITLOCK, #ifdef XCASE OPT_XCASE, /* termios.c_lflag */ #endif #if defined(TABDLY) && defined(XTABS) OPT_XTABS, /* termios.c_oflag */ #endif OPT_nocomma /* make aix xlc happy, no trailing comma */ } ; /* keep consistent with xiohelp.c:optionphasenames ! */ enum e_phase { PH_ALL, /* not for option definitions; use in apply funcs to say "all phases" */ PH_INIT, /* retrieving info from original state */ PH_EARLY, /* before any other processing */ PH_PREOPEN, /* before file descriptor is created/opened */ PH_OPEN, /* during filesystem entry creation/open */ PH_PASTOPEN, /* past filesystem entry creation/open */ PH_PRESOCKET, /* before socket call */ PH_SOCKET, /* for socket call */ PH_PASTSOCKET, /* after socket call */ PH_PREBIGEN, /* before socketpair() pipe() openpty() */ PH_BIGEN, /* during socketpair() pipe() openpty() */ PH_PASTBIGEN, /* past socketpair() pipe() openpty() */ PH_FD, /* soon after FD creation or identification */ PH_PREBIND, /* before socket bind() */ PH_BIND, /* during socket bind() ? */ PH_PASTBIND, /* past socket bind() - for client and server sockets! */ PH_PRELISTEN, /* before socket listen() */ PH_LISTEN, /* during socket listen() ? */ PH_PASTLISTEN, /* after socket listen() */ PH_PRECONNECT, /* before socket connect() */ PH_CONNECT, /* during socket connect() ? */ PH_PASTCONNECT, /* after socket connect() */ PH_PREACCEPT, /* before socket accept() */ PH_ACCEPT, /* during socket accept() ? */ PH_PASTACCEPT, /* after socket accept() */ PH_CONNECTED, /* for sockets, after connect() or accept() */ PH_PREFORK, /* before fork() (with both listen and exec!) */ PH_FORK, /* during fork() (with both listen and exec!) */ PH_PASTFORK, /* after fork() (with both listen and exec!) */ PH_LATE, /* FD is ready, before start of data loop */ PH_LATE2, /* FD is ready, dropping privileges */ PH_PREEXEC, /* before exec() or system() */ PH_EXEC, /* during exec() or system() */ PH_SPEC /* specific to situation, not fix */ } ; /* atomic structure to describe the syntax and more important semantics of an option */ struct optdesc { const char *defname; /* default name */ const char *nickname; /* usual name */ enum e_optcode optcode; /* short form of option name */ unsigned int group; enum e_phase phase; /* when this option is to be used */ enum e_types type; /* the data type as expected on input, and stored */ enum e_func func; /* which function can apply this option, e.g. ioctl(), getsockopt(), or just a bit pattern */ int major; /* major id for func: level (SOL_...) for setsockopt(), request for ioctl() */ int minor; /* minor id for func: SO_..., IP_..., */ long arg3; } ; extern bool xioopts_ignoregroups; extern const struct optname optionnames[]; extern int retropt_bool(struct opt *opts, int optcode, bool *result); extern int retropt_short(struct opt *opts, int optcode, short *result); extern int retropt_ushort(struct opt *opts, int optcode, unsigned short *result); extern int retropt_int(struct opt *opts, int optcode, int *result); extern int retropt_uint(struct opt *opts, int optcode, unsigned int *result); extern int retropt_long(struct opt *opts, int optcode, long *result); extern int retropt_ulong(struct opt *opts, int optcode, unsigned long *result); extern int retropt_flag(struct opt *opts, int optcode, flags_t *result); extern int retropt_string(struct opt *opts, int optcode, char **result); extern int retropt_timespec(struct opt *opts, int optcode, struct timespec *result); extern int retropt_bind(struct opt *opts, int af, int socktype, int ipproto, struct sockaddr *sa, socklen_t *salen, int feats, /* TCP etc: 1..address allowed, 3..address and port allowed */ unsigned long res_opts0, unsigned long res_opts1); extern int applyopts(int fd, struct opt *opts, enum e_phase phase); extern int applyopts2(int fd, struct opt *opts, unsigned int from, unsigned int to); extern int applyopts_flags(struct opt *opts, int group, flags_t *result); extern int applyopts_cloexec(int fd, struct opt *opts); extern int applyopts_early(const char *path, struct opt *opts); extern int applyopts_fchown(int fd, struct opt *opts); extern int applyopts_single(struct single *fd, struct opt *opts, enum e_phase phase); extern int applyopts_offset(struct single *xfd, struct opt *opts); extern int applyopts_signal(struct single *xfd, struct opt *opts); extern int _xio_openlate(struct single *fd, struct opt *opts); extern int parseopts(const char **a, unsigned int groups, struct opt **opts); extern int parseopts_table(const char **a, unsigned int groups, struct opt **opts, const struct optname optionnames[], size_t optionnum); extern struct opt *copyopts(const struct opt *opts, unsigned int groups); extern struct opt *moveopts(struct opt *opts, unsigned int groups); extern int leftopts(const struct opt *opts); extern int showleft(const struct opt *opts); extern int groupbits(int fd); extern int _groupbits(mode_t mode); extern int dropopts(struct opt *opts, unsigned int phase); extern int dropopts2(struct opt *opts, unsigned int from, unsigned int to); #if HAVE_BASIC_UID_T==1 # define retropt_uid(o,c,r) retropt_short(o,c,r) #elif HAVE_BASIC_UID_T==2 # define retropt_uid(o,c,r) retropt_ushort(o,c,r) #elif HAVE_BASIC_UID_T==3 # define retropt_uid(o,c,r) retropt_int(o,c,r) #elif HAVE_BASIC_UID_T==4 # define retropt_uid(o,c,r) retropt_uint(o,c,r) #elif HAVE_BASIC_UID_T==5 # define retropt_uid(o,c,r) retropt_long(o,c,r) #elif HAVE_BASIC_UID_T==6 # define retropt_uid(o,c,r) retropt_ulong(o,c,r) #else # error "HAVE_BASIC_UID_T is out of range: " HAVE_BASIC_UID_T #endif #if HAVE_BASIC_GID_T==1 # define retropt_gid(o,c,r) retropt_short(o,c,r) #elif HAVE_BASIC_GID_T==2 # define retropt_gid(o,c,r) retropt_ushort(o,c,r) #elif HAVE_BASIC_GID_T==3 # define retropt_gid(o,c,r) retropt_int(o,c,r) #elif HAVE_BASIC_GID_T==4 # define retropt_gid(o,c,r) retropt_uint(o,c,r) #elif HAVE_BASIC_GID_T==5 # define retropt_gid(o,c,r) retropt_long(o,c,r) #elif HAVE_BASIC_GID_T==6 # define retropt_gid(o,c,r) retropt_ulong(o,c,r) #else # error "HAVE_BASIC_GID_T is out of range: " HAVE_BASIC_GID_T #endif #if HAVE_BASIC_MODE_T==1 # define retropt_mode(o,c,r) retropt_short(o,c,r) #elif HAVE_BASIC_MODE_T==2 # define retropt_mode(o,c,r) retropt_ushort(o,c,r) #elif HAVE_BASIC_MODE_T==3 # define retropt_mode(o,c,r) retropt_int(o,c,r) #elif HAVE_BASIC_MODE_T==4 # define retropt_mode(o,c,r) retropt_uint(o,c,r) #elif HAVE_BASIC_MODE_T==5 # define retropt_mode(o,c,r) retropt_long(o,c,r) #elif HAVE_BASIC_MODE_T==6 # define retropt_mode(o,c,r) retropt_ulong(o,c,r) #else # error "HAVE_BASIC_MODE_T is out of range: " HAVE_BASIC_MODE_T #endif #endif /* !defined(__xioopts_h_included) */ socat-1.7.3.1/snprinterr.c0000644000201000020100000000441012460670272015137 0ustar gerhardgerhard/* snprinterr.c */ /* Copyright Gerhard Rieger */ /* a function similar to vsnprintf() but it just handles %m */ #include "config.h" #include /* ptrdiff_t */ #include /* isdigit() */ #include #include #include #if HAVE_SYSLOG_H #include #endif #include #include /* time_t, strftime() */ #include /* gettimeofday() */ #include #include #if HAVE_UNISTD_H #include #endif #include "snprinterr.h" #define HAVE_STRERROR_R 0 /* replace %m in format with actual strerror() message, write result to *str. keep other % formats unchanged! writes at most size chars including the terminating \0 to *str returns the number of bytes in the output without terminating \0 result is always \0 terminated except when size==0 */ int snprinterr(char *str, size_t size, const char *format) { char c; int full = 0; /* 1 means: there is no space left in * str for more data or \0 */ int count = 0; if (size == 0) return 0; if (count >= size) full = 1; while (c = *format++) { if (c == '%') { c = *format++; switch (c) { case '\0': ++count; if (!full) { (*str++ = '%'); if (count+1 >= size) full = 1; } break; default: ++count; if (!full) { (*str++ = '%'); if (count+1 >= size) full = 1; } ++count; if (!full) { (*str++ = c); if (count+1 >= size) full = 1; } break; case 'm': { #if HAVE_STRERROR_R # define BUFLEN 64 char buf[BUFLEN] = ""; #endif /* HAVE_STRERROR_R */ char *bufp; #if !HAVE_STRERROR_R bufp = strerror(errno); #else /* there are two versions floating around... */ # if 1 /* GNU version */ bufp = strerror_r(errno, buf, BUFLEN); # else /* standard version */ strerror_r(errno, buf, BUFLEN); bufp = buf; # endif #endif /* HAVE_STRERROR_R */ while ((c = *bufp++) != '\0') { ++count; if (!full) { (*str++ = c); if (count+1 >= size) full = 1; } } } c = ' '; /* not \0 ! */ break; } if (c == '\0') break; } else { ++count; if (!full) { (*str++ = c); if (count+1 >= size) full = 1; } } } *str++ = '\0'; /* always write terminating \0 */ return count; #undef BUFLEN } socat-1.7.3.1/xio-pipe.c0000644000201000020100000001243512455415361014471 0ustar gerhardgerhard/* source: xio-pipe.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of pipe type */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-named.h" #if WITH_PIPE static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); static int xioopen_fifo_unnamed(xiofile_t *sock, struct opt *opts); const struct addrdesc addr_pipe = { "pipe", 3, xioopen_fifo, GROUP_FD|GROUP_NAMED|GROUP_OPEN|GROUP_FIFO, 0, 0, 0 HELP(":") }; /* process an unnamed bidirectional "pipe" or "fifo" or "echo" argument with options */ static int xioopen_fifo_unnamed(xiofile_t *sock, struct opt *opts) { struct opt *opts2; int filedes[2]; int numleft; int result; if (applyopts_single(&sock->stream, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); if (Pipe(filedes) != 0) { Error2("pipe(%p): %s", filedes, strerror(errno)); return -1; } /*0 Info2("pipe({%d,%d})", filedes[0], filedes[1]);*/ sock->common.tag = XIO_TAG_RDWR; sock->stream.dtype = XIODATA_PIPE; sock->stream.fd = filedes[0]; sock->stream.para.bipipe.fdout = filedes[1]; applyopts_cloexec(sock->stream.fd, opts); applyopts_cloexec(sock->stream.para.bipipe.fdout, opts); /* one-time and input-direction options, no second application */ retropt_bool(opts, OPT_IGNOREEOF, &sock->stream.ignoreeof); /* here we copy opts! */ if ((opts2 = copyopts(opts, GROUP_FIFO)) == NULL) { return STAT_NORETRY; } /* apply options to first FD */ if ((result = applyopts(sock->stream.fd, opts, PH_ALL)) < 0) { return result; } if ((result = applyopts_single(&sock->stream, opts, PH_ALL)) < 0) { return result; } /* apply options to second FD */ if ((result = applyopts(sock->stream.para.bipipe.fdout, opts2, PH_ALL)) < 0) { return result; } if ((numleft = leftopts(opts)) > 0) { Error1("%d option(s) could not be used", numleft); showleft(opts); } Notice("writing to and reading from unnamed pipe"); return 0; } /* open a named or unnamed pipe/fifo */ static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3) { const char *pipename = argv[1]; int rw = (xioflags & XIO_ACCMODE); #if HAVE_STAT64 struct stat64 pipstat; #else struct stat pipstat; #endif /* !HAVE_STAT64 */ bool opt_unlink_early = false; bool opt_unlink_close = true; mode_t mode = 0666; int result; if (argc == 1) { return xioopen_fifo_unnamed(fd, fd->stream.opts); } if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); } if (applyopts_single(&fd->stream, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); applyopts_named(pipename, opts, PH_EARLY); /* umask! */ applyopts(-1, opts, PH_EARLY); if (opt_unlink_early) { if (Unlink(pipename) < 0) { if (errno == ENOENT) { Warn2("unlink(%s): %s", pipename, strerror(errno)); } else { Error2("unlink(%s): %s", pipename, strerror(errno)); return STAT_RETRYLATER; } } } retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); retropt_modet(opts, OPT_PERM, &mode); if (applyopts_named(pipename, opts, PH_EARLY) < 0) { return STAT_RETRYLATER; } if (applyopts_named(pipename, opts, PH_PREOPEN) < 0) { return STAT_RETRYLATER; } if ( #if HAVE_STAT64 Stat64(pipename, &pipstat) < 0 #else Stat(pipename, &pipstat) < 0 #endif /* !HAVE_STAT64 */ ) { if (errno != ENOENT) { Error3("stat(\"%s\", %p): %s", pipename, &pipstat, strerror(errno)); } else { Debug1("xioopen_fifo(\"%s\"): does not exist, creating fifo", pipename); #if 0 result = Mknod(pipename, S_IFIFO|mode, 0); if (result < 0) { Error3("mknod(%s, %d, 0): %s", pipename, mode, strerror(errno)); return STAT_RETRYLATER; } #else result = Mkfifo(pipename, mode); if (result < 0) { Error3("mkfifo(%s, %d): %s", pipename, mode, strerror(errno)); return STAT_RETRYLATER; } #endif Notice2("created named pipe \"%s\" for %s", pipename, ddirection[rw]); applyopts_named(pipename, opts, PH_ALL); } if (opt_unlink_close) { if ((fd->stream.unlink_close = strdup(pipename)) == NULL) { Error1("strdup(\"%s\"): out of memory", pipename); } fd->stream.opt_unlink_close = true; } } else { /* exists */ Debug1("xioopen_fifo(\"%s\"): already exist, opening it", pipename); Notice3("opening %s \"%s\" for %s", filetypenames[(pipstat.st_mode&S_IFMT)>>12], pipename, ddirection[rw]); /*applyopts_early(pipename, opts);*/ applyopts_named(pipename, opts, PH_EARLY); } if ((result = _xioopen_open(pipename, rw, opts)) < 0) { return result; } fd->stream.fd = result; applyopts_named(pipename, opts, PH_FD); applyopts(fd->stream.fd, opts, PH_FD); applyopts_cloexec(fd->stream.fd, opts); return _xio_openlate(&fd->stream, opts); } #endif /* WITH_PIPE */ socat-1.7.3.1/xio-pty.h0000644000201000020100000000072211453022152014336 0ustar gerhardgerhard/* source: xio-pty.h */ /* Copyright Gerhard Rieger 2002-2004 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_pty_h_included #define __xio_pty_h_included 1 extern const struct addrdesc addr_pty; extern const struct optdesc opt_symbolic_link; #if HAVE_POLL extern const struct optdesc opt_pty_wait_slave; extern const struct optdesc opt_pty_intervall; #endif /* HAVE_POLL */ #endif /* !defined(__xio_pty_h_included) */ socat-1.7.3.1/proxyecho.sh0000755000201000020100000000225012161506654015144 0ustar gerhardgerhard#! /bin/bash # source: proxyecho.sh # Copyright Gerhard Rieger 2003-2009 # Published under the GNU General Public License V.2, see file COPYING # perform primitive simulation of a proxy server with echo function via stdio. # accepts and answers correct HTTP CONNECT requests, but then just echoes data. # it is required for test.sh # for TCP, use this script as: # socat tcp-l:8080,reuseaddr,crlf system:"proxyecho.sh" if type socat >/dev/null 2>&1; then SOCAT=socat else SOCAT=./socat fi case `uname` in HP-UX|OSF1) CAT="$SOCAT -u stdin stdout" ;; *) CAT=cat ;; esac SPACES=" " while [ -n "$1" ]; do case "$1" in -w) n="$2"; while [ "$n" -gt 0 ]; do SPACES="$SPACES "; n=$((n-1)); done shift ;; #-s) STAT="$2"; shift ;; esac shift done # read and parse HTTP request read l if echo "$l" |egrep '^CONNECT +[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+ +HTTP/1.[01]$' >/dev/null then : go on below else echo "HTTP/1.0${SPACES}500 Bad Request" echo exit fi # read more headers until empty line while [ -n "$l" ]; do read l done # send status echo "HTTP/1.0${SPACES}200 OK" # send empty line echo # perform echo function exec $CAT socat-1.7.3.1/xio-termios.c0000644000201000020100000005235512460670272015223 0ustar gerhardgerhard/* source: xio-termios.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for terminal I/O options */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-termios.h" /****** TERMIOS addresses ******/ #if _WITH_TERMIOS #if WITH_TERMIOS const struct optdesc opt_tiocsctty={ "tiocsctty", "ctty",OPT_TIOCSCTTY, GROUP_TERMIOS, PH_LATE2, TYPE_BOOL, OFUNC_SPEC }; const struct optdesc opt_brkint = { "brkint", NULL, OPT_BRKINT, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, BRKINT }; const struct optdesc opt_icrnl = { "icrnl", NULL, OPT_ICRNL, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, ICRNL }; const struct optdesc opt_ignbrk = { "ignbrk", NULL, OPT_IGNBRK, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IGNBRK }; const struct optdesc opt_igncr = { "igncr", NULL, OPT_IGNCR, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IGNCR }; const struct optdesc opt_ignpar = { "ignpar", NULL, OPT_IGNPAR, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IGNPAR }; const struct optdesc opt_imaxbel = { "imaxbel", NULL, OPT_IMAXBEL, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IMAXBEL }; const struct optdesc opt_inlcr = { "inlcr", NULL, OPT_INLCR, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, INLCR }; const struct optdesc opt_inpck = { "inpck", NULL, OPT_INPCK, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, INPCK }; const struct optdesc opt_istrip = { "istrip", NULL, OPT_ISTRIP, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, ISTRIP }; #ifdef IUCLC const struct optdesc opt_iuclc = { "iuclc", NULL, OPT_IUCLC, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IUCLC }; #endif const struct optdesc opt_ixany = { "ixany", NULL, OPT_IXANY, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IXANY }; const struct optdesc opt_ixoff = { "ixoff", NULL, OPT_IXOFF, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IXOFF }; const struct optdesc opt_ixon = { "ixon", NULL, OPT_IXON, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IXON }; const struct optdesc opt_parmrk = { "parmrk", NULL, OPT_PARMRK, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, PARMRK }; #ifdef CRDLY # ifdef CR0 const struct optdesc opt_cr0 = { "cr0", NULL, OPT_CR0, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, CR0, CRDLY }; # endif # ifdef CR1 const struct optdesc opt_cr1 = { "cr1", NULL, OPT_CR1, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, CR1, CRDLY }; # endif # ifdef CR2 const struct optdesc opt_cr2 = { "cr2", NULL, OPT_CR2, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, CR2, CRDLY }; # endif # ifdef CR3 const struct optdesc opt_cr3 = { "cr3", NULL, OPT_CR3, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, CR3, CRDLY }; # endif # if CRDLY_SHIFT >= 0 const struct optdesc opt_crdly = { "crdly", NULL, OPT_CRDLY, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_VALUE, 1, CRDLY, CRDLY_SHIFT }; # endif #endif /* defined(CRDLY) */ #ifdef NLDLY # ifdef NL0 const struct optdesc opt_nl0 = { "nl0", NULL, OPT_NL0, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, NL0, NLDLY }; # endif # ifdef NL1 const struct optdesc opt_nl1 = { "nl1", NULL, OPT_NL1, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, NL1, NLDLY }; # endif const struct optdesc opt_nldly = { "nldly", NULL, OPT_NLDLY, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 1, NLDLY }; #endif /* defined(NLDLY) */ #ifdef OCRNL const struct optdesc opt_ocrnl = { "ocrnl", NULL, OPT_OCRNL, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 1, OCRNL }; #endif #ifdef OFDEL const struct optdesc opt_ofdel = { "ofdel", NULL, OPT_OFDEL, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 1, OFDEL }; #endif #ifdef OFILL const struct optdesc opt_ofill = { "ofill", NULL, OPT_OFILL, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 1, OFILL }; #endif const struct optdesc opt_opost = { "opost", NULL, OPT_OPOST, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 1, OPOST }; #ifdef OLCUC const struct optdesc opt_olcuc = { "olcuc", NULL, OPT_OLCUC, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 1, OLCUC }; #endif const struct optdesc opt_onlcr = { "onlcr", NULL, OPT_ONLCR, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 1, ONLCR }; #ifdef ONLRET const struct optdesc opt_onlret = { "onlret", NULL, OPT_ONLRET, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 1, ONLRET }; #endif #ifdef ONOCR const struct optdesc opt_onocr = { "onocr", NULL, OPT_ONOCR, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 1, ONOCR }; #endif #ifdef TABDLY # ifdef TAB0 const struct optdesc opt_tab0 = { "tab0", NULL, OPT_TAB0, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_FLAG, 1, TAB0, TABDLY }; # endif # ifdef TAB1 const struct optdesc opt_tab1 = { "tab1", NULL, OPT_TAB1, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_FLAG, 1, TAB1, TABDLY }; # endif # ifdef TAB2 const struct optdesc opt_tab2 = { "tab2", NULL, OPT_TAB2, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_FLAG, 1, TAB2, TABDLY }; # endif # ifdef TAB3 const struct optdesc opt_tab3 = { "tab3", NULL, OPT_TAB3, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_FLAG, 1, TAB3, TABDLY }; # endif # ifdef XTABS const struct optdesc opt_xtabs = { "xtabs", NULL, OPT_XTABS, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_FLAG, 1, XTABS, TABDLY }; # endif # if TABDLY_SHIFT >= 0 const struct optdesc opt_tabdly = { "tabdly", NULL, OPT_TABDLY, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_VALUE, 1, TABDLY, TABDLY_SHIFT }; # endif #endif /* defined(TABDLY) */ #ifdef BSDLY # ifdef BS0 const struct optdesc opt_bs0 = { "bs0", NULL, OPT_BS0, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, BS0, BSDLY }; #endif # ifdef BS1 const struct optdesc opt_bs1 = { "bs1", NULL, OPT_BS1, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, BS1, BSDLY }; # endif const struct optdesc opt_bsdly = { "bsdly", NULL, OPT_BSDLY, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 1, BSDLY }; #endif #ifdef VTDLY # ifdef VT0 const struct optdesc opt_vt0 = { "vt0", NULL, OPT_VT0, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, VT0, VTDLY }; # endif # ifdef VT1 const struct optdesc opt_vt1 = { "vt1", NULL, OPT_VT1, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, VT1, VTDLY }; # endif const struct optdesc opt_vtdly = { "vtdly", NULL, OPT_VTDLY, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 1, VTDLY }; #endif #ifdef FFDLY # ifdef FF0 const struct optdesc opt_ff0 = { "ff0", NULL, OPT_FF0, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, FF0, FFDLY }; # endif # ifdef FF1 const struct optdesc opt_ff1 = { "ff1", NULL, OPT_FF1, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, FF1, FFDLY }; # endif const struct optdesc opt_ffdly = { "ffdly", NULL, OPT_FFDLY, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 1, FFDLY }; #endif #ifdef CBAUD const struct optdesc opt_b0 = { "b0", NULL, OPT_B0, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B0, CBAUD }; const struct optdesc opt_b50 = { "b50", NULL, OPT_B50, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B50, CBAUD }; const struct optdesc opt_b75 = { "b75", NULL, OPT_B75, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B75, CBAUD }; const struct optdesc opt_b110 = { "b110", NULL, OPT_B110, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B110, CBAUD }; const struct optdesc opt_b134 = { "b134", NULL, OPT_B134, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B134, CBAUD }; const struct optdesc opt_b150 = { "b150", NULL, OPT_B150, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B150, CBAUD }; const struct optdesc opt_b200 = { "b200", NULL, OPT_B200, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B200, CBAUD }; const struct optdesc opt_b300 = { "b300", NULL, OPT_B300, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B300, CBAUD }; const struct optdesc opt_b600 = { "b600", NULL, OPT_B600, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B600, CBAUD }; #ifdef B900 /* HP-UX */ const struct optdesc opt_b900 = { "b900", NULL, OPT_B900, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B900, CBAUD }; #endif const struct optdesc opt_b1200 = { "b1200", NULL, OPT_B1200, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B1200, CBAUD }; const struct optdesc opt_b1800 = { "b1800", NULL, OPT_B1800, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B1800, CBAUD }; const struct optdesc opt_b2400 = { "b2400", NULL, OPT_B2400, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B2400, CBAUD }; #ifdef B3600 /* HP-UX */ const struct optdesc opt_b3600 = { "b3600", NULL, OPT_B3600, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B3600, CBAUD }; #endif const struct optdesc opt_b4800 = { "b4800", NULL, OPT_B4800, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B4800, CBAUD }; #ifdef B7200 /* HP-UX */ const struct optdesc opt_b7200 = { "b7200", NULL, OPT_B7200, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B7200, CBAUD }; #endif const struct optdesc opt_b9600 = { "b9600", NULL, OPT_B9600, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B9600, CBAUD }; const struct optdesc opt_b19200 = { "b19200", NULL, OPT_B19200, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B19200, CBAUD }; const struct optdesc opt_b38400 = { "b38400", NULL, OPT_B38400, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B38400, CBAUD }; #ifdef B57600 const struct optdesc opt_b57600 = { "b57600", NULL, OPT_B57600, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B57600, CBAUD }; #endif #ifdef B115200 const struct optdesc opt_b115200 = { "b115200", NULL, OPT_B115200, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B115200, CBAUD }; #endif #ifdef B230400 const struct optdesc opt_b230400 = { "b230400", NULL, OPT_B230400, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B230400, CBAUD }; #endif #ifdef B460800 const struct optdesc opt_b460800 = { "b460800", NULL, OPT_B460800, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B460800, CBAUD }; #endif #ifdef B500000 const struct optdesc opt_b500000 = { "b500000", NULL, OPT_B500000, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B500000, CBAUD }; #endif #ifdef B576000 const struct optdesc opt_b576000 = { "b576000", NULL, OPT_B576000, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B576000, CBAUD }; #endif #ifdef B921600 const struct optdesc opt_b921600 = { "b921600", NULL, OPT_B921600, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B921600, CBAUD }; #endif #ifdef B1000000 const struct optdesc opt_b1000000= { "b1000000",NULL, OPT_B1000000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B1000000, CBAUD }; #endif #ifdef B1152000 const struct optdesc opt_b1152000= { "b1152000",NULL, OPT_B1152000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B1152000, CBAUD }; #endif #ifdef B1500000 const struct optdesc opt_b1500000= { "b1500000",NULL, OPT_B1500000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B1500000, CBAUD }; #endif #ifdef B2000000 const struct optdesc opt_b2000000= { "b2000000",NULL, OPT_B2000000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B2000000, CBAUD }; #endif #ifdef B2500000 const struct optdesc opt_b2500000= { "b2500000",NULL, OPT_B2500000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B2500000, CBAUD }; #endif #ifdef B3000000 const struct optdesc opt_b3000000= { "b3000000",NULL, OPT_B3000000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B3000000, CBAUD }; #endif #ifdef B3500000 const struct optdesc opt_b3500000= { "b3500000",NULL, OPT_B3500000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B3500000, CBAUD }; #endif #ifdef B4000000 const struct optdesc opt_b4000000= { "b4000000",NULL, OPT_B4000000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B4000000, CBAUD }; #endif #endif /* defined(CBAUD) */ const struct optdesc opt_cs5 = { "cs5", NULL, OPT_CS5, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, CS5, CSIZE }; const struct optdesc opt_cs6 = { "cs6", NULL, OPT_CS6, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, CS6, CSIZE }; const struct optdesc opt_cs7 = { "cs7", NULL, OPT_CS7, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, CS7, CSIZE }; const struct optdesc opt_cs8 = { "cs8", NULL, OPT_CS8, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, CS8, CSIZE }; #if CSIZE_SHIFT >= 0 const struct optdesc opt_csize = { "csize", NULL, OPT_CSIZE, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_VALUE, 2, CSIZE, CSIZE_SHIFT }; #endif const struct optdesc opt_cstopb = { "cstopb", NULL, OPT_CSTOPB, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 2, CSTOPB }; const struct optdesc opt_cread = { "cread", NULL, OPT_CREAD, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 2, CREAD }; const struct optdesc opt_parenb = { "parenb", NULL, OPT_PARENB, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 2, PARENB }; const struct optdesc opt_parodd = { "parodd", NULL, OPT_PARODD, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 2, PARODD }; const struct optdesc opt_hupcl = { "hupcl", NULL, OPT_HUPCL, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 2, HUPCL }; const struct optdesc opt_clocal = { "clocal", NULL, OPT_CLOCAL, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 2, CLOCAL }; /*const struct optdesc opt_cibaud = { "cibaud",NULL, OPT_CIBAUD, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 2, CIBAUD };*/ #ifdef CRTSCTS const struct optdesc opt_crtscts = { "crtscts", NULL, OPT_CRTSCTS, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 2, CRTSCTS }; #endif const struct optdesc opt_isig = { "isig", NULL, OPT_ISIG, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, ISIG }; const struct optdesc opt_icanon = { "icanon", NULL, OPT_ICANON, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, ICANON }; #ifdef XCASE const struct optdesc opt_xcase = { "xcase", NULL, OPT_XCASE, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, XCASE }; #endif const struct optdesc opt_echo = { "echo", NULL, OPT_ECHO, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, ECHO }; const struct optdesc opt_echoe = { "echoe", NULL, OPT_ECHOE, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, ECHOE }; const struct optdesc opt_echok = { "echok", NULL, OPT_ECHOK, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, ECHOK }; const struct optdesc opt_echonl = { "echonl", NULL, OPT_ECHONL, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, ECHONL }; const struct optdesc opt_echoctl = { "echoctl", NULL, OPT_ECHOCTL, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, ECHOCTL }; #ifdef ECHOPRT const struct optdesc opt_echoprt = { "echoprt", NULL, OPT_ECHOPRT, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, ECHOPRT }; #endif const struct optdesc opt_echoke = { "echoke", NULL, OPT_ECHOKE, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, ECHOKE }; const struct optdesc opt_flusho = { "flusho", NULL, OPT_FLUSHO, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, FLUSHO }; const struct optdesc opt_noflsh = { "noflsh", NULL, OPT_NOFLSH, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, NOFLSH }; const struct optdesc opt_tostop = { "tostop", NULL, OPT_TOSTOP, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, TOSTOP }; #ifdef PENDIN const struct optdesc opt_pendin = { "pendin", NULL, OPT_PENDIN, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, PENDIN }; #endif const struct optdesc opt_iexten = { "iexten", NULL, OPT_IEXTEN, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 3, IEXTEN }; const struct optdesc opt_vintr = { "vintr", "intr", OPT_VINTR, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VINTR }; const struct optdesc opt_vquit = { "vquit", "quit", OPT_VQUIT, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VQUIT }; const struct optdesc opt_verase = { "verase", "erase", OPT_VERASE, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VERASE }; const struct optdesc opt_vkill = { "vkill", "kill", OPT_VKILL, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VKILL }; const struct optdesc opt_veof = { "veof", "eof", OPT_VEOF, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VEOF }; const struct optdesc opt_vtime = { "vtime", "time", OPT_VTIME, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VTIME }; const struct optdesc opt_vmin = { "vmin", "min", OPT_VMIN, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VMIN }; #ifdef VSWTC const struct optdesc opt_vswtc = { "vswtc", "swtc", OPT_VSWTC, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VSWTC }; #endif /* VSWTC */ const struct optdesc opt_vstart = { "vstart", "start", OPT_VSTART, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VSTART }; const struct optdesc opt_vstop = { "vstop", "stop", OPT_VSTOP, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VSTOP }; const struct optdesc opt_vsusp = { "vsusp", "susp", OPT_VSUSP, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VSUSP }; #ifdef VDSUSP /* HP-UX */ const struct optdesc opt_vdsusp = { "vdsusp", "dsusp", OPT_VDSUSP, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VDSUSP }; #endif const struct optdesc opt_veol = { "veol", "eol", OPT_VEOL, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VEOL }; #ifdef VREPRINT const struct optdesc opt_vreprint = { "vreprint","reprint",OPT_VREPRINT,GROUP_TERMIOS,PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VREPRINT }; #endif #ifdef VDISCARD const struct optdesc opt_vdiscard = { "vdiscard","discard",OPT_VDISCARD,GROUP_TERMIOS,PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VDISCARD }; #endif #ifdef VWERASE const struct optdesc opt_vwerase = { "vwerase","werase",OPT_VWERASE, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VWERASE }; #endif const struct optdesc opt_vlnext = { "vlnext", "lnext", OPT_VLNEXT, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VLNEXT }; const struct optdesc opt_veol2 = { "veol2", "eol2", OPT_VEOL2, GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VEOL2 }; const struct optdesc opt_raw = { "raw", NULL, OPT_RAW, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_SPEC }; const struct optdesc opt_sane = { "sane", NULL, OPT_SANE, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_SPEC }; const struct optdesc opt_termios_cfmakeraw = { "termios-cfmakeraw", "cfmakeraw", OPT_TERMIOS_CFMAKERAW, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_SPEC }; const struct optdesc opt_termios_rawer = { "termios-rawer", "rawer", OPT_TERMIOS_RAWER, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_SPEC }; #ifdef HAVE_TERMIOS_ISPEED #if defined(ISPEED_OFFSET) && (ISPEED_OFFSET != -1) #if defined(OSPEED_OFFSET) && (OSPEED_OFFSET != -1) const struct optdesc opt_ispeed = { "ispeed", NULL, OPT_ISPEED, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_SPEED, ISPEED_OFFSET }; const struct optdesc opt_ospeed = { "ospeed", NULL, OPT_OSPEED, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_SPEED, OSPEED_OFFSET }; #endif #endif #endif /* HAVE_TERMIOS_ISPEED */ int xiotermiosflag_applyopt(int fd, struct opt *opt) { int result; if (opt->value.u_bool) { result = xiotermios_setflag(fd, opt->desc->major, opt->desc->minor); } else { result = xiotermios_clrflag(fd, opt->desc->major, opt->desc->minor); } if (result < 0) { opt->desc = ODESC_ERROR; return -1; } return 0; } #endif /* WITH_TERMIOS */ int xiotermios_setflag(int fd, int word, tcflag_t mask) { union { struct termios termarg; tcflag_t flags[4]; } tdata; if (Tcgetattr(fd, &tdata.termarg) < 0) { Error3("tcgetattr(%d, %p): %s", fd, &tdata.termarg, strerror(errno)); return -1; } tdata.flags[word] |= mask; if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) { Error3("tcsetattr(%d, TCSADRAIN, %p): %s", fd, &tdata.termarg, strerror(errno)); return -1; } return 0; } int xiotermios_clrflag(int fd, int word, tcflag_t mask) { union { struct termios termarg; tcflag_t flags[4]; } tdata; if (Tcgetattr(fd, &tdata.termarg) < 0) { Error3("tcgetattr(%d, %p): %s", fd, &tdata.termarg, strerror(errno)); return -1; } tdata.flags[word] &= ~mask; if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) { Error3("tcsetattr(%d, TCSADRAIN, %p): %s", fd, &tdata.termarg, strerror(errno)); return -1; } return 0; } #endif /* _WITH_TERMIOS */ socat-1.7.3.1/xio-interface.h0000644000201000020100000000047211453022152015464 0ustar gerhardgerhard/* source: xio-interface.h */ /* Copyright Gerhard Rieger 2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_interface_h_included #define __xio_interface_h_included 1 extern const struct addrdesc xioaddr_interface; #endif /* !defined(__xio_interface_h_included) */ socat-1.7.3.1/config.h.in0000644000201000020100000003706412460670272014623 0ustar gerhardgerhard/* source: config.h.in */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __config_h_included #define __config_h_included 1 /* Define to empty if the keyword does not work. */ #undef const /* Define to `int' if doesn't define. */ #undef gid_t /* Define if your struct stat has st_blksize. */ #undef HAVE_ST_BLKSIZE /* Define if your struct stat has st_blocks. */ #undef HAVE_ST_BLOCKS /* Define if your struct stat has st_rdev. */ #undef HAVE_ST_RDEV /* Define if you have the strftime function. */ #undef HAVE_STRFTIME /* Define if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define to `int' if doesn't define. */ #undef mode_t /* Define to `long' if doesn't define. */ #undef off_t /* Define to `int' if doesn't define. */ #undef pid_t /* Define as the return type of signal handlers (int or void). */ #undef RETSIGTYPE /* Define to `unsigned' if doesn't define. */ #undef size_t /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define to `int' if doesn't define. */ #undef uid_t /* Define if you have the putenv function. */ #undef HAVE_PUTENV /* Define if your cc provides char **environ declaration. This implies HAVE_VAR_ENVIRON */ #undef HAVE_DECL_ENVIRON /* Define if you have the char **environ variable */ #undef HAVE_VAR_ENVIRON /* Define if you have the select function. */ #undef HAVE_SELECT /* Define if you have the poll function. */ #undef HAVE_POLL /* Define if you have the socket function. */ #undef HAVE_SOCKET /* Define if you have the strdup function. */ #undef HAVE_PROTOTYPE_LIB_strdup /* Define if you have the strerror function. */ #undef HAVE_PROTOTYPE_LIB_strerror /* Define if you have the strstr function. */ #undef HAVE_PROTOTYPE_LIB_strstr /* Define if you have the strtod function. */ #undef HAVE_STRTOD /* Define if you have the strtol function. */ #undef HAVE_STRTOL /* Define if you have the strtoul function. */ #undef HAVE_STRTOUL /* Define if you have the uname function. */ #undef HAVE_UNAME /* Define if you have the getpgid function. */ #undef HAVE_GETPGID /* Define if you have the getsid function. */ #undef HAVE_GETSID /* Define if you have the nanosleep function. */ #undef HAVE_NANOSLEEP /* Define if you have the getaddrinfo function. */ #undef HAVE_GETADDRINFO /* Define if you have the getipnodebyname function. */ #undef HAVE_PROTOTYPE_LIB_getipnodebyname /* Define if you have the setgroups function. */ #undef HAVE_SETGROUPS /* Define if you have the inet_aton function. */ #undef HAVE_INET_ATON /* Define if you have the memrchr function. */ #undef HAVE_PROTOTYPE_LIB_memrchr /* Define if you have the if_indextoname function. */ #undef HAVE_PROTOTYPE_LIB_if_indextoname /* Define if you have the sigaction function */ #undef HAVE_SIGACTION /* Define if you have the stat64 function */ #undef HAVE_STAT64 /* Define if you have the fstat64 function */ #undef HAVE_FSTAT64 /* Define if you have the lstat64 function */ #undef HAVE_LSTAT64 /* Define if you have the lseek64 function */ #undef HAVE_LSEEK64 /* Define if you have the truncate64 function */ #undef HAVE_TRUNCATE64 /* Define if you have the ftruncate64 function */ #undef HAVE_FTRUNCATE64 /* Define if you have the clock_gettime function */ #undef HAVE_CLOCK_GETTIME /* Define if you have the strtoll function */ #undef HAVE_STRTOLL /* Define if you have the hstrerror function */ #undef HAVE_HSTRERROR /* Define if you have the inet_ntop function */ #undef HAVE_INET_NTOP /* Define if you have the hstrerror prototype */ #undef HAVE_PROTOTYPE_HSTRERROR /* Define if you have the header file. */ #undef HAVE_STDBOOL_H /* Define if you have the header file. */ #undef HAVE_INTTYPES_H /* Define if you have the header file. */ #undef HAVE_FCNTL_H /* Define if you have the header file. */ #undef HAVE_LIMITS_H /* Define if you have the header file. */ #undef HAVE_STRINGS_H /* Define if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define if you have the header file. */ #undef HAVE_SYSLOG_H /* Define if you have the header file. */ #undef HAVE_UNISTD_H /* Define if you have the header file. */ #undef HAVE_PWD_H /* Define if you have the header file. */ #undef HAVE_GRP_H /* Define if you have the header file. */ #undef HAVE_STDINT_H /* Define if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define if you have the header file. */ #undef HAVE_POLL_H /* Define if you have the header file. */ #undef HAVE_SYS_POLL_H /* Define if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define if you have the header file. */ #undef HAVE_SYS_UIO_H /* Define if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define if you have the header file. */ #undef HAVE_NETDB_H /* Define if you have the header file. */ #undef HAVE_SYS_UN_H /* Define if you have the header file. */ #undef HAVE_PTY_H /* Define if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define if you have the header file. */ #undef HAVE_NETINET_IN_SYSTM_H /* Define if you have the header file. */ #undef HAVE_NETINET_IP_H /* Define if you have the header file. */ #undef HAVE_NETINET_TCP_H /* Define if you have the header file. */ #undef HAVE_NETINET_IP6_H /* Define if you have the header file. */ #undef HAVE_NETINET6_IN6_H /* Define if you have the header file. */ #undef HAVE_ARPA_NAMESER_H /* Define if you have the header file. */ #undef HAVE_RESOLV_H /* Define if you have the header file. */ #undef HAVE_TERMIOS_H /* Define if you have the header file. */ #undef HAVE_NET_IF_H /* Define if you have the header file. */ #undef HAVE_NET_IF_DL_H /* Define if you have the header file. */ #undef HAVE_LINUX_TYPES_H /* Define if you have the header file. */ #undef HAVE_LINUX_ERRQUEUE_H /* Define if you have the header file. */ #undef HAVE_LINUX_IF_TUN_H /* Define if you have the header file. */ #undef HAVE_NETPACKET_PACKET_H /* Define if you have the header file. */ #undef HAVE_NETINET_IF_ETHER_H /* Define if you have the header file. */ #undef HAVE_SYS_UTSNAME_H /* Define if you have the header file. (AIX) */ #undef HAVE_SYS_SELECT_H /* Define if you have the header file. (AIX) */ #undef HAVE_SYS_FILE_H /* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ #undef HAVE_UTIL_H /* Define if you have the header file. */ #undef HAVE_BSD_LIBUTIL_H /* Define if you have the header file. (FreeBSD: openpty()) */ #undef HAVE_LIBUTIL_H /* Define if you have the header file. (stream opts on SunOS)*/ #undef HAVE_SYS_STROPTS_H /* Define if you have the header file. */ #undef HAVE_REGEX_H /* Define if you have the header file. */ #undef HAVE_LINUX_FS_H /* Define if you have the header file. */ #undef HAVE_LINUX_EXT2_FS_H /* Define if you have the header file. */ #undef HAVE_READLINE_READLINE_H /* Define if you have the header file. */ #undef HAVE_READLINE_HISTORY_H /* Define if you have the readline library. */ #undef HAVE_LIBREADLINE /* Define if you have the m library (-lm). */ #undef HAVE_LIBM /* Define if you have the floor function */ #undef HAVE_FLOOR /* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ #undef _XOPEN_EXTENDED_SOURCE /* fdset may have component fds_bits or __fds_bits */ #undef HAVE_FDS_BITS /* Define if you have the sa_family_t */ #undef HAVE_TYPE_SA_FAMILY_T /* define if your struct sigaction has sa_sigaction */ #undef HAVE_STRUCT_SIGACTION_SA_SIGACTION /* define if you have struct sock_extended_err */ #undef HAVE_STRUCT_SOCK_EXTENDED_ERR /* Define if your struct termios has component c_ispeed */ #undef HAVE_TERMIOS_ISPEED /* the offset of c_ispeed in struct termios - usable in an speed_t array. Applies only when HAVE_TERMIOS_ISPEED is set */ #undef ISPEED_OFFSET /* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ #ifdef ISPEED_OFFSET # define OSPEED_OFFSET (ISPEED_OFFSET+1) #else # undef OSPEED_OFFSET #endif /* Define if your termios.h likes _SVID3 defined */ #undef _SVID3 /* Define if your sys/socket.h likes _XPG4_2 defined */ #undef _XPG4_2 /* Define if your ctime_r() choices need _POSIX_PTHREAD_SEMANTICS */ #undef _POSIX_PTHREAD_SEMANTICS /* Define if you need __EXTENSIONS__ */ #undef __EXTENSIONS__ /* Define if you have struct timespec (e.g. for nanosleep) */ #undef HAVE_STRUCT_TIMESPEC /* Define if you have struct linger */ #undef HAVE_STRUCT_LINGER /* Define if you have struct ip_mreq */ #undef HAVE_STRUCT_IP_MREQ /* Define if you have struct ip_mreqn */ #undef HAVE_STRUCT_IP_MREQN /* Define if you have struct ipv6_mreq */ #undef HAVE_STRUCT_IPV6_MREQ /* Define if you have struct ifreq */ #undef HAVE_STRUCT_IFREQ /* Define if you have struct ifreq.ifr_index */ #undef HAVE_STRUCT_IFREQ_IFR_INDEX /* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX /* Define if your struct sockaddr has sa_len */ #undef HAVE_STRUCT_SOCKADDR_SALEN /* there are several implementations of sockaddr_in6 */ #undef HAVE_IP6_SOCKADDR /* Define if you have struct iovec */ #undef HAVE_STRUCT_IOVEC /* define if your struct msghdr has msg_control */ #undef HAVE_STRUCT_MSGHDR_MSGCONTROL /* define if your struct msghdr has msg_controllen */ #undef HAVE_STRUCT_MSGHDR_MSGCONTROLLEN /* define if your struct msghdr has msg_flag */ #undef HAVE_STRUCT_MSGHDR_MSGFLAGS /* define if you have struct cmsghdr */ #undef HAVE_STRUCT_CMSGHDR /* define if you have struct in_pktinfo */ #undef HAVE_STRUCT_IN_PKTINFO /* define if your struct in_pktinfo has component ipi_spec_dst */ #undef HAVE_PKTINFO_IPI_SPEC_DST /* define if you have struct in6_pktinfo */ #undef HAVE_STRUCT_IN6_PKTINFO /* define if your struct ip has ip_hl; otherwise assume ip_vhl */ #undef HAVE_STRUCT_IP_IP_HL /* Define if you have the setenv function */ #undef HAVE_SETENV /* Define if you have the unsetenv function. not on HP-UX */ #undef HAVE_UNSETENV /* Define if you have the SSLv2 client and server method functions. not in new openssl */ #undef HAVE_SSLv2_client_method #undef HAVE_SSLv2_server_method /* Define if you have the HAVE_SSL_CTX_set_default_verify_paths function */ #undef HAVE_SSL_CTX_set_default_verify_paths /* Define if you have the SSLv3 client and server method functions. not in new openssl */ #undef HAVE_SSLv3_client_method #undef HAVE_SSLv3_server_method /* Define if you have the SSLv3 client and server method functions with rollback to v2 */ #undef HAVE_SSLv23_client_method #undef HAVE_SSLv23_server_method /* Define if you have the TLSv1.0 client and server method functions */ #undef HAVE_TLSv1_client_method #undef HAVE_TLSv1_server_method /* Define if you have the TLSv1.1 client and server method functions */ #undef HAVE_TLSv1_1_client_method #undef HAVE_TLSv1_1_server_method /* Define if you have the TLSv1.2 client and server method functions */ #undef HAVE_TLSv1_2_client_method #undef HAVE_TLSv1_2_server_method /* Define if you have the DTLSv1 client and server method functions */ #undef HAVE_DTLSv1_client_method #undef HAVE_DTLSv1_server_method /* Define if you have the flock function */ #undef HAVE_FLOCK /* Define if you have the openpty function */ #undef HAVE_OPENPTY /* Define if you have the grantpt function */ #undef HAVE_GRANTPT /* Define if you have the unlockpt function */ #undef HAVE_UNLOCKPT /* Define if you have the ptsname function */ #undef HAVE_PROTOTYPE_LIB_ptsname /* Define if you have the /dev/ptmx pseudo terminal multiplexer */ #undef HAVE_DEV_PTMX /* Define if you have the /dev/ptc pseudo terminal multiplexer */ #undef HAVE_DEV_PTC /* Define if you have the cfmakeraw() function */ #undef HAVE_CFMAKERAW /* Define if you have the long long type */ #undef HAVE_TYPE_LONGLONG /* is sig_atomic_t declared */ #undef HAVE_TYPE_SIG_ATOMIC_T /* is bool already typedef'd? */ #undef HAVE_TYPE_BOOL /* is socklen_t already typedef'd? */ #undef HAVE_TYPE_SOCKLEN /* Define if you have the struct stat64 type */ #undef HAVE_TYPE_STAT64 /* Define if you have the struct off64_t type */ #undef HAVE_TYPE_OFF64 /* is sighandler_t already typedef'd? */ #undef HAVE_TYPE_SIGHANDLER /* is uint8_t already defined? */ #undef HAVE_TYPE_UINT8 /* is uint16_t already defined? */ #undef HAVE_TYPE_UINT16 /* is uint32_t already defined? */ #undef HAVE_TYPE_UINT32 /* is uint64_t already defined? */ #undef HAVE_TYPE_UINT64 /* Define if snprintf() returns required len on truncation (C-99 conform) */ #undef HAVE_C99_SNPRINTF /* Define if you have the printf "Z" modifier */ #undef HAVE_FORMAT_Z /* Define the shift offset of the CRDLY mask */ #undef CRDLY_SHIFT /* Define the shift offset of the TABDLY mask */ #undef TABDLY_SHIFT /* Define the shift offset of the CSIZE mask */ #undef CSIZE_SHIFT /* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ #undef HAVE_HOSTS_ALLOW_TABLE #if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE # define HAVE_HOSTS_DENY_TABLE 1 #else # undef HAVE_HOSTS_DENY_TABLE #endif /* 1..short, 3..int, 5..long; 2,4,6..unsigned */ #undef HAVE_BASIC_SIZE_T #undef HAVE_BASIC_MODE_T #undef HAVE_BASIC_PID_T #undef HAVE_BASIC_UID_T #undef HAVE_BASIC_GID_T #undef HAVE_BASIC_TIME_T #undef HAVE_BASIC_OFF_T #undef HAVE_BASIC_OFF64_T #undef HAVE_BASIC_DEV_T #undef HAVE_BASIC_SOCKLEN_T #undef HAVE_TYPEOF_ST_INO #undef HAVE_TYPEOF_ST_NLINK #undef HAVE_TYPEOF_ST_SIZE #undef HAVE_TYPEOF_ST_BLKSIZE #undef HAVE_TYPEOF_ST_BLOCKS #undef HAVE_TYPEOF_ST64_DEV #undef HAVE_TYPEOF_ST64_INO #undef HAVE_TYPEOF_ST64_NLINK #undef HAVE_TYPEOF_ST64_SIZE #undef HAVE_TYPEOF_ST64_BLKSIZE #undef HAVE_TYPEOF_ST64_BLOCKS #undef HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC #undef HAVE_TYPEOF_RLIM_MAX #undef HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN /* Define if you have the /proc filesystem */ #undef HAVE_PROC_DIR /* Define if you have the /proc/$$/fd directories */ #undef HAVE_PROC_DIR_FD #undef HAVE_SETGRENT #undef HAVE_GETGRENT #undef HAVE_ENDGRENT #undef HAVE_GETGROUPLIST #undef WITH_HELP #undef WITH_STDIO #undef WITH_FDNUM #undef WITH_FILE #undef WITH_CREAT #undef WITH_GOPEN #undef WITH_TERMIOS #undef WITH_PIPE #undef WITH_UNIX #undef WITH_ABSTRACT_UNIXSOCKET #undef WITH_IP4 #undef WITH_IP6 #undef WITH_RAWIP #undef WITH_GENERICSOCKET #undef WITH_INTERFACE #undef WITH_TCP #undef WITH_UDP #undef WITH_SCTP #undef WITH_LISTEN #undef WITH_SOCKS4 #undef WITH_SOCKS4A #undef WITH_PROXY #undef WITH_EXEC #undef WITH_SYSTEM #undef WITH_READLINE #undef WITH_TUN #undef WITH_PTY #undef WITH_EXT2 #undef WITH_OPENSSL #define WITH_STREAMS 1 #undef WITH_FIPS #undef OPENSSL_FIPS #undef WITH_LIBWRAP #undef HAVE_TCPD_H #undef HAVE_LIBWRAP #undef WITH_SYCLS #undef WITH_FILAN #undef WITH_RETRY #undef WITH_MSGLEVEL #define BUILD_DATE __DATE__ " " __TIME__ #endif /* !defined(__config_h_included) */ socat-1.7.3.1/socat.c0000644000201000020100000013040712460670272014050 0ustar gerhardgerhard/* source: socat.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the main source, including command line option parsing, general control, and the data shuffler */ #include "config.h" #include "xioconfig.h" /* what features are enabled */ #include "sysincludes.h" #include "mytypes.h" #include "compat.h" #include "error.h" #include "sycls.h" #include "sysutils.h" #include "dalan.h" #include "filan.h" #include "xio.h" #include "xioopts.h" #include "xiolockfile.h" /* command line options */ struct { size_t bufsiz; bool verbose; bool verbhex; struct timeval pollintv; /* with ignoreeof, reread after seconds */ struct timeval closwait; /* after close of x, die after seconds */ struct timeval total_timeout;/* when nothing happens, die after seconds */ bool debug; bool strictopts; /* stop on errors in address options */ char logopt; /* y..syslog; s..stderr; f..file; m..mixed */ bool lefttoright; /* first addr ro, second addr wo */ bool righttoleft; /* first addr wo, second addr ro */ xiolock_t lock; /* a lock file */ } socat_opts = { 8192, /* bufsiz */ false, /* verbose */ false, /* verbhex */ {1,0}, /* pollintv */ {0,500000}, /* closwait */ {0,0}, /* total_timeout */ 0, /* debug */ 0, /* strictopts */ 's', /* logopt */ false, /* lefttoright */ false, /* righttoleft */ { NULL, 0 }, /* lock */ }; void socat_usage(FILE *fd); void socat_version(FILE *fd); int socat(const char *address1, const char *address2); int _socat(void); int cv_newline(unsigned char **buff, ssize_t *bytes, int lineterm1, int lineterm2); void socat_signal(int sig); static int socat_sigchild(struct single *file); void lftocrlf(char **in, ssize_t *len, size_t bufsiz); void crlftolf(char **in, ssize_t *len, size_t bufsiz); static int socat_lock(void); static void socat_unlock(void); static int socat_newchild(void); static const char socatversion[] = #include "./VERSION" ; static const char timestamp[] = BUILD_DATE; const char copyright_socat[] = "socat by Gerhard Rieger - see www.dest-unreach.org"; #if WITH_OPENSSL const char copyright_openssl[] = "This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (http://www.openssl.org/)"; const char copyright_ssleay[] = "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"; #endif bool havelock; int main(int argc, const char *argv[]) { const char **arg1, *a; char *mainwaitstring; char buff[10]; double rto; int i, argc0, result; struct utsname ubuf; int lockrc; if (mainwaitstring = getenv("SOCAT_MAIN_WAIT")) { sleep(atoi(mainwaitstring)); } diag_set('p', strchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]); /* we must init before applying options because env settings have lower priority and are to be overridden by options */ if (xioinitialize() != 0) { Exit(1); } xiosetopt('p', "!!"); xiosetopt('o', ":"); argc0 = argc; /* save for later use */ arg1 = argv+1; --argc; while (arg1[0] && (arg1[0][0] == '-')) { switch (arg1[0][1]) { case 'V': socat_version(stdout); Exit(0); #if WITH_HELP case '?': case 'h': socat_usage(stdout); xioopenhelp(stdout, (arg1[0][2]=='?'||arg1[0][2]=='h') ? (arg1[0][3]=='?'||arg1[0][3]=='h') ? 2 : 1 : 0); Exit(0); #endif /* WITH_HELP */ case 'd': diag_set('d', NULL); break; #if WITH_FILAN case 'D': socat_opts.debug = true; break; #endif case 'l': switch (arg1[0][2]) { case 'm': /* mixed mode: stderr, then switch to syslog; + facility */ diag_set('s', NULL); xiosetopt('l', "m"); socat_opts.logopt = arg1[0][2]; xiosetopt('y', &arg1[0][3]); break; case 'y': /* syslog + facility */ diag_set(arg1[0][2], &arg1[0][3]); break; case 'f': /* to file, +filename */ case 'p': /* artificial program name */ if (arg1[0][3]) { diag_set(arg1[0][2], &arg1[0][3]); } else if (arg1[1]) { diag_set(arg1[0][2], arg1[1]); ++arg1, --argc; } else { Error1("option -l%c requires an argument; use option \"-h\" for help", arg1[0][2]); } break; case 's': /* stderr */ diag_set(arg1[0][2], NULL); break; case 'u': diag_set('u', NULL); break; case 'h': diag_set_int('h', true); break; default: Error1("unknown log option \"%s\"; use option \"-h\" for help", arg1[0]); break; } break; case 'v': socat_opts.verbose = true; break; case 'x': socat_opts.verbhex = true; break; case 'b': if (arg1[0][2]) { a = *arg1+2; } else { ++arg1, --argc; if ((a = *arg1) == NULL) { Error("option -b requires an argument; use option \"-h\" for help"); Exit(1); } } socat_opts.bufsiz = strtoul(a, (char **)&a, 0); break; case 's': diag_set_int('e', E_FATAL); break; case 't': if (arg1[0][2]) { a = *arg1+2; } else { ++arg1, --argc; if ((a = *arg1) == NULL) { Error("option -t requires an argument; use option \"-h\" for help"); Exit(1); } } rto = strtod(a, (char **)&a); socat_opts.closwait.tv_sec = rto; socat_opts.closwait.tv_usec = (rto-socat_opts.closwait.tv_sec) * 1000000; break; case 'T': if (arg1[0][2]) { a = *arg1+2; } else { ++arg1, --argc; if ((a = *arg1) == NULL) { Error("option -T requires an argument; use option \"-h\" for help"); Exit(1); } } rto = strtod(a, (char **)&a); socat_opts.total_timeout.tv_sec = rto; socat_opts.total_timeout.tv_usec = (rto-socat_opts.total_timeout.tv_sec) * 1000000; break; case 'u': socat_opts.lefttoright = true; break; case 'U': socat_opts.righttoleft = true; break; case 'g': xioopts_ignoregroups = true; break; case 'L': if (socat_opts.lock.lockfile) Error("only one -L and -W option allowed"); if (arg1[0][2]) { socat_opts.lock.lockfile = *arg1+2; } else { ++arg1, --argc; if ((socat_opts.lock.lockfile = *arg1) == NULL) { Error("option -L requires an argument; use option \"-h\" for help"); Exit(1); } } break; case 'W': if (socat_opts.lock.lockfile) Error("only one -L and -W option allowed"); if (arg1[0][2]) { socat_opts.lock.lockfile = *arg1+2; } else { ++arg1, --argc; if ((socat_opts.lock.lockfile = *arg1) == NULL) { Error("option -W requires an argument; use option \"-h\" for help"); Exit(1); } } socat_opts.lock.waitlock = true; socat_opts.lock.intervall.tv_sec = 1; socat_opts.lock.intervall.tv_nsec = 0; break; #if WITH_IP4 || WITH_IP6 #if WITH_IP4 case '4': #endif #if WITH_IP6 case '6': #endif xioopts.default_ip = arg1[0][1]; xioopts.preferred_ip = arg1[0][1]; break; #endif /* WITH_IP4 || WITH_IP6 */ case '\0': case ',': case ':': break; /* this "-" is a variation of STDIO */ default: xioinqopt('p', buff, sizeof(buff)); if (arg1[0][1] == buff[0]) { break; } Error1("unknown option \"%s\"; use option \"-h\" for help", arg1[0]); Exit(1); } /* the leading "-" might be a form of the first address */ xioinqopt('p', buff, sizeof(buff)); if (arg1[0][0] == '-' && (arg1[0][1] == '\0' || arg1[0][1] == ':' || arg1[0][1] == ',' || arg1[0][1] == buff[0])) break; ++arg1; --argc; } if (argc != 2) { Error1("exactly 2 addresses required (there are %d); use option \"-h\" for help", argc); Exit(1); } if (socat_opts.lefttoright && socat_opts.righttoleft) { Error("-U and -u must not be combined"); } xioinitialize2(); Info(copyright_socat); #if WITH_OPENSSL Info(copyright_openssl); Info(copyright_ssleay); #endif Debug2("socat version %s on %s", socatversion, timestamp); xiosetenv("VERSION", socatversion, 1, NULL); /* SOCAT_VERSION */ uname(&ubuf); /* ! here we circumvent internal tracing (Uname) */ Debug4("running on %s version %s, release %s, machine %s\n", ubuf.sysname, ubuf.version, ubuf.release, ubuf.machine); #if WITH_MSGLEVEL <= E_DEBUG for (i = 0; i < argc0; ++i) { Debug2("argv[%d]: \"%s\"", i, argv[i]); } #endif /* WITH_MSGLEVEL <= E_DEBUG */ { struct sigaction act; sigfillset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = socat_signal; /* not sure which signals should be cauhgt and print a message */ Sigaction(SIGHUP, &act, NULL); Sigaction(SIGINT, &act, NULL); Sigaction(SIGQUIT, &act, NULL); Sigaction(SIGILL, &act, NULL); Sigaction(SIGABRT, &act, NULL); Sigaction(SIGBUS, &act, NULL); Sigaction(SIGFPE, &act, NULL); Sigaction(SIGSEGV, &act, NULL); Sigaction(SIGTERM, &act, NULL); } Signal(SIGPIPE, SIG_IGN); /* set xio hooks */ xiohook_newchild = &socat_newchild; if (lockrc = socat_lock()) { /* =0: goon; >0: locked; <0: error, printed in sub */ if (lockrc > 0) Error1("could not obtain lock \"%s\"", socat_opts.lock.lockfile); Exit(1); } Atexit(socat_unlock); result = socat(arg1[0], arg1[1]); Notice1("exiting with status %d", result); Exit(result); return 0; /* not reached, just for gcc -Wall */ } void socat_usage(FILE *fd) { fputs(copyright_socat, fd); fputc('\n', fd); fputs("Usage:\n", fd); fputs("socat [options] \n", fd); fputs(" options:\n", fd); fputs(" -V print version and feature information to stdout, and exit\n", fd); #if WITH_HELP fputs(" -h|-? print a help text describing command line options and addresses\n", fd); fputs(" -hh like -h, plus a list of all common address option names\n", fd); fputs(" -hhh like -hh, plus a list of all available address option names\n", fd); #endif /* WITH_HELP */ fputs(" -d increase verbosity (use up to 4 times; 2 are recommended)\n", fd); #if WITH_FILAN fputs(" -D analyze file descriptors before loop\n", fd); #endif fputs(" -ly[facility] log to syslog, using facility (default is daemon)\n", fd); fputs(" -lf log to file\n", fd); fputs(" -ls log to stderr (default if no other log)\n", fd); fputs(" -lm[facility] mixed log mode (stderr during initialization, then syslog)\n", fd); fputs(" -lp set the program name used for logging\n", fd); fputs(" -lu use microseconds for logging timestamps\n", fd); fputs(" -lh add hostname to log messages\n", fd); fputs(" -v verbose data traffic, text\n", fd); fputs(" -x verbose data traffic, hexadecimal\n", fd); fputs(" -b set data buffer size (8192)\n", fd); fputs(" -s sloppy (continue on error)\n", fd); fputs(" -t wait seconds before closing second channel\n", fd); fputs(" -T total inactivity timeout in seconds\n", fd); fputs(" -u unidirectional mode (left to right)\n", fd); fputs(" -U unidirectional mode (right to left)\n", fd); fputs(" -g do not check option groups\n", fd); fputs(" -L try to obtain lock, or fail\n", fd); fputs(" -W try to obtain lock, or wait\n", fd); #if WITH_IP4 fputs(" -4 prefer IPv4 if version is not explicitly specified\n", fd); #endif #if WITH_IP6 fputs(" -6 prefer IPv6 if version is not explicitly specified\n", fd); #endif } void socat_version(FILE *fd) { struct utsname ubuf; fputs(copyright_socat, fd); fputc('\n', fd); fprintf(fd, "socat version %s on %s\n", socatversion, timestamp); Uname(&ubuf); fprintf(fd, " running on %s version %s, release %s, machine %s\n", ubuf.sysname, ubuf.version, ubuf.release, ubuf.machine); fputs("features:\n", fd); #ifdef WITH_STDIO fprintf(fd, " #define WITH_STDIO %d\n", WITH_STDIO); #else fputs(" #undef WITH_STDIO\n", fd); #endif #ifdef WITH_FDNUM fprintf(fd, " #define WITH_FDNUM %d\n", WITH_FDNUM); #else fputs(" #undef WITH_FDNUM\n", fd); #endif #ifdef WITH_FILE fprintf(fd, " #define WITH_FILE %d\n", WITH_FILE); #else fputs(" #undef WITH_FILE\n", fd); #endif #ifdef WITH_CREAT fprintf(fd, " #define WITH_CREAT %d\n", WITH_CREAT); #else fputs(" #undef WITH_CREAT\n", fd); #endif #ifdef WITH_GOPEN fprintf(fd, " #define WITH_GOPEN %d\n", WITH_GOPEN); #else fputs(" #undef WITH_GOPEN\n", fd); #endif #ifdef WITH_TERMIOS fprintf(fd, " #define WITH_TERMIOS %d\n", WITH_TERMIOS); #else fputs(" #undef WITH_TERMIOS\n", fd); #endif #ifdef WITH_PIPE fprintf(fd, " #define WITH_PIPE %d\n", WITH_PIPE); #else fputs(" #undef WITH_PIPE\n", fd); #endif #ifdef WITH_UNIX fprintf(fd, " #define WITH_UNIX %d\n", WITH_UNIX); #else fputs(" #undef WITH_UNIX\n", fd); #endif /* WITH_UNIX */ #ifdef WITH_ABSTRACT_UNIXSOCKET fprintf(fd, " #define WITH_ABSTRACT_UNIXSOCKET %d\n", WITH_ABSTRACT_UNIXSOCKET); #else fputs(" #undef WITH_ABSTRACT_UNIXSOCKET\n", fd); #endif /* WITH_ABSTRACT_UNIXSOCKET */ #ifdef WITH_IP4 fprintf(fd, " #define WITH_IP4 %d\n", WITH_IP4); #else fputs(" #undef WITH_IP4\n", fd); #endif #ifdef WITH_IP6 fprintf(fd, " #define WITH_IP6 %d\n", WITH_IP6); #else fputs(" #undef WITH_IP6\n", fd); #endif #ifdef WITH_RAWIP fprintf(fd, " #define WITH_RAWIP %d\n", WITH_RAWIP); #else fputs(" #undef WITH_RAWIP\n", fd); #endif #ifdef WITH_GENERICSOCKET fprintf(fd, " #define WITH_GENERICSOCKET %d\n", WITH_GENERICSOCKET); #else fputs(" #undef WITH_GENERICSOCKET\n", fd); #endif #ifdef WITH_INTERFACE fprintf(fd, " #define WITH_INTERFACE %d\n", WITH_INTERFACE); #else fputs(" #undef WITH_INTERFACE\n", fd); #endif #ifdef WITH_TCP fprintf(fd, " #define WITH_TCP %d\n", WITH_TCP); #else fputs(" #undef WITH_TCP\n", fd); #endif #ifdef WITH_UDP fprintf(fd, " #define WITH_UDP %d\n", WITH_UDP); #else fputs(" #undef WITH_UDP\n", fd); #endif #ifdef WITH_SCTP fprintf(fd, " #define WITH_SCTP %d\n", WITH_SCTP); #else fputs(" #undef WITH_SCTP\n", fd); #endif #ifdef WITH_LISTEN fprintf(fd, " #define WITH_LISTEN %d\n", WITH_LISTEN); #else fputs(" #undef WITH_LISTEN\n", fd); #endif #ifdef WITH_SOCKS4 fprintf(fd, " #define WITH_SOCKS4 %d\n", WITH_SOCKS4); #else fputs(" #undef WITH_SOCKS4\n", fd); #endif #ifdef WITH_SOCKS4A fprintf(fd, " #define WITH_SOCKS4A %d\n", WITH_SOCKS4A); #else fputs(" #undef WITH_SOCKS4A\n", fd); #endif #ifdef WITH_PROXY fprintf(fd, " #define WITH_PROXY %d\n", WITH_PROXY); #else fputs(" #undef WITH_PROXY\n", fd); #endif #ifdef WITH_SYSTEM fprintf(fd, " #define WITH_SYSTEM %d\n", WITH_SYSTEM); #else fputs(" #undef WITH_SYSTEM\n", fd); #endif #ifdef WITH_EXEC fprintf(fd, " #define WITH_EXEC %d\n", WITH_EXEC); #else fputs(" #undef WITH_EXEC\n", fd); #endif #ifdef WITH_READLINE fprintf(fd, " #define WITH_READLINE %d\n", WITH_READLINE); #else fputs(" #undef WITH_READLINE\n", fd); #endif #ifdef WITH_TUN fprintf(fd, " #define WITH_TUN %d\n", WITH_TUN); #else fputs(" #undef WITH_TUN\n", fd); #endif #ifdef WITH_PTY fprintf(fd, " #define WITH_PTY %d\n", WITH_PTY); #else fputs(" #undef WITH_PTY\n", fd); #endif #ifdef WITH_OPENSSL fprintf(fd, " #define WITH_OPENSSL %d\n", WITH_OPENSSL); #else fputs(" #undef WITH_OPENSSL\n", fd); #endif #ifdef WITH_FIPS fprintf(fd, " #define WITH_FIPS %d\n", WITH_FIPS); #else fputs(" #undef WITH_FIPS\n", fd); #endif #ifdef WITH_LIBWRAP fprintf(fd, " #define WITH_LIBWRAP %d\n", WITH_LIBWRAP); #else fputs(" #undef WITH_LIBWRAP\n", fd); #endif #ifdef WITH_SYCLS fprintf(fd, " #define WITH_SYCLS %d\n", WITH_SYCLS); #else fputs(" #undef WITH_SYCLS\n", fd); #endif #ifdef WITH_FILAN fprintf(fd, " #define WITH_FILAN %d\n", WITH_FILAN); #else fputs(" #undef WITH_FILAN\n", fd); #endif #ifdef WITH_RETRY fprintf(fd, " #define WITH_RETRY %d\n", WITH_RETRY); #else fputs(" #undef WITH_RETRY\n", fd); #endif #ifdef WITH_MSGLEVEL fprintf(fd, " #define WITH_MSGLEVEL %d /*%s*/\n", WITH_MSGLEVEL, &"debug\0\0\0info\0\0\0\0notice\0\0warn\0\0\0\0error\0\0\0fatal\0\0\0"[WITH_MSGLEVEL<<3]); #else fputs(" #undef WITH_MSGLEVEL\n", fd); #endif } xiofile_t *sock1, *sock2; int closing = 0; /* 0..no eof yet, 1..first eof just occurred, 2..counting down closing timeout */ /* call this function when the common command line options are parsed, and the addresses are extracted (but not resolved). */ int socat(const char *address1, const char *address2) { int mayexec; if (socat_opts.lefttoright) { if ((sock1 = xioopen(address1, XIO_RDONLY|XIO_MAYFORK|XIO_MAYCHILD|XIO_MAYCONVERT)) == NULL) { return -1; } xiosetsigchild(sock1, socat_sigchild); } else if (socat_opts.righttoleft) { if ((sock1 = xioopen(address1, XIO_WRONLY|XIO_MAYFORK|XIO_MAYCHILD|XIO_MAYCONVERT)) == NULL) { return -1; } xiosetsigchild(sock1, socat_sigchild); } else { if ((sock1 = xioopen(address1, XIO_RDWR|XIO_MAYFORK|XIO_MAYCHILD|XIO_MAYCONVERT)) == NULL) { return -1; } xiosetsigchild(sock1, socat_sigchild); } #if 1 /*! */ if (XIO_READABLE(sock1) && (XIO_RDSTREAM(sock1)->howtoend == END_KILL || XIO_RDSTREAM(sock1)->howtoend == END_CLOSE_KILL || XIO_RDSTREAM(sock1)->howtoend == END_SHUTDOWN_KILL)) { if (XIO_RDSTREAM(sock1)->para.exec.pid == diedunknown1) { /* child has alread died... but it might have put regular data into the communication channel, so continue */ Info1("child "F_pid" has already died (diedunknown1)", XIO_RDSTREAM(sock1)->para.exec.pid); diedunknown1 = 0; XIO_RDSTREAM(sock1)->para.exec.pid = 0; /* return STAT_RETRYLATER; */ } else if (XIO_RDSTREAM(sock1)->para.exec.pid == diedunknown2) { Info1("child "F_pid" has already died (diedunknown2)", XIO_RDSTREAM(sock1)->para.exec.pid); diedunknown2 = 0; XIO_RDSTREAM(sock1)->para.exec.pid = 0; } else if (XIO_RDSTREAM(sock1)->para.exec.pid == diedunknown3) { Info1("child "F_pid" has already died (diedunknown3)", XIO_RDSTREAM(sock1)->para.exec.pid); diedunknown3 = 0; XIO_RDSTREAM(sock1)->para.exec.pid = 0; } else if (XIO_RDSTREAM(sock1)->para.exec.pid == diedunknown4) { Info1("child "F_pid" has already died (diedunknown4)", XIO_RDSTREAM(sock1)->para.exec.pid); diedunknown4 = 0; XIO_RDSTREAM(sock1)->para.exec.pid = 0; } } #endif mayexec = (sock1->common.flags&XIO_DOESCONVERT ? 0 : XIO_MAYEXEC); if (XIO_WRITABLE(sock1)) { if (XIO_READABLE(sock1)) { if ((sock2 = xioopen(address2, XIO_RDWR|XIO_MAYFORK|XIO_MAYCHILD|mayexec|XIO_MAYCONVERT)) == NULL) { return -1; } xiosetsigchild(sock2, socat_sigchild); } else { if ((sock2 = xioopen(address2, XIO_RDONLY|XIO_MAYFORK|XIO_MAYCHILD|mayexec|XIO_MAYCONVERT)) == NULL) { return -1; } xiosetsigchild(sock2, socat_sigchild); } } else { /* assuming sock1 is readable */ if ((sock2 = xioopen(address2, XIO_WRONLY|XIO_MAYFORK|XIO_MAYCHILD|mayexec|XIO_MAYCONVERT)) == NULL) { return -1; } xiosetsigchild(sock2, socat_sigchild); } #if 1 /*! */ if (XIO_READABLE(sock2) && (XIO_RDSTREAM(sock2)->howtoend == END_KILL || XIO_RDSTREAM(sock2)->howtoend == END_CLOSE_KILL || XIO_RDSTREAM(sock2)->howtoend == END_SHUTDOWN_KILL)) { if (XIO_RDSTREAM(sock2)->para.exec.pid == diedunknown1) { /* child has alread died... but it might have put regular data into the communication channel, so continue */ Info1("child "F_pid" has already died (diedunknown1)", XIO_RDSTREAM(sock2)->para.exec.pid); diedunknown1 = 0; XIO_RDSTREAM(sock2)->para.exec.pid = 0; /* return STAT_RETRYLATER; */ } else if (XIO_RDSTREAM(sock2)->para.exec.pid == diedunknown2) { Info1("child "F_pid" has already died (diedunknown2)", XIO_RDSTREAM(sock2)->para.exec.pid); diedunknown2 = 0; XIO_RDSTREAM(sock2)->para.exec.pid = 0; } else if (XIO_RDSTREAM(sock2)->para.exec.pid == diedunknown3) { Info1("child "F_pid" has already died (diedunknown3)", XIO_RDSTREAM(sock2)->para.exec.pid); diedunknown3 = 0; XIO_RDSTREAM(sock2)->para.exec.pid = 0; } else if (XIO_RDSTREAM(sock2)->para.exec.pid == diedunknown4) { Info1("child "F_pid" has already died (diedunknown4)", XIO_RDSTREAM(sock2)->para.exec.pid); diedunknown4 = 0; XIO_RDSTREAM(sock2)->para.exec.pid = 0; } } #endif Info("resolved and opened all sock addresses"); return _socat(); /* nsocks, sockets are visible outside function */ } /* checks if this is a connection to a child process, and if so, sees if the child already died, leaving some data for us. returns <0 if an error occurred; returns 0 if no child or not yet died or died without data (sets eof); returns >0 if child died and left data */ int childleftdata(xiofile_t *xfd) { struct pollfd in; int retval; /* have to check if a child process died before, but left read data */ if (XIO_READABLE(xfd) && (XIO_RDSTREAM(xfd)->howtoend == END_KILL || XIO_RDSTREAM(xfd)->howtoend == END_CLOSE_KILL || XIO_RDSTREAM(xfd)->howtoend == END_SHUTDOWN_KILL) && XIO_RDSTREAM(xfd)->para.exec.pid == 0) { struct timeval timeout = { 0, 0 }; if (XIO_READABLE(xfd) && !(XIO_RDSTREAM(xfd)->eof >= 2 && !XIO_RDSTREAM(xfd)->ignoreeof)) { in.fd = XIO_GETRDFD(xfd); in.events = POLLIN/*|POLLRDBAND*/; in.revents = 0; } do { int _errno; retval = xiopoll(&in, 1, &timeout); _errno = errno; diag_flush(); errno = _errno; /* just in case it's not debug level and Msg() not been called */ } while (retval < 0 && errno == EINTR); if (retval < 0) { Error5("xiopoll({%d,%0o}, 1, {"F_tv_sec"."F_tv_usec"}): %s", in.fd, in.events, timeout.tv_sec, timeout.tv_usec, strerror(errno)); return -1; } if (retval == 0) { Info("terminated child did not leave data for us"); XIO_RDSTREAM(xfd)->eof = 2; xfd->stream.eof = 2; closing = MAX(closing, 1); } } return 0; } int xiotransfer(xiofile_t *inpipe, xiofile_t *outpipe, unsigned char **buff, size_t bufsiz, bool righttoleft); bool mayrd1; /* sock1 has read data or eof, according to poll() */ bool mayrd2; /* sock2 has read data or eof, according to poll() */ bool maywr1; /* sock1 can be written to, according to poll() */ bool maywr2; /* sock2 can be written to, according to poll() */ /* here we come when the sockets are opened (in the meaning of C language), and their options are set/applied returns -1 on error or 0 on success */ int _socat(void) { struct pollfd fds[4], *fd1in = &fds[0], *fd1out = &fds[1], *fd2in = &fds[2], *fd2out = &fds[3]; int retval; unsigned char *buff; ssize_t bytes1, bytes2; int polling = 0; /* handling ignoreeof */ int wasaction = 1; /* last poll was active, do NOT sleep before next */ struct timeval total_timeout; /* the actual total timeout timer */ #if WITH_FILAN if (socat_opts.debug) { int fdi, fdo; int msglevel, exitlevel; msglevel = diag_get_int('D'); /* save current message level */ diag_set_int('D', E_ERROR); /* only print errors and fatals in filan */ exitlevel = diag_get_int('e'); /* save current exit level */ diag_set_int('e', E_FATAL); /* only exit on fatals */ fdi = XIO_GETRDFD(sock1); fdo = XIO_GETWRFD(sock1); filan_fd(fdi, stderr); if (fdo != fdi) { filan_fd(fdo, stderr); } fdi = XIO_GETRDFD(sock2); fdo = XIO_GETWRFD(sock2); filan_fd(fdi, stderr); if (fdo != fdi) { filan_fd(fdo, stderr); } diag_set_int('e', exitlevel); /* restore old exit level */ diag_set_int('D', msglevel); /* restore old message level */ } #endif /* WITH_FILAN */ /* when converting nl to crnl, size might double */ buff = Malloc(2*socat_opts.bufsiz+1); if (buff == NULL) return -1; if (socat_opts.logopt == 'm' && xioinqopt('l', NULL, 0) == 'm') { Info("switching to syslog"); diag_set('y', xioopts.syslogfac); xiosetopt('l', "\0"); } total_timeout = socat_opts.total_timeout; Notice4("starting data transfer loop with FDs [%d,%d] and [%d,%d]", XIO_GETRDFD(sock1), XIO_GETWRFD(sock1), XIO_GETRDFD(sock2), XIO_GETWRFD(sock2)); while (XIO_RDSTREAM(sock1)->eof <= 1 || XIO_RDSTREAM(sock2)->eof <= 1) { struct timeval timeout, *to = NULL; Debug6("data loop: sock1->eof=%d, sock2->eof=%d, closing=%d, wasaction=%d, total_to={"F_tv_sec"."F_tv_usec"}", XIO_RDSTREAM(sock1)->eof, XIO_RDSTREAM(sock2)->eof, closing, wasaction, total_timeout.tv_sec, total_timeout.tv_usec); /* for ignoreeof */ if (polling) { if (!wasaction) { if (socat_opts.total_timeout.tv_sec != 0 || socat_opts.total_timeout.tv_usec != 0) { if (total_timeout.tv_usec < socat_opts.pollintv.tv_usec) { total_timeout.tv_usec += 1000000; total_timeout.tv_sec -= 1; } total_timeout.tv_sec -= socat_opts.pollintv.tv_sec; total_timeout.tv_usec -= socat_opts.pollintv.tv_usec; if (total_timeout.tv_sec < 0 || total_timeout.tv_sec == 0 && total_timeout.tv_usec < 0) { Notice("inactivity timeout triggered"); free(buff); return 0; } } } else { wasaction = 0; } } if (polling) { /* there is a ignoreeof poll timeout, use it */ timeout = socat_opts.pollintv; to = &timeout; } else if (socat_opts.total_timeout.tv_sec != 0 || socat_opts.total_timeout.tv_usec != 0) { /* there might occur a total inactivity timeout */ timeout = socat_opts.total_timeout; to = &timeout; } else { to = NULL; } if (closing>=1) { /* first eof already occurred, start end timer */ timeout = socat_opts.pollintv; to = &timeout; closing = 2; } /* frame 1: set the poll parameters and loop over poll() EINTR) */ do { /* loop over poll() EINTR */ int _errno; childleftdata(sock1); childleftdata(sock2); if (closing>=1) { /* first eof already occurred, start end timer */ timeout = socat_opts.closwait; to = &timeout; closing = 2; } /* use the ignoreeof timeout if appropriate */ if (polling) { if (closing == 0 || (socat_opts.pollintv.tv_sec < timeout.tv_sec) || ((socat_opts.pollintv.tv_sec == timeout.tv_sec) && socat_opts.pollintv.tv_usec < timeout.tv_usec)) { timeout = socat_opts.pollintv; } } /* now the fds will be assigned */ if (XIO_READABLE(sock1) && !(XIO_RDSTREAM(sock1)->eof > 1 && !XIO_RDSTREAM(sock1)->ignoreeof) && !socat_opts.righttoleft) { if (!mayrd1 && !(XIO_RDSTREAM(sock1)->eof > 1)) { fd1in->fd = XIO_GETRDFD(sock1); fd1in->events = POLLIN; } else { fd1in->fd = -1; } if (!maywr2) { fd2out->fd = XIO_GETWRFD(sock2); fd2out->events = POLLOUT; } else { fd2out->fd = -1; } } else { fd1in->fd = -1; fd2out->fd = -1; } if (XIO_READABLE(sock2) && !(XIO_RDSTREAM(sock2)->eof > 1 && !XIO_RDSTREAM(sock2)->ignoreeof) && !socat_opts.lefttoright) { if (!mayrd2 && !(XIO_RDSTREAM(sock2)->eof > 1)) { fd2in->fd = XIO_GETRDFD(sock2); fd2in->events = POLLIN; } else { fd2in->fd = -1; } if (!maywr1) { fd1out->fd = XIO_GETWRFD(sock1); fd1out->events = POLLOUT; } else { fd1out->fd = -1; } } else { fd1out->fd = -1; fd2in->fd = -1; } /* frame 0: innermost part of the transfer loop: check FD status */ retval = xiopoll(fds, 4, to); if (retval >= 0 || errno != EINTR) { break; } _errno = errno; Info1("poll(): %s", strerror(errno)); errno = _errno; } while (true); /* attention: when an exec'd process sends data and terminates, it is unpredictable whether the data or the sigchild arrives first. */ if (retval < 0) { Error11("xiopoll({%d,%0o}{%d,%0o}{%d,%0o}{%d,%0o}, 4, {"F_tv_sec"."F_tv_usec"}): %s", fds[0].fd, fds[0].events, fds[1].fd, fds[1].events, fds[2].fd, fds[2].events, fds[3].fd, fds[3].events, timeout.tv_sec, timeout.tv_usec, strerror(errno)); free(buff); return -1; } else if (retval == 0) { Info2("poll timed out (no data within %ld.%06ld seconds)", closing>=1?socat_opts.closwait.tv_sec:socat_opts.total_timeout.tv_sec, closing>=1?socat_opts.closwait.tv_usec:socat_opts.total_timeout.tv_usec); if (polling && !wasaction) { /* there was a ignoreeof poll timeout, use it */ polling = 0; /*%%%*/ if (XIO_RDSTREAM(sock1)->ignoreeof) { mayrd1 = 0; } if (XIO_RDSTREAM(sock2)->ignoreeof) { mayrd2 = 0; } } else if (polling && wasaction) { wasaction = 0; } else if (socat_opts.total_timeout.tv_sec != 0 || socat_opts.total_timeout.tv_usec != 0) { /* there was a total inactivity timeout */ Notice("inactivity timeout triggered"); free(buff); return 0; } if (closing) { break; } /* one possibility to come here is ignoreeof on some fd, but no EOF and no data on any descriptor - this is no indication for end! */ continue; } if (XIO_READABLE(sock1) && XIO_GETRDFD(sock1) >= 0 && (fd1in->revents /*&(POLLIN|POLLHUP|POLLERR)*/)) { if (fd1in->revents & POLLNVAL) { /* this is what we find on Mac OS X when poll()'ing on a device or named pipe. a read() might imm. return with 0 bytes, resulting in a loop? */ Error1("poll(...[%d]: invalid request", fd1in->fd); free(buff); return -1; } mayrd1 = true; } if (XIO_READABLE(sock2) && XIO_GETRDFD(sock2) >= 0 && (fd2in->revents)) { if (fd2in->revents & POLLNVAL) { Error1("poll(...[%d]: invalid request", fd2in->fd); free(buff); return -1; } mayrd2 = true; } if (XIO_GETWRFD(sock1) >= 0 && fd1out->fd >= 0 && fd1out->revents) { if (fd1out->revents & POLLNVAL) { Error1("poll(...[%d]: invalid request", fd1out->fd); free(buff); return -1; } maywr1 = true; } if (XIO_GETWRFD(sock2) >= 0 && fd2out->fd >= 0 && fd2out->revents) { if (fd2out->revents & POLLNVAL) { Error1("poll(...[%d]: invalid request", fd2out->fd); free(buff); return -1; } maywr2 = true; } if (mayrd1 && maywr2) { mayrd1 = false; if ((bytes1 = xiotransfer(sock1, sock2, &buff, socat_opts.bufsiz, false)) < 0) { if (errno != EAGAIN) { closing = MAX(closing, 1); Notice("socket 1 to socket 2 is in error"); if (socat_opts.lefttoright) { break; } } } else if (bytes1 > 0) { maywr2 = false; total_timeout = socat_opts.total_timeout; wasaction = 1; /* is more data available that has already passed poll()? */ mayrd1 = (xiopending(sock1) > 0); if (XIO_RDSTREAM(sock1)->readbytes != 0 && XIO_RDSTREAM(sock1)->actbytes == 0) { /* avoid idle when all readbytes already there */ mayrd1 = true; } /* escape char occurred? */ if (XIO_RDSTREAM(sock1)->actescape) { bytes1 = 0; /* indicate EOF */ } } /* (bytes1 == 0) handled later */ } else { bytes1 = -1; } if (mayrd2 && maywr1) { mayrd2 = false; if ((bytes2 = xiotransfer(sock2, sock1, &buff, socat_opts.bufsiz, true)) < 0) { if (errno != EAGAIN) { closing = MAX(closing, 1); Notice("socket 2 to socket 1 is in error"); if (socat_opts.righttoleft) { break; } } } else if (bytes2 > 0) { maywr1 = false; total_timeout = socat_opts.total_timeout; wasaction = 1; /* is more data available that has already passed poll()? */ mayrd2 = (xiopending(sock2) > 0); if (XIO_RDSTREAM(sock2)->readbytes != 0 && XIO_RDSTREAM(sock2)->actbytes == 0) { /* avoid idle when all readbytes already there */ mayrd2 = true; } /* escape char occurred? */ if (XIO_RDSTREAM(sock2)->actescape) { bytes2 = 0; /* indicate EOF */ } } /* (bytes2 == 0) handled later */ } else { bytes2 = -1; } /* NOW handle EOFs */ /*0 Debug4("bytes1=F_Zd, XIO_RDSTREAM(sock1)->eof=%d, XIO_RDSTREAM(sock1)->ignoreeof=%d, closing=%d", bytes1, XIO_RDSTREAM(sock1)->eof, XIO_RDSTREAM(sock1)->ignoreeof, closing);*/ if (bytes1 == 0 || XIO_RDSTREAM(sock1)->eof >= 2) { if (XIO_RDSTREAM(sock1)->ignoreeof && !XIO_RDSTREAM(sock1)->actescape && !closing) { Debug1("socket 1 (fd %d) is at EOF, ignoring", XIO_RDSTREAM(sock1)->fd); /*! */ mayrd1 = true; polling = 1; /* do not hook this eof fd to poll for pollintv*/ } else { Notice1("socket 1 (fd %d) is at EOF", XIO_GETRDFD(sock1)); xioshutdown(sock2, SHUT_WR); XIO_RDSTREAM(sock1)->eof = 2; XIO_RDSTREAM(sock1)->ignoreeof = false; } } else if (polling && XIO_RDSTREAM(sock1)->ignoreeof) { polling = 0; } if (XIO_RDSTREAM(sock1)->eof >= 2) { if (socat_opts.lefttoright) { break; } closing = 1; } if (bytes2 == 0 || XIO_RDSTREAM(sock2)->eof >= 2) { if (XIO_RDSTREAM(sock2)->ignoreeof && !XIO_RDSTREAM(sock2)->actescape && !closing) { Debug1("socket 2 (fd %d) is at EOF, ignoring", XIO_RDSTREAM(sock2)->fd); mayrd2 = true; polling = 1; /* do not hook this eof fd to poll for pollintv*/ } else { Notice1("socket 2 (fd %d) is at EOF", XIO_GETRDFD(sock2)); xioshutdown(sock1, SHUT_WR); XIO_RDSTREAM(sock2)->eof = 2; XIO_RDSTREAM(sock2)->ignoreeof = false; } } else if (polling && XIO_RDSTREAM(sock2)->ignoreeof) { polling = 0; } if (XIO_RDSTREAM(sock2)->eof >= 2) { if (socat_opts.righttoleft) { break; } closing = 1; } } /* close everything that's still open */ xioclose(sock1); xioclose(sock2); free(buff); return 0; } #define MAXTIMESTAMPLEN 128 /* prints the timestamp to the buffer and terminates it with '\0'. This buffer should be at least MAXTIMESTAMPLEN bytes long. returns 0 on success or -1 if an error occurred */ int gettimestamp(char *timestamp) { size_t bytes; #if HAVE_GETTIMEOFDAY || 1 struct timeval now; int result; time_t nowt; #else /* !HAVE_GETTIMEOFDAY */ time_t now; #endif /* !HAVE_GETTIMEOFDAY */ #if HAVE_GETTIMEOFDAY || 1 result = gettimeofday(&now, NULL); if (result < 0) { return result; } else { nowt = now.tv_sec; #if HAVE_STRFTIME bytes = strftime(timestamp, 20, "%Y/%m/%d %H:%M:%S", localtime(&nowt)); bytes += sprintf(timestamp+19, "."F_tv_usec" ", now.tv_usec); #else strcpy(timestamp, ctime(&nowt)); bytes = strlen(timestamp); #endif } #else /* !HAVE_GETTIMEOFDAY */ now = time(NULL); if (now == (time_t)-1) { return -1; } else { #if HAVE_STRFTIME bytes = strftime(timestamp, 21, "%Y/%m/%d %H:%M:%S ", localtime(&now)); #else strcpy(timestamp, ctime(&now)); bytes = strlen(timestamp); #endif } #endif /* !HAVE_GETTIMEOFDAY */ return 0; } static const char *prefixltor = "> "; static const char *prefixrtol = "< "; static unsigned long numltor; static unsigned long numrtol; /* print block header (during verbose or hex dump) returns 0 on success or -1 if an error occurred */ static int xioprintblockheader(FILE *file, size_t bytes, bool righttoleft) { char timestamp[MAXTIMESTAMPLEN]; char buff[128+MAXTIMESTAMPLEN]; if (gettimestamp(timestamp) < 0) { return -1; } if (righttoleft) { sprintf(buff, "%s%s length="F_Zu" from=%lu to=%lu\n", prefixrtol, timestamp, bytes, numrtol, numrtol+bytes-1); numrtol+=bytes; } else { sprintf(buff, "%s%s length="F_Zu" from=%lu to=%lu\n", prefixltor, timestamp, bytes, numltor, numltor+bytes-1); numltor+=bytes; } fputs(buff, file); return 0; } /* inpipe is suspected to have read data available; read at most bufsiz bytes and transfer them to outpipe. Perform required data conversions. buff must be a malloc()'ed storage and might be realloc()'ed in this function if more space is required after conversions. Returns the number of bytes written, or 0 on EOF or <0 if an error occurred or when data was read but none written due to conversions (with EAGAIN). EAGAIN also occurs when reading from a nonblocking FD where the file has a mandatory lock. If 0 bytes were read (EOF), it does NOT shutdown or close a channel, and it does NOT write a zero bytes block. */ /* inpipe, outpipe must be single descriptors (not dual!) */ int xiotransfer(xiofile_t *inpipe, xiofile_t *outpipe, unsigned char **buff, size_t bufsiz, bool righttoleft) { ssize_t bytes, writt = 0; bytes = xioread(inpipe, *buff, bufsiz); if (bytes < 0) { if (errno != EAGAIN) XIO_RDSTREAM(inpipe)->eof = 2; /*xioshutdown(inpipe, SHUT_RD);*/ return -1; } if (bytes == 0 && XIO_RDSTREAM(inpipe)->ignoreeof && !closing) { ; } else if (bytes == 0) { XIO_RDSTREAM(inpipe)->eof = 2; closing = MAX(closing, 1); } if (bytes > 0) { /* handle escape char */ if (XIO_RDSTREAM(inpipe)->escape != -1) { /* check input data for escape char */ unsigned char *ptr = *buff; size_t ctr = 0; while (ctr < bytes) { if (*ptr == XIO_RDSTREAM(inpipe)->escape) { /* found: set flag, truncate input data */ XIO_RDSTREAM(inpipe)->actescape = true; bytes = ctr; Info("escape char found in input"); break; } ++ptr; ++ctr; } if (ctr != bytes) { XIO_RDSTREAM(inpipe)->eof = 2; } } } if (bytes > 0) { if (XIO_RDSTREAM(inpipe)->lineterm != XIO_WRSTREAM(outpipe)->lineterm) { cv_newline(buff, &bytes, XIO_RDSTREAM(inpipe)->lineterm, XIO_WRSTREAM(outpipe)->lineterm); } if (bytes == 0) { errno = EAGAIN; return -1; } if (socat_opts.verbose && socat_opts.verbhex) { /* Hack-o-rama */ size_t i = 0; size_t j; size_t N = 16; const unsigned char *end, *s, *t; s = *buff; end = (*buff)+bytes; xioprintblockheader(stderr, bytes, righttoleft); while (s < end) { /*! prefix? */ j = Min(N, (size_t)(end-s)); /* print hex */ t = s; i = 0; while (i < j) { int c = *t++; fprintf(stderr, " %02x", c); ++i; if (c == '\n') break; } /* fill hex column */ while (i < N) { fputs(" ", stderr); ++i; } fputs(" ", stderr); /* print acsii */ t = s; i = 0; while (i < j) { int c = *t++; if (c == '\n') { fputc('.', stderr); break; } if (!isprint(c)) c = '.'; fputc(c, stderr); ++i; } fputc('\n', stderr); s = t; } fputs("--\n", stderr); } else if (socat_opts.verbose) { size_t i = 0; xioprintblockheader(stderr, bytes, righttoleft); while (i < (size_t)bytes) { int c = (*buff)[i]; if (i > 0 && (*buff)[i-1] == '\n') /*! prefix? */; switch (c) { case '\a' : fputs("\\a", stderr); break; case '\b' : fputs("\\b", stderr); break; case '\t' : fputs("\t", stderr); break; case '\n' : fputs("\n", stderr); break; case '\v' : fputs("\\v", stderr); break; case '\f' : fputs("\\f", stderr); break; case '\r' : fputs("\\r", stderr); break; case '\\' : fputs("\\\\", stderr); break; default: if (!isprint(c)) c = '.'; fputc(c, stderr); break; } ++i; } } else if (socat_opts.verbhex) { int i; /* print prefix */ xioprintblockheader(stderr, bytes, righttoleft); for (i = 0; i < bytes; ++i) { fprintf(stderr, " %02x", (*buff)[i]); } fputc('\n', stderr); } writt = xiowrite(outpipe, *buff, bytes); if (writt < 0) { /* EAGAIN when nonblocking but a mandatory lock is on file. the problem with EAGAIN is that the read cannot be repeated, so we need to buffer the data and try to write it later again. not yet implemented, sorry. */ #if 0 if (errno == EPIPE) { return 0; /* can no longer write; handle like EOF */ } #endif return -1; } else { Info3("transferred "F_Zu" bytes from %d to %d", writt, XIO_GETRDFD(inpipe), XIO_GETWRFD(outpipe)); } } return writt; } #define CR '\r' #define LF '\n' /* converts the newline characters (or character sequences) from the one specified in lineterm1 to that of lineterm2. Possible values are LINETERM_CR, LINETERM_CRNL, LINETERM_RAW. buff points to the malloc()'ed data, input and output. It may be subject to realloc(). bytes specifies the number of bytes input and output */ int cv_newline(unsigned char **buff, ssize_t *bufsiz, int lineterm1, int lineterm2) { ssize_t *bytes = bufsiz; /* must perform newline changes */ if (lineterm1 <= LINETERM_CR && lineterm2 <= LINETERM_CR) { /* no change in data length */ unsigned char from, to, *p, *z; if (lineterm1 == LINETERM_RAW) { from = '\n'; to = '\r'; } else { from = '\r'; to = '\n'; } z = *buff + *bytes; p = *buff; while (p < z) { if (*p == from) *p = to; ++p; } } else if (lineterm1 == LINETERM_CRNL) { /* buffer becomes shorter */ unsigned char to, *s, *t, *z; if (lineterm2 == LINETERM_RAW) { to = '\n'; } else { to = '\r'; } z = *buff + *bytes; s = t = *buff; while (s < z) { if (*s == '\r') { ++s; continue; } if (*s == '\n') { *t++ = to; ++s; } else { *t++ = *s++; } } *bufsiz = t - *buff; } else { /* buffer becomes longer, must alloc another space */ unsigned char *buf2; unsigned char from; unsigned char *s, *t, *z; if (lineterm1 == LINETERM_RAW) { from = '\n'; } else { from = '\r'; } if ((buf2 = Malloc(2*socat_opts.bufsiz/*sic!*/+1)) == NULL) { return -1; } s = *buff; t = buf2; z = *buff + *bytes; while (s < z) { if (*s == from) { *t++ = '\r'; *t++ = '\n'; ++s; continue; } else { *t++ = *s++; } } free(*buff); *buff = buf2; *bufsiz = t - buf2;; } return 0; } void socat_signal(int signum) { int _errno; _errno = errno; diag_in_handler = 1; Notice1("socat_signal(): handling signal %d", signum); switch (signum) { case SIGQUIT: case SIGILL: case SIGABRT: case SIGBUS: case SIGFPE: case SIGSEGV: case SIGPIPE: diag_set_int('x', 128+signum); /* in case Error exits for us */ Error1("exiting on signal %d", signum); diag_set_int('x', 0); /* in case Error did not exit */ break; case SIGTERM: Warn1("exiting on signal %d", signum); break; case SIGHUP: case SIGINT: Notice1("exiting on signal %d", signum); break; } //Exit(128+signum); Notice1("socat_signal(): finishing signal %d", signum); diag_exit(128+signum); /*!!! internal cleanup + _exit() */ diag_in_handler = 0; errno = _errno; } /* this is the callback when the child of an address died */ static int socat_sigchild(struct single *file) { if (file->ignoreeof && !closing) { ; } else { file->eof = MAX(file->eof, 1); closing = 1; } return 0; } static int socat_lock(void) { int lockrc; #if 1 if ((lockrc = xiolock(&socat_opts.lock)) < 0) { return -1; } if (lockrc == 0) { havelock = true; } return lockrc; #else if (socat_opts.lock.lockfile) { if ((lockrc = xiolock(socat_opts.lock.lockfile)) < 0) { /*Error1("error with lockfile \"%s\"", socat_opts.lock.lockfile);*/ return -1; } if (lockrc) { return 1; } havelock = true; /*0 Info1("obtained lock \"%s\"", socat_opts.lock.lockfile);*/ } if (socat_opts.lock.waitlock) { if (xiowaitlock(socat_opts.lock.waitlock, socat_opts.lock.intervall)) { /*Error1("error with lockfile \"%s\"", socat_opts.lock.lockfile);*/ return -1; } else { havelock = true; /*0 Info1("obtained lock \"%s\"", socat_opts.lock.waitlock);*/ } } return 0; #endif } static void socat_unlock(void) { if (!havelock) return; if (socat_opts.lock.lockfile) { if (Unlink(socat_opts.lock.lockfile) < 0) { if (!diag_in_handler) { Warn2("unlink(\"%s\"): %s", socat_opts.lock.lockfile, strerror(errno)); } else { Warn1("unlink(\"%s\"): "F_strerror, socat_opts.lock.lockfile); } } else { Info1("released lock \"%s\"", socat_opts.lock.lockfile); } } } /* this is a callback function that may be called by the newchild hook of xio */ static int socat_newchild(void) { havelock = false; return 0; } socat-1.7.3.1/xiosysincludes.h0000644000201000020100000000056311632611226016022 0ustar gerhardgerhard/* source: xiosysincludes.h */ /* Copyright Gerhard Rieger 2001 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xiosysincludes_h_included #define __xiosysincludes_h_included 1 #include "config.h" #include "xioconfig.h" /* what features are enabled */ #include "sysincludes.h" #endif /* !defined(__xiosysincludes_h_included) */ socat-1.7.3.1/xio-sctp.c0000644000201000020100000000517011453022152014470 0ustar gerhardgerhard/* source: xio-sctp.c */ /* Copyright Gerhard Rieger 2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for SCTP related functions and options */ #include "xiosysincludes.h" #if WITH_SCTP #include "xioopen.h" #include "xio-listen.h" #include "xio-ip4.h" #include "xio-ipapp.h" #include "xio-sctp.h" /****** SCTP addresses ******/ #if WITH_IP4 || WITH_IP6 const struct addrdesc addr_sctp_connect = { "sctp-connect", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_SCTP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_UNSPEC HELP("::") }; #if WITH_LISTEN const struct addrdesc addr_sctp_listen = { "sctp-listen", 1+XIO_RDWR, xioopen_ipapp_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_SCTP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_UNSPEC HELP(":") }; #endif #endif #if WITH_IP4 const struct addrdesc addr_sctp4_connect = { "sctp4-connect", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_SCTP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_INET HELP("::") }; #if WITH_LISTEN const struct addrdesc addr_sctp4_listen = { "sctp4-listen", 1+XIO_RDWR, xioopen_ipapp_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_SCTP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_INET HELP(":") }; #endif #endif /* WITH_IP4 */ #if WITH_IP6 const struct addrdesc addr_sctp6_connect = { "sctp6-connect", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_SCTP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_INET6 HELP("::") }; #if WITH_LISTEN const struct addrdesc addr_sctp6_listen = { "sctp6-listen", 1+XIO_RDWR, xioopen_ipapp_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_SCTP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_INET6 HELP(":") }; #endif #endif /* WITH_IP6 */ /****** SCTP address options ******/ #ifdef SCTP_NODELAY const struct optdesc opt_sctp_nodelay = { "sctp-nodelay", "nodelay", OPT_SCTP_NODELAY, GROUP_IP_SCTP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SCTP, SCTP_NODELAY }; #endif #ifdef SCTP_MAXSEG const struct optdesc opt_sctp_maxseg = { "sctp-maxseg", "mss", OPT_SCTP_MAXSEG, GROUP_IP_SCTP, PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_SCTP, SCTP_MAXSEG }; const struct optdesc opt_sctp_maxseg_late={"sctp-maxseg-late","mss-late",OPT_SCTP_MAXSEG_LATE,GROUP_IP_SCTP,PH_CONNECTED,TYPE_INT,OFUNC_SOCKOPT, SOL_SCTP, SCTP_MAXSEG}; #endif #endif /* WITH_SCTP */ socat-1.7.3.1/xio-tcp.c0000644000201000020100000001621012455410434014311 0ustar gerhardgerhard/* source: xio-tcp.c */ /* Copyright Gerhard Rieger 2001-2006 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for TCP related functions and options */ #include "xiosysincludes.h" #if WITH_TCP #include "xioopen.h" #include "xio-listen.h" #include "xio-ip4.h" #include "xio-ipapp.h" #include "xio-tcp.h" /****** TCP addresses ******/ #if WITH_IP4 || WITH_IP6 const struct addrdesc addr_tcp_connect = { "tcp-connect", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_TCP, PF_UNSPEC HELP("::") }; #if WITH_LISTEN const struct addrdesc addr_tcp_listen = { "tcp-listen", 1+XIO_RDWR, xioopen_ipapp_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_TCP, PF_UNSPEC HELP(":") }; #endif #endif #if WITH_IP4 const struct addrdesc addr_tcp4_connect = { "tcp4-connect", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_TCP, PF_INET HELP("::") }; #if WITH_LISTEN const struct addrdesc addr_tcp4_listen = { "tcp4-listen", 1+XIO_RDWR, xioopen_ipapp_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_TCP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_TCP, PF_INET HELP(":") }; #endif #endif /* WITH_IP4 */ #if WITH_IP6 const struct addrdesc addr_tcp6_connect = { "tcp6-connect", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_TCP, PF_INET6 HELP("::") }; #if WITH_LISTEN const struct addrdesc addr_tcp6_listen = { "tcp6-listen", 1+XIO_RDWR, xioopen_ipapp_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_TCP, PF_INET6 HELP(":") }; #endif #endif /* WITH_IP6 */ /****** TCP address options ******/ #ifdef TCP_NODELAY const struct optdesc opt_tcp_nodelay = { "tcp-nodelay", "nodelay", OPT_TCP_NODELAY, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_NODELAY }; #endif #ifdef TCP_MAXSEG const struct optdesc opt_tcp_maxseg = { "tcp-maxseg", "mss", OPT_TCP_MAXSEG, GROUP_IP_TCP, PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_MAXSEG }; const struct optdesc opt_tcp_maxseg_late={"tcp-maxseg-late","mss-late",OPT_TCP_MAXSEG_LATE,GROUP_IP_TCP,PH_CONNECTED,TYPE_INT,OFUNC_SOCKOPT, SOL_TCP, TCP_MAXSEG}; #endif #ifdef TCP_CORK const struct optdesc opt_tcp_cork = { "tcp-cork", "cork", OPT_TCP_CORK, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_CORK }; #endif #ifdef TCP_STDURG const struct optdesc opt_tcp_stdurg = { "tcp-stdurg", "stdurg", OPT_TCP_STDURG, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_STDURG }; #endif #ifdef TCP_RFC1323 const struct optdesc opt_tcp_rfc1323= { "tcp-rfc1323", "rfc1323", OPT_TCP_RFC1323, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_RFC1323}; #endif #ifdef TCP_KEEPIDLE const struct optdesc opt_tcp_keepidle={ "tcp-keepidle", "keepidle",OPT_TCP_KEEPIDLE,GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP,TCP_KEEPIDLE}; #endif #ifdef TCP_KEEPINTVL const struct optdesc opt_tcp_keepintvl={"tcp-keepintvl","keepintvl",OPT_TCP_KEEPINTVL,GROUP_IP_TCP,PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP,TCP_KEEPINTVL}; #endif #ifdef TCP_KEEPCNT const struct optdesc opt_tcp_keepcnt= { "tcp-keepcnt", "keepcnt", OPT_TCP_KEEPCNT, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_KEEPCNT }; #endif #ifdef TCP_SYNCNT const struct optdesc opt_tcp_syncnt = { "tcp-syncnt", "syncnt", OPT_TCP_SYNCNT, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_SYNCNT }; #endif #ifdef TCP_LINGER2 const struct optdesc opt_tcp_linger2= { "tcp-linger2", "linger2", OPT_TCP_LINGER2, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_LINGER2 }; #endif #ifdef TCP_DEFER_ACCEPT const struct optdesc opt_tcp_defer_accept={"tcp-defer-accept","defer-accept",OPT_TCP_DEFER_ACCEPT,GROUP_IP_TCP,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_TCP,TCP_DEFER_ACCEPT }; #endif #ifdef TCP_WINDOW_CLAMP const struct optdesc opt_tcp_window_clamp={"tcp-window-clamp","window-clamp",OPT_TCP_WINDOW_CLAMP,GROUP_IP_TCP,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_TCP,TCP_WINDOW_CLAMP }; #endif #ifdef TCP_INFO const struct optdesc opt_tcp_info = { "tcp-info", "info", OPT_TCP_INFO, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_INFO }; #endif #ifdef TCP_QUICKACK const struct optdesc opt_tcp_quickack = { "tcp-quickack", "quickack", OPT_TCP_QUICKACK, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_QUICKACK }; #endif #ifdef TCP_NOOPT const struct optdesc opt_tcp_noopt = { "tcp-noopt", "noopt", OPT_TCP_NOOPT, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_NOOPT }; #endif #ifdef TCP_NOPUSH const struct optdesc opt_tcp_nopush = { "tcp-nopush", "nopush", OPT_TCP_NOPUSH, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_NOPUSH }; #endif #ifdef TCP_MD5SIG const struct optdesc opt_tcp_md5sig = { "tcp-md5sig", "md5sig", OPT_TCP_MD5SIG, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_MD5SIG }; #endif #ifdef TCP_SACK_DISABLE const struct optdesc opt_tcp_sack_disable = { "tcp-sack-disable", "sack-disable", OPT_TCP_SACK_DISABLE, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_SACK_DISABLE }; #endif #ifdef TCP_SIGNATURE_ENABLE const struct optdesc opt_tcp_signature_enable = { "tcp-signature-enable", "signature-enable", OPT_TCP_SIGNATURE_ENABLE, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_SIGNATURE_ENABLE }; #endif #ifdef TCP_ABORT_THRESHOLD /* HP-UX */ const struct optdesc opt_tcp_abort_threshold = { "tcp-abort-threshold", "abort-threshold", OPT_TCP_ABORT_THRESHOLD, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_ABORT_THRESHOLD }; #endif #ifdef TCP_CONN_ABORT_THRESHOLD /* HP-UX */ const struct optdesc opt_tcp_conn_abort_threshold = { "tcp-conn-abort-threshold", "conn-abort-threshold", OPT_TCP_CONN_ABORT_THRESHOLD, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_CONN_ABORT_THRESHOLD }; #endif #ifdef TCP_KEEPINIT /* OSF1 aka Tru64 */ const struct optdesc opt_tcp_keepinit = { "tcp-keepinit", "keepinit", OPT_TCP_KEEPINIT, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_TCP, TCP_KEEPINIT }; #endif #ifdef TCP_PAWS /* OSF1 aka Tru64 */ const struct optdesc opt_tcp_paws = { "tcp-paws", "paws", OPT_TCP_PAWS, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_TCP, TCP_PAWS }; #endif #ifdef TCP_SACKENA /* OSF1 aka Tru64 */ const struct optdesc opt_tcp_sackena = { "tcp-sackena", "sackena", OPT_TCP_SACKENA, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_TCP, TCP_SACKENA }; #endif #ifdef TCP_TSOPTENA /* OSF1 aka Tru64 */ const struct optdesc opt_tcp_tsoptena = { "tcp-tsoptena", "tsoptena", OPT_TCP_TSOPTENA, GROUP_IP_TCP, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_TCP, TCP_TSOPTENA }; #endif #endif /* WITH_TCP */ socat-1.7.3.1/COPYING.OpenSSL0000644000201000020100000001420707546500502015104 0ustar gerhardgerhard LICENSE ISSUES ============== The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the OpenSSL License and the original SSLeay license apply to the toolkit. See below for the actual license texts. Actually both licenses are BSD-style Open Source licenses. In case of any license issues related to OpenSSL please contact openssl-core@openssl.org. OpenSSL License --------------- /* ==================================================================== * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * openssl-core@openssl.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.openssl.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */ Original SSLeay License ----------------------- /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ socat-1.7.3.1/socks4echo.sh0000755000201000020100000000433211453022152015161 0ustar gerhardgerhard#! /bin/bash # source: socks4echo.sh # Copyright Gerhard Rieger 2004-2006 # Published under the GNU General Public License V.2, see file COPYING # perform primitive simulation of a socks4 server with echo function via stdio. # accepts and answers correct SOCKS4 requests, but then just echoes data. # it is required for test.sh # for TCP, use this script as: # socat tcp-l:1080,reuseaddr,crlf system:"socks4echo.sh" # older bash and ksh do not have -n option to read command; we try dd then if echo a |read -n 1 null >/dev/null 2>&1; then HAVE_READ_N=1 else HAVE_READ_N= fi if type socat >/dev/null 2>&1; then SOCAT=socat else SOCAT=./socat fi case `uname` in HP-UX|OSF1) CAT="$SOCAT -u stdin stdout" ;; *) CAT=cat ;; esac if [ $(echo "x\c") = "x" ]; then E="" elif [ $(echo -e "x\c") = "x" ]; then E="-e" else echo "cannot suppress trailing newline on echo" >&2 exit 1 fi ECHO="echo $E" if [ $($ECHO "\0101") = "A" ]; then SOCKSREPLY_FAILED="\0\0133\0\0\0\0\0\0\c" SOCKSREPLY_OK="\0\0132\0\0\0\0\0\0\c" else SOCKSREPLY_FAILED="\0\133\0\0\0\0\0\0\c" SOCKSREPLY_OK="\0\132\0\0\0\0\0\0\c" fi # read and parse SOCKS4 header if [ "$HAVE_READ_N" ]; then read -r -n 1 vn # bash 2.0.3 does not support -n else vn=$(dd bs=1 count=1 2>/dev/null) fi if [ "$vn" != $($ECHO "\04") ]; then $ECHO "$SOCKSREPLY_FAILED" echo "invalid socks version requested" >&2 exit fi if [ "$HAVE_READ_N" ]; then read -r -n 1 cd else cd=$(dd bs=1 count=1 2>/dev/null) fi if [ "$cd" != $($ECHO "\01") ]; then $ECHO "$SOCKSREPLY_FAILED" echo "invalid socks operation requested" >&2 exit fi if [ "$HAVE_READ_N" ]; then read -r -n 6 a else a=$(dd bs=1 count=6 2>/dev/null) fi if [ "$a" != "$($ECHO "}m bL6")" ]; then $ECHO "$SOCKSREPLY_FAILED" echo "$0: wrong socks address or port requested" >&2 echo "$0: expected $($ECHO "}m bL6"|od -t x1), received $($ECHO "$a"|od -t x1)" >&2 exit fi if [ "$HAVE_READ_N" ]; then read -r -n 7 u else u=$(dd bs=1 count=7 2>/dev/null) fi if [ "$u" != "nobody" ]; then $ECHO "$SOCKSREPLY_FAILED" echo "wrong socks user requested" >&2 exit fi # send ok status $ECHO "$SOCKSREPLY_OK" # perform echo function $CAT socat-1.7.3.1/sslcls.c0000644000201000020100000002603212460670272014240 0ustar gerhardgerhard/* source: sslcls.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* explicit system call and C library trace function, for those who miss strace */ #include "config.h" #include "xioconfig.h" /* what features are enabled */ #if WITH_SYCLS && WITH_OPENSSL #include "sysincludes.h" #include "mytypes.h" #include "compat.h" #include "errno.h" #include "error.h" #include "filan.h" #include "sysutils.h" #include "sycls.h" void sycSSL_load_error_strings(void) { Debug("SSL_load_error_strings()"); SSL_load_error_strings(); Debug("SSL_load_error_strings() ->"); } int sycSSL_library_init(void) { int result; Debug("SSL_library_init()"); result = SSL_library_init(); Debug1("SSL_library_init() -> %d", result); return result; } #if HAVE_SSLv2_client_method const SSL_METHOD *sycSSLv2_client_method(void) { const SSL_METHOD *result; Debug("SSLv2_client_method()"); result = SSLv2_client_method(); Debug1("SSLv2_client_method() -> %p", result); return result; } #endif #if HAVE_SSLv2_server_method const SSL_METHOD *sycSSLv2_server_method(void) { const SSL_METHOD *result; Debug("SSLv2_server_method()"); result = SSLv2_server_method(); Debug1("SSLv2_server_method() -> %p", result); return result; } #endif const SSL_METHOD *sycSSLv3_client_method(void) { const SSL_METHOD *result; Debug("SSLv3_client_method()"); result = SSLv3_client_method(); Debug1("SSLv3_client_method() -> %p", result); return result; } const SSL_METHOD *sycSSLv3_server_method(void) { const SSL_METHOD *result; Debug("SSLv3_server_method()"); result = SSLv3_server_method(); Debug1("SSLv3_server_method() -> %p", result); return result; } const SSL_METHOD *sycSSLv23_client_method(void) { const SSL_METHOD *result; Debug("SSLv23_client_method()"); result = SSLv23_client_method(); Debug1("SSLv23_client_method() -> %p", result); return result; } const SSL_METHOD *sycSSLv23_server_method(void) { const SSL_METHOD *result; Debug("SSLv23_server_method()"); result = SSLv23_server_method(); Debug1("SSLv23_server_method() -> %p", result); return result; } const SSL_METHOD *sycTLSv1_client_method(void) { const SSL_METHOD *result; Debug("TLSv1_client_method()"); result = TLSv1_client_method(); Debug1("TLSv1_client_method() -> %p", result); return result; } const SSL_METHOD *sycTLSv1_server_method(void) { const SSL_METHOD *result; Debug("TLSv1_server_method()"); result = TLSv1_server_method(); Debug1("TLSv1_server_method() -> %p", result); return result; } #if HAVE_TLSv1_1_client_method const SSL_METHOD *sycTLSv1_1_client_method(void) { const SSL_METHOD *result; Debug("TLSv1_1_client_method()"); result = TLSv1_1_client_method(); Debug1("TLSv1_1_client_method() -> %p", result); return result; } #endif #if HAVE_TLSv1_1_server_method const SSL_METHOD *sycTLSv1_1_server_method(void) { const SSL_METHOD *result; Debug("TLSv1_1_server_method()"); result = TLSv1_1_server_method(); Debug1("TLSv1_1_server_method() -> %p", result); return result; } #endif #if HAVE_TLSv1_2_client_method const SSL_METHOD *sycTLSv1_2_client_method(void) { const SSL_METHOD *result; Debug("TLSv1_2_client_method()"); result = TLSv1_2_client_method(); Debug1("TLSv1_2_client_method() -> %p", result); return result; } #endif #if HAVE_TLSv1_2_server_method const SSL_METHOD *sycTLSv1_2_server_method(void) { const SSL_METHOD *result; Debug("TLSv1_2_server_method()"); result = TLSv1_2_server_method(); Debug1("TLSv1_2_server_method() -> %p", result); return result; } #endif const SSL_METHOD *sycDTLSv1_client_method(void) { const SSL_METHOD *result; Debug("DTLSv1_client_method()"); result = DTLSv1_client_method(); Debug1("DTLSv1_client_method() -> %p", result); return result; } const SSL_METHOD *sycDTLSv1_server_method(void) { const SSL_METHOD *result; Debug("DTLSv1_server_method()"); result = DTLSv1_server_method(); Debug1("DTLSv1_server_method() -> %p", result); return result; } SSL_CTX *sycSSL_CTX_new(const SSL_METHOD *method) { SSL_CTX *result; Debug1("SSL_CTX_new(%p)", method); result = SSL_CTX_new(method); Debug1("SSL_CTX_new() -> %p", result); return result; } SSL *sycSSL_new(SSL_CTX *ctx) { SSL *result; Debug1("SSL_new(%p)", ctx); result = SSL_new(ctx); Debug1("SSL_new() -> %p", result); return result; } int sycSSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath) { int result; Debug7("SSL_CTX_load_verify_locations(%p, %s%s%s, %s%s%s)", ctx, CAfile?"\"":"", CAfile?CAfile:"", CAfile?"\"":"", CApath?"\"":"", CApath?CApath:"", CApath?"\"":""); result = SSL_CTX_load_verify_locations(ctx, CAfile, CApath); Debug1("SSL_CTX_load_verify_locations() -> %d", result); return result; } int sycSSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) { int result; Debug3("SSL_CTX_use_certificate_file(%p, \"%s\", %d)", ctx, file, type); result = SSL_CTX_use_certificate_file(ctx, file, type); Debug1("SSL_CTX_use_certificate_file() -> %d", result); return result; } int sycSSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) { int result; Debug2("SSL_CTX_use_certificate_chain_file(%p, \"%s\")", ctx, file); result = SSL_CTX_use_certificate_chain_file(ctx, file); Debug1("SSL_CTX_use_certificate_chain_file() -> %d", result); return result; } int sycSSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) { int result; Debug3("SSL_CTX_use_PrivateKey_file(%p, \"%s\", %d)", ctx, file, type); result = SSL_CTX_use_PrivateKey_file(ctx, file, type); Debug1("SSL_CTX_use_PrivateKey_file() -> %d", result); return result; } void sycSSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) { Debug3("SSL_CTX_set_verify(%p, %u, %p)", ctx, mode, verify_callback); SSL_CTX_set_verify(ctx, mode, verify_callback); Debug("SSL_CTX_set_verify() -> "); } int sycSSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) { int result; Debug2("SSL_CTX_set_cipher_list(%p, \"%s\")", ctx, str); result = SSL_CTX_set_cipher_list(ctx, str); Debug1("SSL_CTX_set_cipher_list() -> %d", result); return result; } int sycSSL_CTX_set_tmp_dh(SSL_CTX *ctx, DH *dh) { int result; Debug2("SSL_CTX_set_tmp_dh(%p, %p)", ctx, dh); result = SSL_CTX_set_tmp_dh(ctx, dh); Debug1("SSL_CTX_set_tmp_dh() -> %d", result); return result; } int sycSSL_set_cipher_list(SSL *ssl, const char *str) { int result; Debug2("SSL_set_cipher_list(%p, \"%s\")", ssl, str); result = SSL_set_cipher_list(ssl, str); Debug1("SSL_set_cipher_list() -> %d", result); return result; } long sycSSL_get_verify_result(SSL *ssl) { long result; Debug1("SSL_get_verify_result(%p)", ssl); result = SSL_get_verify_result(ssl); Debug1("SSL_get_verify_result() -> %lx", result); return result; } int sycSSL_set_fd(SSL *ssl, int fd) { int result; Debug2("SSL_set_fd(%p, %d)", ssl, fd); result = SSL_set_fd(ssl, fd); Debug1("SSL_set_fd() -> %d", result); return result; } int sycSSL_connect(SSL *ssl) { int result; Debug1("SSL_connect(%p)", ssl); result = SSL_connect(ssl); Debug1("SSL_connect() -> %d", result); return result; } int sycSSL_accept(SSL *ssl) { int result; Debug1("SSL_accept(%p)", ssl); result = SSL_accept(ssl); Debug1("SSL_accept() -> %d", result); return result; } int sycSSL_read(SSL *ssl, void *buf, int num) { int result; Debug3("SSL_read(%p, %p, %d)", ssl, buf, num); result = SSL_read(ssl, buf, num); Debug1("SSL_read() -> %d", result); return result; } int sycSSL_pending(SSL *ssl) { int result; Debug1("SSL_pending(%p)", ssl); result = SSL_pending(ssl); Debug1("SSL_pending() -> %d", result); return result; } int sycSSL_write(SSL *ssl, const void *buf, int num) { int result; Debug3("SSL_write(%p, %p, %d)", ssl, buf, num); result = SSL_write(ssl, buf, num); Debug1("SSL_write() -> %d", result); return result; } X509 *sycSSL_get_peer_certificate(SSL *ssl) { X509 *result; Debug1("SSL_get_peer_certificate(%p)", ssl); result = SSL_get_peer_certificate(ssl); if (result) { Debug1("SSL_get_peer_certificate() -> %p", result); } else { Debug("SSL_get_peer_certificate() -> NULL"); } return result; } int sycSSL_shutdown(SSL *ssl) { int result; Debug1("SSL_shutdown(%p)", ssl); result = SSL_shutdown(ssl); Debug1("SSL_shutdown() -> %d", result); return result; } void sycSSL_CTX_free(SSL_CTX *ctx) { Debug1("SSL_CTX_free(%p)", ctx); SSL_CTX_free(ctx); Debug("SSL_CTX_free() -> void"); return; } void sycSSL_free(SSL *ssl) { Debug1("SSL_free(%p)", ssl); SSL_free(ssl); Debug("SSL_free() -> void"); return; } int sycRAND_egd(const char *path) { int result; Debug1("RAND_egd(\"%s\")", path); result = RAND_egd(path); Debug1("RAND_egd() -> %d", result); return result; } DH *sycPEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) { DH *result; Debug4("PEM_read_bio_DHparams(%p, %p, %p, %p)", bp, x, cb, u); result = PEM_read_bio_DHparams(bp, x, cb, u); if (result) { /*Debug2("PEM_read_bio_DHparams(, {%p},,) -> %p", *x, result);*/ Debug1("PEM_read_bio_DHparams() -> %p", result); } else { Debug("PEM_read_bio_DHparams() -> NULL"); } return result; } BIO *sycBIO_new_file(const char *filename, const char *mode) { BIO *result; Debug2("BIO_new_file(\"%s\", \"%s\")", filename, mode); result = BIO_new_file(filename, mode); if (result) { Debug1("BIO_new_file() -> %p", result); } else { Debug("BIO_new_file() -> NULL"); } return result; } #if WITH_FIPS int sycFIPS_mode_set(int onoff) { int result; Debug1("FIPS_mode_set(%d)", onoff); result = FIPS_mode_set(onoff); Debug1("FIPS_mode_set() -> %d", result); return result; } #endif /* WITH_FIPS */ #if OPENSSL_VERSION_NUMBER >= 0x00908000L const COMP_METHOD *sycSSL_get_current_compression(SSL *ssl) { const COMP_METHOD *result; Debug1("SSL_get_current_compression(%p)", ssl); result = SSL_get_current_compression(ssl); if (result) { Debug1("SSL_get_current_compression() -> %p", result); } else { Debug("SSL_get_current_compression() -> NULL"); } return result; } const COMP_METHOD *sycSSL_get_current_expansion(SSL *ssl) { const COMP_METHOD *result; Debug1("SSL_get_current_expansion(%p)", ssl); result = SSL_get_current_expansion(ssl); if (result) { Debug1("SSL_get_current_expansion() -> %p", result); } else { Debug("SSL_get_current_expansion() -> NULL"); } return result; } const char *sycSSL_COMP_get_name(const COMP_METHOD *comp) { const char *result; Debug1("SSL_COMP_get_name(%p)", comp); result = SSL_COMP_get_name(comp); if (result) { Debug1("SSL_COMP_get_name() -> \"%s\"", result); } else { Debug("SSL_COMP_get_name() -> NULL"); } return result; } #endif #endif /* WITH_SYCLS && WITH_OPENSSL */ socat-1.7.3.1/xiolockfile.c0000644000201000020100000000542312161511320015230 0ustar gerhardgerhard/* source: xiolockfile.c */ /* Copyright Gerhard Rieger 2005-2011 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains socats explicit locking mechanisms */ #include "xiosysincludes.h" #include "compat.h" #include "mytypes.h" #include "error.h" #include "utils.h" #include "sysutils.h" #include "sycls.h" #include "xio.h" #include "xiolockfile.h" /* returns 0 if it could create lock; 1 if the lock exists; -1 on error */ int xiogetlock(const char *lockfile) { char *s; struct stat strat; int fd; pid_t pid; char pidbuf[3*sizeof(pid_t)+1]; size_t bytes; if (Lstat(lockfile, &strat) == 0) { return 1; } switch (errno) { case ENOENT: break; default: Error3("Lstat(\"%s\", %p): %s", lockfile, &strat, strerror(errno)); return -1; } /* in this moment, the file did not exist */ if ((s = Malloc(strlen(lockfile)+8)) == NULL) { errno = ENOMEM; return -1; } strcpy(s, lockfile); strcat(s, ".XXXXXX"); if ((fd = Mkstemp(s)) < 0) { Error2("mkstemp(\"%s\"): %s", s, strerror(errno)); return -1; } pid = Getpid(); bytes = sprintf(pidbuf, F_pid, pid); if (writefull(fd, pidbuf, bytes) < 0) { Error4("write(%d, %p, "F_Zu"): %s", fd, pidbuf, bytes, strerror(errno)); return -1; } Close(fd); /* Chmod(lockfile, 0600); */ if (Link(s, lockfile) < 0) { int _errno = errno; Error3("link(\"%s\", \"%s\"): %s", s, lockfile, strerror(errno)); Unlink(s); errno = _errno; return -1; } Unlink(s); return 0; } int xiounlock(const char *lockfile) { return Unlink(lockfile); } /* returns 0 when it could create lock, or -1 on error */ int xiowaitlock(const char *lockfile, struct timespec *intervall) { int rc; int level = E_NOTICE; /* first print a notice */ while ((rc = xiogetlock(lockfile)) == 1) { Msg1(level, "waiting for lock \"%s\"", lockfile); level = E_INFO; /* afterwards only make info */ Nanosleep(intervall, NULL); } return rc; } /* returns 0 when it could obtain lock or the lock is not valid (lockfile==NULL), 1 if it could not obtain the lock, or -1 on error */ int xiolock(xiolock_t *lock) { int result; if (lock->lockfile == NULL) { return 0; } if (lock->waitlock) { result = xiowaitlock(lock->lockfile, &lock->intervall); } else { result = xiogetlock(lock->lockfile); } if (result == 0) { Info1("obtained lock \"%s\"", lock->lockfile); } return result; } int xiofiledroplock(xiofile_t *xfd) { if (xfd->tag == XIO_TAG_DUAL) { xiofiledroplock((xiofile_t *)xfd->dual.stream[0]); xiofiledroplock((xiofile_t *)xfd->dual.stream[1]); } else { xfd->stream.havelock = false; } return 0; } socat-1.7.3.1/xio.h0000644000201000020100000003640112460670272013542 0ustar gerhardgerhard/* source: xio.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_h_included #define __xio_h_included 1 #if 1 /*!*/ #include "mytypes.h" #include "sysutils.h" #endif #define XIO_MAXSOCK 2 /* Linux 2.2.10 */ #define HAVE_STRUCT_LINGER 1 #define LINETERM_RAW 0 #define LINETERM_CR 1 #define LINETERM_CRNL 2 struct addrdesc; struct opt; /* the flags argument of xioopen */ #define XIO_RDONLY O_RDONLY /* asserted to be 0 */ #define XIO_WRONLY O_WRONLY /* asserted to be 1 */ #define XIO_RDWR O_RDWR /* asserted to be 2 */ #define XIO_ACCMODE O_ACCMODE /* must be 3 */ #define XIO_MAYFORK 4 /* address is allowed to fork the program (fork) */ #define XIO_MAYCHILD 8 /* address is allowed to fork off a child (exec)*/ #define XIO_MAYEXEC 16 /* address is allowed to exec a prog (exec+nofork) */ #define XIO_MAYCONVERT 32 /* address is allowed to perform modifications on the stream data, e.g. SSL, REALDINE; CRLF */ /* the status flags of xiofile_t */ #define XIO_DOESFORK XIO_MAYFORK #define XIO_DOESCHILD XIO_MAYCHILD #define XIO_DOESEXEC XIO_MAYEXEC #define XIO_DOESCONVERT XIO_MAYCONVERT /* methods for reading and writing, and for related checks */ #define XIODATA_READMASK 0xf000 /* mask for basic r/w method */ #define XIOREAD_STREAM 0x1000 /* read() (default) */ #define XIOREAD_RECV 0x2000 /* recvfrom() */ #define XIOREAD_PTY 0x4000 /* handle EIO */ #define XIOREAD_READLINE 0x5000 /* ... */ #define XIOREAD_OPENSSL 0x6000 /* SSL_read() */ #define XIODATA_WRITEMASK 0x0f00 /* mask for basic r/w method */ #define XIOWRITE_STREAM 0x0100 /* write() (default) */ #define XIOWRITE_SENDTO 0x0200 /* sendto() */ #define XIOWRITE_PIPE 0x0300 /* write() to alternate (pipe) Fd */ #define XIOWRITE_2PIPE 0x0400 /* write() to alternate (2pipe) Fd */ #define XIOWRITE_READLINE 0x0500 /* check for prompt */ #define XIOWRITE_OPENSSL 0x0600 /* SSL_write() */ /* modifiers to XIODATA_READ_RECV */ #define XIOREAD_RECV_CHECKPORT 0x0001 /* recv, check peer port */ #define XIOREAD_RECV_CHECKADDR 0x0002 /* recv, check peer address */ #define XIOREAD_RECV_CHECKRANGE 0x0004 /* recv, check if peer addr in range */ #define XIOREAD_RECV_ONESHOT 0x0008 /* give EOF after first packet */ #define XIOREAD_RECV_SKIPIP 0x0010 /* recv, skip IPv4 header */ #define XIOREAD_RECV_FROM 0x0020 /* remember peer for replying */ /* combinations */ #define XIODATA_MASK (XIODATA_READMASK|XIODATA_WRITEMASK) #define XIODATA_STREAM (XIOREAD_STREAM|XIOWRITE_STREAM) #define XIODATA_RECVFROM (XIOREAD_RECV|XIOWRITE_SENDTO|XIOREAD_RECV_CHECKPORT|XIOREAD_RECV_CHECKADDR|XIOREAD_RECV_FROM) #define XIODATA_RECVFROM_SKIPIP (XIODATA_RECVFROM|XIOREAD_RECV_SKIPIP) #define XIODATA_RECVFROM_ONE (XIODATA_RECVFROM|XIOREAD_RECV_ONESHOT) #define XIODATA_RECVFROM_SKIPIP_ONE (XIODATA_RECVFROM_SKIPIP|XIOREAD_RECV_ONESHOT) #define XIODATA_RECV (XIOREAD_RECV|XIOWRITE_SENDTO|XIOREAD_RECV_CHECKRANGE) #define XIODATA_RECV_SKIPIP (XIODATA_RECV|XIOREAD_RECV_SKIPIP) #define XIODATA_PIPE (XIOREAD_STREAM|XIOWRITE_PIPE) #define XIODATA_2PIPE (XIOREAD_STREAM|XIOWRITE_2PIPE) #define XIODATA_PTY (XIOREAD_PTY|XIOWRITE_STREAM) #define XIODATA_READLINE (XIOREAD_READLINE|XIOWRITE_STREAM) #define XIODATA_OPENSSL (XIOREAD_OPENSSL|XIOWRITE_OPENSSL) /* these are the values allowed for the "enum xiotag tag" flag of the "struct single" and "union bipipe" (xiofile_t) structures. */ enum xiotag { XIO_TAG_INVALID, /* the record is not in use */ XIO_TAG_RDONLY, /* this is a single read-only stream */ XIO_TAG_WRONLY, /* this is a single write-only stream */ XIO_TAG_RDWR, /* this is a single read-write stream */ XIO_TAG_DUAL /* this is a dual stream, consisting of two single streams */ } ; /* global XIO options/parameters */ typedef struct { bool strictopts; const char *pipesep; const char *paramsep; const char *optionsep; char ip4portsep; char ip6portsep; /* do not change, might be hardcoded somewhere! */ char logopt; /* 'm' means "switch to syslog when entering daemon mode" */ const char *syslogfac; /* syslog facility (only with mixed mode) */ char default_ip; /* default prot.fam for IP based listen ('4' or '6') */ char preferred_ip; /* preferred prot.fam. for name resolution ('0' for unspecified, '4', or '6') */ } xioopts_t; /* pack the description of a lock file */ typedef struct { const char *lockfile; /* name of lockfile; NULL if no locking */ bool waitlock; /* dont't exit when already locked */ struct timespec intervall; /* polling intervall */ } xiolock_t; extern xioopts_t xioopts; #define MAXARGV 8 /* a non-dual file descriptor */ typedef struct single { enum xiotag tag; /* see enum xiotag */ const struct addrdesc *addr; int flags; /* until here, keep consistent with bipipe.common !!! */ #if WITH_RETRY unsigned int retry; /* retry opening this many times */ bool forever; /* retry opening forever */ struct timespec intervall; /* wait so long between retries */ #endif /* WITH_RETRY */ bool ignoreeof; /* option ignoreeof; do not pass eof condition to app*/ int eof; /* 1..exec'd child has died, but no explicit eof occurred 2..fd0 has reached EOF (definitely; never with ignoreeof! */ size_t wsize; /* write always this size; 0..all available */ size_t readbytes; /* read only so many bytes; 0...unlimited */ size_t actbytes; /* so many bytes still to be read (when readbytes!=0)*/ xiolock_t lock; /* parameters of lockfile */ bool havelock; /* we are happy owner of the above lock */ bool cool_write; /* downlevel EPIPE, ECONNRESET to notice */ /* until here, keep consistent with bipipe.dual ! */ int argc; /* number of fields in argv */ const char *argv[MAXARGV]; /* address keyword, required args */ struct opt *opts; /* the options of this address */ int lineterm; /* 0..dont touch; 1..CR; 2..CRNL on extern data */ int fd; bool opt_unlink_close; /* option unlink_close */ char *unlink_close; /* name of a symlink or unix socket to be removed */ int dtype; enum { XIOSHUT_UNSPEC, /* standard (address dependent) behaviour */ XIOSHUT_NONE, /* do nothing on shutdown */ XIOSHUT_CLOSE, /* close the FD */ XIOSHUT_DOWN, /* shutdown() */ XIOSHUT_NULL /* send an empty packet (dgram socket) */ } howtoshut; enum { END_UNSPEC, /* after init, when no end-close... option */ END_NONE, /* no action */ END_CLOSE, /* close() */ END_SHUTDOWN, /* shutdown() */ END_KILL, /* has subprocess */ END_CLOSE_KILL, /* first close fd, then kill subprocess */ END_SHUTDOWN_KILL /* first shutdown fd, then kill subprocess */ } howtoend; #if _WITH_SOCKET union sockaddr_union peersa; socklen_t salen; #endif /* _WITH_SOCKET */ #if WITH_TERMIOS bool ttyvalid; /* the following struct is valid */ struct termios savetty; /* save orig tty settings for later restore */ #endif /* WITH_TERMIOS */ int (*sigchild)(struct single *); /* callback after sigchild */ pid_t ppid; /* parent pid, only if we send it signals */ int escape; /* escape character; -1 for no escape */ bool actescape; /* escape character found in input data */ union { struct { int fdout; /* use fd for output */ } bipipe; #if _WITH_SOCKET struct { struct timeval connect_timeout; /* how long to hang in connect() */ union sockaddr_union la; /* local socket address */ bool null_eof; /* with dgram: empty packet means EOF */ bool dorange; struct xiorange range; /* restrictions for peer address */ #if _WITH_IP4 || _WITH_IP6 struct { unsigned int res_opts[2]; /* bits to be set in _res.options are at [0], bits to be cleared are at [1] */ bool dosourceport; uint16_t sourceport; /* host byte order */ bool lowport; #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP bool dolibwrap; char *libwrapname; char *tcpwrap_etc; char *hosts_allow_table; char *hosts_deny_table; #endif } ip; #endif /* _WITH_IP4 || _WITH_IP6 */ #if WITH_UNIX struct { bool tight; } un; #endif /* WITH_UNIX */ } socket; #endif /* _WITH_SOCKET */ struct { pid_t pid; /* child PID, with EXEC: */ int fdout; /* use fd for output if two pipes */ } exec; #if WITH_READLINE struct { char *history_file; char *prompt; /* static prompt, passed to readline() */ size_t dynbytes; /* length of buffer for dynamic prompt */ char *dynprompt; /* the dynamic prompt */ char *dynend; /* current end of dynamic prompt */ #if HAVE_REGEX_H bool hasnoecho; /* following regex is set */ regex_t noecho; /* if it matches the prompt, input is silent */ #endif } readline; #endif /* WITH_READLINE */ #if WITH_OPENSSL struct { struct timeval connect_timeout; /* how long to hang in connect() */ SSL *ssl; SSL_CTX* ctx; } openssl; #endif /* WITH_OPENSSL */ #if WITH_TUN struct { short iff_opts[2]; /* ifr flags, using OFUNC_OFFSET_MASKS */ } tun; #endif /* WITH_TUN */ } para; } xiosingle_t; /* rw: 0..read, 1..write, 2..r/w */ /* when implementing a new address type take care of following topics: . be aware that xioopen_single is used for O_RDONLY, O_WRONLY, and O_RDWR data . which options are allowed (option groups) . implement application of all these options . set FD_CLOEXEC on new file descriptors BEFORE the cloexec option might be applied . */ typedef union bipipe { enum xiotag tag; struct { enum xiotag tag; const struct addrdesc *addr; int flags; } common; struct single stream; struct { enum xiotag tag; const struct addrdesc *addr; int flags; /* compatible to fcntl(.., F_GETFL, ..) */ #if WITH_RETRY unsigned retry; /* retry opening this many times */ bool forever; /* retry opening forever */ struct timespec intervall; /* wait so long between retries */ #endif /* WITH_RETRY */ bool ignoreeof; int eof; /* fd0 has reached EOF */ size_t wsize; /* write always this size; 0..all available */ size_t readbytes; /* read only so many bytes; 0...unlimited */ size_t actbytes; /* so many bytes still to be read */ xiolock_t lock; /* parameters of lockfile */ bool havelock; /* we are happy owner of the above lock */ xiosingle_t *stream[2]; /* input stream, output stream */ } dual; } xiofile_t; 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, unsigned groups, int arg1, int arg2, int arg3); unsigned groups; int arg1; int arg2; int arg3; #if WITH_HELP const char *syntax; #endif } ; #define XIO_WRITABLE(s) (((s)->common.flags+1)&2) #define XIO_READABLE(s) (((s)->common.flags+1)&1) #define XIO_RDSTREAM(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[0]:&(s)->stream) #define XIO_WRSTREAM(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[1]:&(s)->stream) #define XIO_GETRDFD(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[0]->fd:(s)->stream.fd) #define XIO_GETWRFD(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[1]->fd:(((s)->stream.dtype&XIODATA_WRITEMASK)==XIOWRITE_2PIPE)?(s)->stream.para.exec.fdout:(((s)->stream.dtype&XIODATA_WRITEMASK)==XIOWRITE_PIPE)?(s)->stream.para.bipipe.fdout:(s)->stream.fd) #define XIO_EOF(s) (XIO_RDSTREAM(s)->eof && !XIO_RDSTREAM(s)->ignoreeof) typedef unsigned long flags_t; union integral { int u_bool; uint8_t u_byte; gid_t u_gidt; int u_int; long u_long; #if HAVE_TYPE_LONGLONG long long u_longlong; #endif double u_double; mode_t u_modet; short u_short; size_t u_sizet; char *u_string; uid_t u_uidt; unsigned int u_uint; unsigned long u_ulong; unsigned short u_ushort; uint16_t u_2bytes; void *u_ptr; flags_t u_flag; struct { uint8_t *b_data; size_t b_len; } u_bin; struct timeval u_timeval; #if HAVE_STRUCT_LINGER struct linger u_linger; #endif /* HAVE_STRUCT_LINGER */ #if HAVE_STRUCT_TIMESPEC struct timespec u_timespec; #endif /* HAVE_STRUCT_TIMESPEC */ #if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IP_MREQN struct { char *multiaddr; char *param2; /* address, interface */ #if HAVE_STRUCT_IP_MREQN char ifindex[IF_NAMESIZE+1]; #endif } u_ip_mreq; #endif #if WITH_IP4 struct in_addr u_ip4addr; #endif } ; /* some aliases */ #if HAVE_BASIC_OFF_T==3 # define u_off u_int #elif HAVE_BASIC_OFF_T==5 # define u_off u_long #elif HAVE_BASIC_OFF_T==7 # define u_off u_longlong #else # error "unexpected size of off_t, please report this as bug" #endif #if defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T # if HAVE_BASIC_OFF64_T==5 # define u_off64 u_long # elif HAVE_BASIC_OFF64_T==7 # define u_off64 u_longlong # else # error "unexpected size of off64_t, please report this as bug" # endif #endif /* defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T */ /* this handles option instances, for communication between subroutines */ struct opt { const struct optdesc *desc; union integral value; union integral value2; union integral value3; } ; extern const char *PIPESEP; extern xiofile_t *sock[XIO_MAXSOCK]; extern int num_child; /* return values of xioopensingle */ #define STAT_OK 0 #define STAT_WARNING 1 #define STAT_EXIT 2 #define STAT_NOACTION 3 /* by retropt_* when option not applied */ #define STAT_RETRYNOW -1 /* only after timeouts useful ? */ #define STAT_RETRYLATER -2 /* address cannot be opened, but user might change something in the filesystem etc. to make this process succeed later. */ #define STAT_NORETRY -3 /* address syntax error, not implemented etc; not even by external changes correctable */ extern int xioinitialize(void); extern int xioinitialize2(void); extern pid_t xio_fork(bool subchild, int level); extern int xio_forked_inchild(void); extern int xiosetopt(char what, const char *arg); extern int xioinqopt(char what, char *arg, size_t n); extern xiofile_t *xioopen(const char *args, int flags); extern int xioopensingle(char *addr, struct single *xfd, int xioflags); extern int xioopenhelp(FILE *of, int level); /* must be outside function for use by childdied handler */ extern xiofile_t *sock1, *sock2; #define NUMUNKNOWN 4 extern pid_t diedunknown[NUMUNKNOWN]; /* child died before it is registered */ #define diedunknown1 (diedunknown[0]) #define diedunknown2 (diedunknown[1]) #define diedunknown3 (diedunknown[2]) #define diedunknown4 (diedunknown[3]) extern int xiosetsigchild(xiofile_t *xfd, int (*callback)(struct single *)); extern int xiosetchilddied(void); extern int xio_opt_signal(pid_t pid, int signum); extern void childdied(int signum); extern ssize_t xioread(xiofile_t *sock1, void *buff, size_t bufsiz); extern ssize_t xiopending(xiofile_t *sock1); extern ssize_t xiowrite(xiofile_t *sock1, const void *buff, size_t bufsiz); extern int xioshutdown(xiofile_t *sock, int how); extern int xioclose(xiofile_t *sock); extern void xioexit(void); extern int (*xiohook_newchild)(void); /* xio calls this function from a new child process */ #endif /* !defined(__xio_h_included) */ socat-1.7.3.1/FILES0000644000201000020100000000531307547120544013357 0ustar gerhardgerhard The socat distribution contains the following files: * README: an introduction to socat * FILES: a navigator through the socat distribution (this file) * EXAMPLES: a collection of simple examples how to use socat. * COPYING: what you and others are allowed to do with socat. * PORTING: instructions and tips if you want to try socat on a new platform. * BUGREPORTS: instructions what to do with problems and contributions. * SECURITY: tips if you want to use socat in a security relevant environment. * DEVELOPMENT: infos for programmers * VERSION: the version of the socat distribution, for inclusion during compilation * CHANGES: what happened since first public release * socat.1: man page of socat * socat.html: html version of man page * xio.help: reference manual of the address definitions (xioopen function) * daemon.sh: example shell script for running socat as TCP relay daemon * ftp.sh: example shell based ftp client, using socat for transport * mail.sh: example shell based smtp client, for execution by socat * gatherinfo.sh: shell script for gathering info about platform and socat implementation * server.pem: a self signed test cerificate, for self test only The source code system: * configure: the autoconf generated configurator script * Makefile.in: the Makefile source input to configure * config.h.in: the config.h source input to configure * Config/config..h: sample config.h for platform. * Config/Makefile.: sample Makefile for platform. Copy the appropriate files to ./config.h and ./Makefile if configure fails * socat.c: the main C source, including option parsing, general control, and the data shuffler * xio-*.c, xio-*.h: the source of the different address type implementations with all their modes and options * xio*.c, xio*.h: the source of the xio API and xio utilities * filan.c, filan.h: file descriptor analyzer function * dalan.c, dalan.h: data language, a most primitive subset of what should become a language for describing/generating all kinds of binary data. * error.c, error.h: the logging subsystem * sycls.c, sycls.h: explicit system call and C library trace functions * sslcls.c, sslcls.h: explicit openssl call trace functions * xioconfig.h: ensures some dependencies between configure WITH defines; to be included immediately after config.h * sysutils.c, sysutils.h: some more general system (socket, IP) related functions, e.g. converting socket addresses to human readable form * utils.c, utils.h: useful additions to C library; currently memdup, binary search, and setenv. * mytypes.h: some types and macros I miss in C89 * test.sh: an incomplete attempt to automate tests of socat * compat.h: ensure some features that might be missing on some platforms socat-1.7.3.1/doc/0000755000201000020100000000000012652745660013342 5ustar gerhardgerhardsocat-1.7.3.1/doc/socat-tun.html0000644000201000020100000001505212161511320016123 0ustar gerhardgerhard Building TUN based virtual networks with socat

Building TUN based virtual networks with socat

Introduction

Some operating systems allow the generation of virtual network interfaces that do not connect to a wire but to a process that simulates the network. Often these devices are called TUN or TAP.

socat provides an address type that creates a TUN device on Linux; the other socat address can be any type; it transfers the "wire" data as desired.

This document shows how a simple virtual network can be created between two hosts that may be far (many network hops) apart. On both hosts a socat instance is started that connects to the other host using TCP and creates a TUN device. See socat-openssltunnel.html for a guide on securing the connection using SSL.

The following IP addresses are used in the example; replace them in the following commands with the requirements of your situation:

hostaddressmask
physical "server" address1.2.3.4n/a
physical "client" addressn/an/a
TUN on "server"192.168.255.1255.255.255.0
TUN on "client"192.168.255.2255.255.255.0

The TCP connection uses port 11443.

On "default" Linux installations, creating TUN/TAP devices might require root privilege.

Generate TUN devices with socat

In this section two instances of socat are used to generate TUN devices on different hosts and connect the "wire" sides, providing a simple virtual network.

We distinguish server and client only with respect to the connection between the two socat instances; the TUN interfaces both have the same quality.

TUN Server

socat -d -d TCP-LISTEN:11443,reuseaddr TUN:192.168.255.1/24,up

After starting this command, socat will wait for a connection and then create a TUN pseudo network device with address 192.168.255.1; the bit number specifies the mask of the network that is pretended to be connected on this interface.

TUN Client

socat TCP:1.2.3.4:11443 TUN:192.168.255.2/24,up

This command should establish a connection to the server and create the TUN device on the client.

Seeing it work

After successful connection both TUN interfaces should be active and transfer date between each other using the TCP connection. Try this by pinging 192.168.255.1 from the client and 192.168.255.2 from the server.

TCP/IP version 6

IPv6 as transport should work just like any TCP/IPv6 connection.

Creation of an IPv6 virtual interface is not directly possible, but you can generate an IPv4 interface as described above, and add IPv6 addresses using the ifconfig command.

Troubleshooting

Test TUN integration

If you get error messages like this:

... E unknown device/address "tun"

your socat executable probably does not provide TUN/TAP support. Potential reasons: you are not on Linux or are using an older version of socat.

Missing kernel support

An error message like:

... E open("/dev/net/tun", 02, 0666): No such file or directory

indicates that your kernel either needs to load the tun module or does not have TUN/TAP support compiled in. Try to load the module:

modprobe tun

and check for /dev/net/tun. If that does not succeed you need to rebuild your kernel with the appropriate configuration (probably under Device driver / Network device support / Network device / Universal TUN/TAP).

TUN cloning device permissions

An error message like:

... E open("/dev/net/tun", 02, 0666): Permission denied

indicates that you do not have permission to read or write the TUN cloning device. Check its permission and ownership.

Interface down

If no error occurs but the pings do not work check if the network devices have been created:

ifconfig tun0

The output should look like:

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:192.168.255.1  P-t-P:192.168.255.1  Mask:255.255.255.0
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

Check the "UP" keyword; you forget the "up" option in the socat command if it is missing.

Check if the correct IP address and network mask are displayed.

Routing

netstat -an |fgrep 192.168.255

The output should look like:

192.168.255.0   0.0.0.0         255.255.255.0   U         0 0          0 tun0

Other problems

Another reason for failure might be iptables.

Run socat with options -d -d -d, this will show every data transfer between the two processes. Each ping probe should cause a forth and a back transfer.

History

Linux TUN/TAP support was added to socat in version 1.6.0.

This document was last modified in February 2010.

More info about socat TUN/TAP support

Links regarding this tutorial

socat address tun

socat options for TUN/TAP addresses

TUN/TAP options

References

socat home page
socat man page
OpenVPN home page
TUN/TAP on Wikipedia

Copyright: Gerhard Rieger 2007-2010
License: GNU Free Documentation License (FDL)

socat-1.7.3.1/doc/socat-genericsocket.html0000644000201000020100000003624212161506654020164 0ustar gerhardgerhard Generic sockets with Socat

Generic sockets with Socat

Introduction

Beginning with version 1.7.0 socat provides means to freely control important aspects of socket handling. This allows to experiment with socket types and protocols that are not explicitely implemented in socat.

The related socat features fall into three major categories:

  • address options for changing socket parameters while using common socket types: pf (protocol-family), so-type (socktype), so-prototype (protocol)
  • address options for setting arbitrary socket options: setsockopt-int, setsockopt-string, setsockopt-bin
  • address types for passing almost arbitrary parameters and address data to the standard system calls: socket-connect, socket-listen, socket-sendto, socket-recv, socket-recvfrom, socket-datagram

In practice this gives you two possibilities:

If you want to cope with sockets staying within the usual domains ( = protocol families = address families) which are IPv4, IPv6, UNIX/local, and raw interface for socat 1.7.0, it is sufficient to learn about a couple of address options that allow to change default parameters, and to apply generic socket options.

For other address families socat provides generic socket addresses.

Generic socket options

Example 1: DCCP communication

A relatively new communication protocol has been introduced in the Internet community for which no socat address type has been implemented up to version 1.7.0 (see IETF's Datagram Congestion Control Protocol and Linux foundation Net:DCCP for more info). Taken that the operating system implements DCCP, it is possible to use this protocol with socat while just employing standard socket addresses and some options.

A simple server that accepts a DCCP connection, passes the arriving data to a subprocess for converting upper case to lower case characters, and then returns it to the client:

socat TCP4-LISTEN:4096,reuseaddr,type=6,prototype=33 exec:'tr A-Z a-z',pty,raw,echo=0

A simple client that sends some upper case characters to the server via DCCP and prints what the server returns:

echo ABCD |socat - TCP4-CONNECT:localhost:4096,type=6,prototype=33

We choose the TCP4 addresses as base because it best matches the DCCP requirements:

  1. DCCP is (here) based on IPv4
  2. DCCP is stream oriented and uses connect() and listen(); accept() calls
  3. DCCP protocol uses ports

Option type=6 changes TCP's SOCK_STREAM parameter to SOCK_DCCP, and prototype=33 replaces the default IPPROTO_TCP with IPPROTO_DCCP.

DCCP has an important parameter, the service code. It provides another multiplexing layer beyond the protocol ports. The Linux implementation of DCCP allows to set this parameter with code like setsocktopt(fd, SOL_DCCP, DCCP_SOCKOPT_SERVICE, {1}, sizeof(int)). The equivalent generic socat option is: setsockopt-int=269:2:1 for service code 1. If the service codes on server and client do not match the connect() operation fails with error:

... E connect(3, AF=2 127.0.0.1:4096, 16): Invalid request code

Please note that this examples works with IPv6 as well, you just need to replace the TCP4 words with TCP6, and the IPv4 socket address with an appropriate IPv6 socket address, e.g. [::1]!

Generic socket addresses

socat's generic socket addresses are a more comprehensive mechanism that allows to deal with protocol families whose socket addresses are not supported by socat - no semantical parsing, no structured assignment to the struct components are available. Instead, the socket address records for binding and connecting/sending are specified in unstructured hexadecimal form. The following example demonstrates this by performing simple data transfer over raw AppleTalk protocol.

Note: I do not have any knowledge about AppleTalk. I just managed to configure my Linux host to tolerate the creation of a receiving and a sending socket. Don't blame me nor ask me for support if it does not work for you.

Enabling AppleTalk protocol

Install the netatalk package. Check that /etc/netatalk/atalkd.conf has an entry like eth0 -phase 2 -net 0-65534 -addr 65280.243. The last part is an arbitrary (?) host address, some of the following values must fit it. Make sure the atalkd daemon is running. Run the AppleTalk ping command:

aecho 65280.243

If you get an error like:

Device or resource busy

then try to restart atalkd:

/etc/init.d/atalkd restart

When aecho works like ping you are ready for the next step.

Example 2: AppleTalk datagram communication

We start a socat process with a receiver and echo service:

socat SOCKET-RECVFROM:5:2:0:x40x00x0000x00x00x0000000000000000 PIPE

Then, in another shell on the same host, we start a client socket process that sends data to the server and gets the answer:

echo ABCD |socat - SOCKET-DATAGRAM:5:2:0:x40x00xff00xf3x00x0000000000000000

The client process should print the data.

How did this work? The generic socat address has just used the system call parameters that were provided on command line, without knowing anything about AppleTalk sockets and protocol. The values 5, 2, and 0 are directly used for the socket() call: they specify the domain (PF_APPLETALK=5), socket type (SOCK_DGRAM=2), and no protocol (0) - values for Linux. The long hex strings define the socket addresses. They can only be constructed with knowledge of the underlying structure. In /usr/include/linux/atalk.h we find the following declarations:

struct atalk_addr {
        __be16  s_net;
        __u8    s_node;
};

struct sockaddr_at {
        sa_family_t       sat_family;
        __u8              sat_port;
        struct atalk_addr sat_addr;
        char              sat_zero[8];

After rolling out atalk_addr and considering implicit padding by the C programming language we get the following byte map:

componentoffsetlengthvaluemeaning
sat_family02x0005address family
sat_port21x40port
-31x00padding
sat_addr.s_net42xff00network address
sat_addr.s_node61xf3node address
-71x00padding
sat_zero88x0000000000000000padding

Note that hexadecimal ff00 is the same as decimal 65280, and hexadecimal xf3 is the same as decimal 243 - these are the numbers specified in atalkd.conf.

The address family component must be omitted from the socket address because it is added by socat implicitely. The resulting hexadecimal representation of the target socket address is therefore:

x40x00xff00xf3x00x0000000000000000

The receiver just has to specify the port, so its bind address data is:

x40x00x0000x00x00x0000000000000000

Parameters for well known socket types

Finding the correct parameters and socket addresses is not always trivial. Therefore this section provides tables with the parameters of common socket types. Some of these types are directly implemented by socat (and other programs). Establishing interoperability between a directly implemented socket and a generic socket might be your first step before entering unknown ground.

Socket parameters

Table: parameter names for "well known" sockets:

namedomainsocktypeprotocol levelremark
UDP4PF_INETSOCK_DGRAMIPPROTO_UDP SOL_UDP
UDP6PF_INET6SOCK_DGRAMIPPROTO_UDP SOL_UDP
raw IPv4PF_INETSOCK_RAWIPPROTO_RAW SOL_IP
raw IPv6PF_INET6SOCK_RAWIPPROTO_RAW SOL_IPV6
UNIXPF_LOCALSOCK_DGRAM0 SOL_SOCKET
PACKETPF_PACKETSOCK_RAW768SOL_PACKETtcpdump (include layer 2 header)
PACKETPF_PACKETSOCK_DGRAM768SOL_PACKETno level 2 header
SCTP4PF_INETSOCK_SEQPACKETIPPROTO_SCTP SOL_SCTP

Table: parameter values:

nameLinuxFreeBSDNetBSDOpenBSDSolarisAIXCygwinMac OS XHP-UX
PF_LOCAL111111111
PF_INET222222222
PF_APPLETALK51616161616161616
PF_INET6102824242624-3022
PF_PACKET17--------
SOCK_STREAM111121111
SOCK_DGRAM222212222
SOCK_RAW333343333
SOCK_SEQPACKET555565555
SOCK_DCCP(6)--------
SOCK_PACKET10--------
IPPROTO_IP000000000
IPPROTO_TCP666666666
IPPROTO_UDP171717171717171717
IPPROTO_DCCP33--------
IPPROTO_SCTP132132--132132---
IPPROTO_RAW255255255255255----
SOL_SOCKET16553565535655356553565535655356553565535
SOL_IP000000000
SOL_TCP666666666
SOL_UDP17-----17--
SOL_IPV6414141414141-4141
SOL_PACKET263--------
SOL_DCCP269--------

Socket address specifications

These hexadecimal data define socket addresses for local and remote sockets, and for bind and range options. The basis is the struct sockaddr_* for the respective address family that should be declared in the C include files. Please keep in mind that their first two bytes (sa_family and - on BSD - sa_len) are implicitely prepended by socat.

Linux on 32bit Intel:

namesocket address type (without leading address family)binary specification
IPv42 bytes port, 4 bytes IPv4 addr, 8 bytes 0x0016 x7f000001 x0000000000000000
IPv62 bytes port, 4 bytes flowinfo, 16 bytes IPv6 addr, 4 bytes scope-idx0016 x00000000 x0102030405060708090a0b0c0d0e0f x00000000
UNIXvariable length path name, 0 terminatedx2f746d702f736f636b00
PACKET2 bytes protocol (0x0003), interface index as int in host byte order, 8 bytes 0x0003 x02000000 x0000000000000000

For AppleTalk see above example.

Solaris on 32bit Intel:

namesocket address type (without leading address family)binary specification
IPv62 bytes port, 4 bytes flowinfo, 16 bytes IPv6 addr, 4 bytes scope-id, 4 bytes src-idx0016 x00000000 x0102030405060708090a0b0c0d0e0f x00000000 x00000000

Forever - play on...

Eager to experiment with exotic socket types? Run nmap's protocol scan and see what is available on your system:

nmap -sO localhost

Copyright: Gerhard Rieger 2008
License: GNU Free Documentation License (FDL)

socat-1.7.3.1/doc/socat.yo0000644000201000020100000053034612460743124015025 0ustar gerhardgerhardCOMMENT(source: socat.yo) mailto(socat@dest-unreach.org) def(unix)(0)(UN*X) def(unixdomain)(0)(UNIX domain) def(socat)(0)(bf(socat)) def(Socat)(0)(bf(Socat)) def(filan)(0)(bf(filan)) def(Filan)(0)(bf(Filan)) def(procan)(0)(bf(procan)) def(Procan)(0)(bf(Procan)) manpage(socat)(1)()()() whenhtml( label(CONTENTS) manpagesection(CONTENTS) link(NAME)(NAME)nl() link(SYNOPSIS)(SYNOPSIS)nl() link(DESCRIPTION)(DESCRIPTION)nl() link(OPTIONS)(OPTIONS)nl() link(ADDRESS SPECIFICATIONS)(ADDRESS_SPECIFICATIONS)nl() link(ADDRESS TYPES)(ADDRESS_TYPES)nl() link(ADDRESS OPTIONS)(ADDRESS_OPTIONS)nl() link(DATA VALUES)(VALUES)nl() link(EXAMPLES)(EXAMPLES)nl() link(DIAGNOSTICS)(DIAGNOSTICS)nl() link(FILES)(FILES)nl() link(ENVIRONMENT VARIABLES)(ENVIRONMENT_VARIABLES)nl() link(CREDITS)(CREDITS)nl() link(VERSION)(VERSION)nl() link(BUGS)(BUGS)nl() link(SEE ALSO)(SEEALSO)nl() ) label(NAME) manpagename(socat) (Multipurpose relay (SOcket CAT)) label(SYNOPSIS) manpagesynopsis() tt(socat [options]
)nl() tt(socat -V)nl() tt(socat -h[h[h]] | -?[?[?]])nl() tt(filan)nl() tt(procan) label(DESCRIPTION) manpagedescription() Socat() is a command line based utility that establishes two bidirectional byte streams and transfers data between them. Because the streams can be constructed from a large set of different types of data sinks and sources (see link(address types)(ADDRESS_TYPES)), and because lots of link(address options)(ADDRESS_OPTIONS) may be applied to the streams, socat can be used for many different purposes. Filan() is a utility that prints information about its active file descriptors to stdout. It has been written for debugging socat(), but might be useful for other purposes too. Use the -h option to find more infos. Procan() is a utility that prints information about process parameters to stdout. It has been written to better understand some UNIX process properties and for debugging socat(), but might be useful for other purposes too. The life cycle of a socat() instance typically consists of four phases. In the em(init) phase, the command line options are parsed and logging is initialized. During the em(open) phase, socat() opens the first address and afterwards the second address. These steps are usually blocking; thus, especially for complex address types like socks, connection requests or authentication dialogs must be completed before the next step is started. In the em(transfer) phase, socat() watches both streams' read and write file descriptors via code(select()), and, when data is available on one side em(and) can be written to the other side, socat reads it, performs newline character conversions if required, and writes the data to the write file descriptor of the other stream, then continues waiting for more data in both directions. When one of the streams effectively reaches EOF, the em(closing) phase begins. Socat() transfers the EOF condition to the other stream, i.e. tries to shutdown only its write stream, giving it a chance to terminate gracefully. For a defined time socat() continues to transfer data in the other direction, but then closes all remaining channels and terminates. label(OPTIONS) manpageoptions() Socat() provides some command line options that modify the behaviour of the program. They have nothing to do with so called link(address options)(ADDRESS_OPTIONS) that are used as parts of link(address specifications)(ADDRESS_SPECIFICATIONS). startdit() dit(bf(tt(-V))) Print version and available feature information to stdout, and exit. dit(bf(tt(-h | -?))) Print a help text to stdout describing command line options and available address types, and exit. dit(bf(tt(-hh | -??))) Like -h, plus a list of the short names of all available address options. Some options are platform dependend, so this output is helpful for checking the particular implementation. dit(bf(tt(-hhh | -???))) Like -hh, plus a list of all available address option names. label(option_d)dit(bf(tt(-d))) Without this option, only fatal and error messages are generated; applying this option also prints warning messages. See link(DIAGNOSTICS)(DIAGNOSTICS) for more information. label(option_d_d)dit(bf(tt(-d -d))) Prints fatal, error, warning, and notice messages. dit(bf(tt(-d -d -d))) Prints fatal, error, warning, notice, and info messages. dit(bf(tt(-d -d -d -d))) Prints fatal, error, warning, notice, info, and debug messages. dit(bf(tt(-D))) Logs information about file descriptors before starting the transfer phase. dit(bf(tt(-ly[]))) Writes messages to syslog instead of stderr; severity as defined with -d option. With optional link()(TYPE_FACILITY), the syslog type can be selected, default is "daemon". Third party libraries might not obey this option. dit(bf(tt(-lf))tt( )) Writes messages to [link(filename)(TYPE_FILENAME)] instead of stderr. Some third party libraries, in particular libwrap, might not obey this option. dit(bf(tt(-ls))) Writes messages to stderr (this is the default). Some third party libraries might not obey this option, in particular libwrap appears to only log to syslog. label(option_lp)dit(bf(tt(-lp))tt()) Overrides the program name printed in error messages and used for constructing environment variable names. dit(bf(tt(-lu))) Extends the timestamp of error messages to microsecond resolution. Does not work when logging to syslog. label(option_lm)dit(bf(tt(-lm[]))) Mixed log mode. During startup messages are printed to stderr; when socat() starts the transfer phase loop or daemon mode (i.e. after opening all streams and before starting data transfer, or, with listening sockets with fork option, before the first accept call), it switches logging to syslog. With optional link()(TYPE_FACILITY), the syslog type can be selected, default is "daemon". label(option_lh)dit(bf(tt(-lh))) Adds hostname to log messages. Uses the value from environment variable HOSTNAME or the value retrieved with tt(uname()) if HOSTNAME is not set. dit(bf(tt(-v))) Writes the transferred data not only to their target streams, but also to stderr. The output format is text with some conversions for readability, and prefixed with "> " or "< " indicating flow directions. dit(bf(tt(-x))) Writes the transferred data not only to their target streams, but also to stderr. The output format is hexadecimal, prefixed with "> " or "< " indicating flow directions. Can be combined with code(-v). label(option_b)dit(bf(tt(-b))tt()) Sets the data transfer block [link(size_t)(TYPE_SIZE_T)]. At most bytes are transferred per step. Default is 8192 bytes. label(option_s)dit(bf(tt(-s))) By default, socat() terminates when an error occurred to prevent the process from running when some option could not be applied. With this option, socat() is sloppy with errors and tries to continue. Even with this option, socat will exit on fatals, and will abort connection attempts when security checks failed. label(option_t)dit(bf(tt(-t))tt()) When one channel has reached EOF, the write part of the other channel is shut down. Then, socat() waits [link(timeval)(TYPE_TIMEVAL)] seconds before terminating. Default is 0.5 seconds. This timeout only applies to addresses where write and read part can be closed independently. When during the timeout interval the read part gives EOF, socat terminates without awaiting the timeout. label(option_T)dit(bf(tt(-T))tt()) Total inactivity timeout: when socat is already in the transfer loop and nothing has happened for [link(timeval)(TYPE_TIMEVAL)] seconds (no data arrived, no interrupt occurred...) then it terminates. Useful with protocols like UDP that cannot transfer EOF. label(option_u)dit(bf(tt(-u))) Uses unidirectional mode. The first address is only used for reading, and the second address is only used for writing (link(example)(EXAMPLE_option_u)). label(option_U)dit(bf(tt(-U))) Uses unidirectional mode in reverse direction. The first address is only used for writing, and the second address is only used for reading. label(option_g)dit(bf(tt(-g))) During address option parsing, don't check if the option is considered useful in the given address environment. Use it if you want to force, e.g., appliance of a socket option to a serial device. label(option_L)dit(bf(tt(-L))tt()) If lockfile exists, exits with error. If lockfile does not exist, creates it and continues, unlinks lockfile on exit. label(option_W)dit(bf(tt(-W))tt()) If lockfile exists, waits until it disappears. When lockfile does not exist, creates it and continues, unlinks lockfile on exit. label(option_4)dit(bf(tt(-4))) Use IP version 4 in case that the addresses do not implicitly or explicitly specify a version; this is the default. label(option_6)dit(bf(tt(-6))) Use IP version 6 in case that the addresses do not implicitly or explicitly specify a version. enddit() label(ADDRESS_SPECIFICATIONS) manpagesection(ADDRESS SPECIFICATIONS) With the address command line arguments, the user gives socat() instructions and the necessary information for establishing the byte streams. An address specification usually consists of an address type keyword, zero or more required address parameters separated by ':' from the keyword and from each other, and zero or more address options separated by ','. The keyword specifies the address type (e.g., TCP4, OPEN, EXEC). For some keywords there exist synonyms ('-' for STDIO, TCP for TCP4). Keywords are case insensitive. For a few special address types, the keyword may be omitted: Address specifications starting with a number are assumed to be FD (raw file descriptor) addresses; if a '/' is found before the first ':' or ',', GOPEN (generic file open) is assumed. The required number and type of address parameters depend on the address type. E.g., TCP4 requires a server specification (name or address), and a port specification (number or service name). Zero or more address options may be given with each address. They influence the address in some ways. Options consist of an option keyword or an option keyword and a value, separated by '='. Option keywords are case insensitive. For filtering the options that are useful with an address type, each option is member of one option group. For each address type there is a set of option groups allowed. Only options belonging to one of these address groups may be used (except with link(option -g)(option_g)). label(ADDRESS_DUAL) Address specifications following the above schema are also called em(single) address specifications. Two single addresses can be combined with "!!" to form a em(dual) type address for one channel. Here, the first address is used by socat() for reading data, and the second address for writing data. There is no way to specify an option only once for being applied to both single addresses. Usually, addresses are opened in read/write mode. When an address is part of a dual address specification, or when link(option -u)(option_u) or link(-U)(option_U) is used, an address might be used only for reading or for writing. Considering this is important with some address types. With socat version 1.5.0 and higher, the lexical analysis tries to handle quotes and parenthesis meaningfully and allows escaping of special characters. If one of the characters ( { [ ' is found, the corresponding closing character - ) } ] ' - is looked for; they may also be nested. Within these constructs, socats special characters and strings : , !! are not handled specially. All those characters and strings can be escaped with \ or within "" label(ADDRESS_TYPES) manpagesection(ADDRESS TYPES) This section describes the available address types with their keywords, parameters, and semantics. startdit() label(ADDRESS_CREAT)dit(bf(tt(CREATE:))) Opens link()(TYPE_FILENAME) with code(creat()) and uses the file descriptor for writing. This address type requires write-only context, because a file opened with code(creat) cannot be read from. nl() Flags like O_LARGEFILE cannot be applied. If you need them use link(OPEN)(ADDRESS_OPEN) with options link(create)(OPTION_O_CREAT),link(create)(OPTION_O_TRUNC). nl() must be a valid existing or not existing path. If is a named pipe, code(creat()) might block; if refers to a socket, this is an error.nl() Option groups: link(FD)(GROUP_FD),link(REG)(GROUP_REG),link(NAMED)(GROUP_NAMED) nl() Useful options: link(mode)(OPTION_MODE), link(user)(OPTION_USER), link(group)(OPTION_GROUP), link(unlink-early)(OPTION_UNLINK_EARLY), link(unlink-late)(OPTION_UNLINK_LATE), link(append)(OPTION_APPEND)nl() See also: link(OPEN)(ADDRESS_OPEN), link(GOPEN)(ADDRESS_GOPEN) label(ADDRESS_EXEC)dit(bf(tt(EXEC:))) Forks a sub process that establishes communication with its parent process and invokes the specified program with code(execvp()). link()(TYPE_COMMAND_LINE) is a simple command with arguments separated by single spaces. If the program name contains a '/', the part after the last '/' is taken as ARGV[0]. If the program name is a relative path, the code(execvp()) semantics for finding the program via code($PATH) apply. After successful program start, socat() writes data to stdin of the process and reads from its stdout using a unixdomain() socket generated by code(socketpair()) per default. (link(example)(EXAMPLE_ADDRESS_EXEC)) nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(EXEC)(GROUP_EXEC),link(FORK)(GROUP_FORK),link(TERMIOS)(GROUP_TERMIOS) nl() Useful options: link(path)(OPTION_PATH), link(fdin)(OPTION_FDIN), link(fdout)(OPTION_FDOUT), link(chroot)(OPTION_CHROOT), link(su)(OPTION_SUBSTUSER), link(su-d)(OPTION_SUBSTUSER_DELAYED), link(nofork)(OPTION_NOFORK), link(pty)(OPTION_PTY), link(stderr)(OPTION_STDERR), link(ctty)(OPTION_CTTY), link(setsid)(OPTION_SETSID), link(pipes)(OPTION_PIPES), link(login)(OPTION_LOGIN), link(sigint)(OPTION_SIGINT), link(sigquit)(OPTION_SIGQUIT)nl() See also: link(SYSTEM)(ADDRESS_SYSTEM) label(ADDRESS_FD)dit(bf(tt(FD:))) Uses the file descriptor link()(TYPE_FDNUM). It must already exist as valid unix() file descriptor.nl() Option groups: link(FD)(GROUP_FD) (link(TERMIOS)(GROUP_TERMIOS),link(REG)(GROUP_REG),link(SOCKET)(GROUP_SOCKET)) nl() See also: link(STDIO)(ADDRESS_STDIO), link(STDIN)(ADDRESS_STDIN), link(STDOUT)(ADDRESS_STDOUT), link(STDERR)(ADDRESS_STDERR) label(ADDRESS_GOPEN)dit(bf(tt(GOPEN:))) (Generic open) This address type tries to handle any file system entry except directories usefully. link()(TYPE_FILENAME) may be a relative or absolute path. If it already exists, its type is checked. In case of a unixdomain() socket, socat() connects; if connecting fails, socat() assumes a datagram socket and uses code(sendto()) calls. If the entry is not a socket, socat() opens it applying the code(O_APPEND) flag. If it does not exist, it is opened with flag code(O_CREAT) as a regular file (link(example)(EXAMPLE_ADDRESS_GOPEN)).nl() Option groups: link(FD)(GROUP_FD),link(REG)(GROUP_REG),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(OPEN)(GROUP_OPEN) nl() See also: link(OPEN)(ADDRESS_OPEN), link(CREATE)(ADDRESS_CREAT), link(UNIX-CONNECT)(ADDRESS_UNIX_CONNECT) label(ADDRESS_IP_SENDTO)dit(bf(tt(IP-SENDTO::))) Opens a raw IP socket. Depending on host specification or option link(pf)(OPTION_PROTOCOL_FAMILY), IP protocol version 4 or 6 is used. It uses link()(TYPE_PROTOCOL) to send packets to [link(IP address)(TYPE_IP_ADDRESS)] and receives packets from host, ignores packets from other hosts. Protocol 255 uses the raw socket with the IP header being part of the data.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6) nl() Useful options: link(pf)(OPTION_PROTOCOL_FAMILY), link(ttl)(OPTION_TTL) nl() See also: link(IP4-SENDTO)(ADDRESS_IP4_SENDTO), link(IP6-SENDTO)(ADDRESS_IP6_SENDTO), link(IP-RECVFROM)(ADDRESS_IP_RECVFROM), link(IP-RECV)(ADDRESS_IP_RECV), link(UDP-SENDTO)(ADDRESS_UDP_SENDTO), link(UNIX-SENDTO)(ADDRESS_UNIX_SENDTO) label(ADDRESS_INTERFACE)dit(bf(tt(INTERFACE:))) Communicates with a network connected on an interface using raw packets including link level data. link()(TYPE_INTERFACE) is the name of the network interface. Currently only available on Linux. Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET) nl() Useful options: link(pf)(OPTION_PROTOCOL_FAMILY), link(type)(OPTION_SO_TYPE)nl() See also: link(ip-recv)(ADDRESS_IP_RECV) label(ADDRESS_IP4_SENDTO)dit(bf(tt(IP4-SENDTO::))) Like link(IP-SENDTO)(ADDRESS_IP_SENDTO), but always uses IPv4.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4) nl() label(ADDRESS_IP6_SENDTO)dit(bf(tt(IP6-SENDTO::))) Like link(IP-SENDTO)(ADDRESS_IP_SENDTO), but always uses IPv6.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6) nl() label(ADDRESS_IP_DATAGRAM)dit(bf(tt(IP-DATAGRAM:
:))) Sends outgoing data to the specified address which may in particular be a broadcast or multicast address. Packets arriving on the local socket are checked if their source addresses match link(RANGE)(OPTION_RANGE) or link(TCPWRAP)(OPTION_TCPWRAPPERS) options. This address type can for example be used for implementing symmetric or asymmetric broadcast or multicast communications.nl() Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET), link(IP4)(GROUP_IP4), link(IP6)(GROUP_IP6), link(RANGE)(GROUP_RANGE) nl() Useful options: link(bind)(OPTION_BIND), link(range)(OPTION_RANGE), link(tcpwrap)(OPTION_TCPWRAPPERS), link(broadcast)(OPTION_SO_BROADCAST), link(ip-multicast-loop)(OPTION_IP_MULTICAST_LOOP), link(ip-multicast-ttl)(OPTION_IP_MULTICAST_TTL), link(ip-multicast-if)(OPTION_IP_MULTICAST_IF), link(ip-add-membership)(OPTION_IP_ADD_MEMBERSHIP), link(ttl)(OPTION_TTL), link(tos)(OPTION_TOS), link(pf)(OPTION_PROTOCOL_FAMILY)nl() See also: link(IP4-DATAGRAM)(ADDRESS_IP4_DATAGRAM), link(IP6-DATAGRAM)(ADDRESS_IP6_DATAGRAM), link(IP-SENDTO)(ADDRESS_IP_SENDTO), link(IP-RECVFROM)(ADDRESS_IP_RECVFROM), link(IP-RECV)(ADDRESS_IP_RECV), link(UDP-DATAGRAM)(ADDRESS_UDP_DATAGRAM) label(ADDRESS_IP4_DATAGRAM)dit(bf(tt(IP4-DATAGRAM::))) Like link(IP-DATAGRAM)(ADDRESS_IP_DATAGRAM), but always uses IPv4. (link(example)(EXAMPLE_ADDRESS_IP4_BROADCAST_CLIENT))nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(RANGE)(GROUP_RANGE) nl() label(ADDRESS_IP6_DATAGRAM)dit(bf(tt(IP6-DATAGRAM::))) Like link(IP-DATAGRAM)(ADDRESS_IP_DATAGRAM), but always uses IPv6. Please note that IPv6 does not know broadcasts.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE) nl() label(ADDRESS_IP_RECVFROM)dit(bf(tt(IP-RECVFROM:))) Opens a raw IP socket of link()(TYPE_PROTOCOL). Depending on option link(pf)(OPTION_PROTOCOL_FAMILY), IP protocol version 4 or 6 is used. It receives one packet from an unspecified peer and may send one or more answer packets to that peer. This mode is particularly useful with fork option where each arriving packet - from arbitrary peers - is handled by its own sub process. This allows a behaviour similar to typical UDP based servers like ntpd or named.nl() Please note that the reply packets might be fetched as incoming traffic when sender and receiver IP address are identical because there is no port number to distinguish the sockets.nl() This address works well with IP-SENDTO address peers (see above). Protocol 255 uses the raw socket with the IP header being part of the data.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) nl() Useful options: link(pf)(OPTION_PROTOCOL_FAMILY), link(fork)(OPTION_FORK), link(range)(OPTION_RANGE), link(ttl)(OPTION_TTL), link(broadcast)(OPTION_SO_BROADCAST)nl() See also: link(IP4-RECVFROM)(ADDRESS_IP4_RECVFROM), link(IP6-RECVFROM)(ADDRESS_IP6_RECVFROM), link(IP-SENDTO)(ADDRESS_IP_SENDTO), link(IP-RECV)(ADDRESS_IP_RECV), link(UDP-RECVFROM)(ADDRESS_UDP_RECVFROM), link(UNIX-RECVFROM)(ADDRESS_UNIX_RECVFROM) label(ADDRESS_IP4_RECVFROM)dit(bf(tt(IP4-RECVFROM:))) Like link(IP-RECVFROM)(ADDRESS_IP_RECVFROM), but always uses IPv4.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) nl() label(ADDRESS_IP6_RECVFROM)dit(bf(tt(IP6-RECVFROM:))) Like link(IP-RECVFROM)(ADDRESS_IP_RECVFROM), but always uses IPv6.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) nl() label(ADDRESS_IP_RECV)dit(bf(tt(IP-RECV:))) Opens a raw IP socket of link()(TYPE_PROTOCOL). Depending on option link(pf)(OPTION_PROTOCOL_FAMILY), IP protocol version 4 or 6 is used. It receives packets from multiple unspecified peers and merges the data. No replies are possible. It can be, e.g., addressed by socat IP-SENDTO address peers. Protocol 255 uses the raw socket with the IP header being part of the data.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE) nl() Useful options: link(pf)(OPTION_PROTOCOL_FAMILY), link(range)(OPTION_RANGE)nl() See also: link(IP4-RECV)(ADDRESS_IP4_RECV), link(IP6-RECV)(ADDRESS_IP6_RECV), link(IP-SENDTO)(ADDRESS_IP_SENDTO), link(IP-RECVFROM)(ADDRESS_IP_RECVFROM), link(UDP-RECV)(ADDRESS_UDP_RECV), link(UNIX-RECV)(ADDRESS_UNIX_RECV) label(ADDRESS_IP4_RECV)dit(bf(tt(IP4-RECV:))) Like link(IP-RECV)(ADDRESS_IP_RECV), but always uses IPv4.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(RANGE)(GROUP_RANGE) nl() label(ADDRESS_IP6_RECV)dit(bf(tt(IP6-RECV:))) Like link(IP-RECV)(ADDRESS_IP_RECV), but always uses IPv6.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE) nl() label(ADDRESS_OPEN)dit(bf(tt(OPEN:))) Opens link()(TYPE_FILENAME) using the code(open()) system call (link(example)(EXAMPLE_ADDRESS_OPEN)). This operation fails on unixdomain() sockets. nl() Note: This address type is rarly useful in bidirectional mode.nl() Option groups: link(FD)(GROUP_FD),link(REG)(GROUP_REG),link(NAMED)(GROUP_NAMED),link(OPEN)(GROUP_OPEN) nl() Useful options: link(creat)(OPTION_O_CREAT), link(excl)(OPTION_EXCL), link(noatime)(OPTION_O_NOATIME), link(nofollow)(OPTION_NOFOLLOW), link(append)(OPTION_APPEND), link(rdonly)(OPTION_RDONLY), link(wronly)(OPTION_WRONLY), link(lock)(OPTION_LOCK), link(readbytes)(OPTION_READBYTES), link(ignoreeof)(OPTION_IGNOREEOF)nl() See also: link(CREATE)(ADDRESS_CREAT), link(GOPEN)(ADDRESS_GOPEN), link(UNIX-CONNECT)(ADDRESS_UNIX_CONNECT) label(ADDRESS_OPENSSL_CONNECT)dit(bf(tt(OPENSSL::))) Tries to establish a SSL connection to [link(TCP service)(TYPE_TCP_SERVICE)] on [link(IP address)(TYPE_IP_ADDRESS)] using TCP/IP version 4 or 6 depending on address specification, name resolution, or option link(pf)(OPTION_PROTOCOL_FAMILY).nl() NOTE: Up to version 1.7.2.4 the server certificate was only checked for validity against the system certificate store or link(cafile)(OPTION_OPENSSL_CAFILE) or link(capath)(OPTION_OPENSSL_CAPATH), but not for match with the server's name or its IP address. Since version 1.7.3.0 socat checks the peer certificate for match with the parameter or the value of the link(openssl-commonname)(OPTION_OPENSSL_COMMONNAME) option. Socat tries to match it against the certificates subject commonName, and the certifications extension subjectAltName DNS names. Wildcards in the certificate are supported.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(OPENSSL)(GROUP_OPENSSL),link(RETRY)(GROUP_RETRY) nl() Useful options: link(cipher)(OPTION_OPENSSL_CIPHERLIST), link(method)(OPTION_OPENSSL_METHOD), link(verify)(OPTION_OPENSSL_VERIFY), link(commonname)(OPTION_OPENSSL_COMMONNAME) link(cafile)(OPTION_OPENSSL_CAFILE), link(capath)(OPTION_OPENSSL_CAPATH), link(certificate)(OPTION_OPENSSL_CERTIFICATE), link(key)(OPTION_OPENSSL_KEY), link(compress)(OPTION_OPENSSL_COMPRESS), link(bind)(OPTION_BIND), link(pf)(OPTION_PROTOCOL_FAMILY), link(connect-timeout)(OPTION_CONNECT_TIMEOUT), link(sourceport)(OPTION_SOURCEPORT), link(retry)(OPTION_RETRY)nl() See also: link(OPENSSL-LISTEN)(ADDRESS_OPENSSL_LISTEN), link(TCP)(ADDRESS_TCP_CONNECT) label(ADDRESS_OPENSSL_LISTEN)dit(bf(tt(OPENSSL-LISTEN:))) Listens on tcp [link(TCP service)(TYPE_TCP_SERVICE)]. The IP version is 4 or the one specified with link(pf)(OPTION_PROTOCOL_FAMILY). When a connection is accepted, this address behaves as SSL server.nl() Note: You probably want to use the link(certificate)(OPTION_OPENSSL_CERTIFICATE) option with this address.nl() NOTE: The client certificate is only checked for validity against link(cafile)(OPTION_OPENSSL_CAFILE) or link(capath)(OPTION_OPENSSL_CAPATH), but not for match with the client's name or its IP address!nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(LISTEN)(GROUP_LISTEN),link(OPENSSL)(GROUP_OPENSSL),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(RETRY)(GROUP_RETRY) nl() Useful options: link(pf)(OPTION_PROTOCOL_FAMILY), link(cipher)(OPTION_OPENSSL_CIPHERLIST), link(method)(OPTION_OPENSSL_METHOD), link(verify)(OPTION_OPENSSL_VERIFY), link(commonname)(OPTION_OPENSSL_COMMONNAME) link(cafile)(OPTION_OPENSSL_CAFILE), link(capath)(OPTION_OPENSSL_CAPATH), link(certificate)(OPTION_OPENSSL_CERTIFICATE), link(key)(OPTION_OPENSSL_KEY), link(compress)(OPTION_OPENSSL_COMPRESS), link(fork)(OPTION_FORK), link(bind)(OPTION_BIND), link(range)(OPTION_RANGE), link(tcpwrap)(OPTION_TCPWRAPPERS), link(su)(OPTION_SUBSTUSER), link(reuseaddr)(OPTION_REUSEADDR), link(retry)(OPTION_RETRY)nl() See also: link(OPENSSL)(ADDRESS_OPENSSL_CONNECT), link(TCP-LISTEN)(ADDRESS_TCP_LISTEN) label(ADDRESS_NAMED_PIPE)dit(bf(tt(PIPE:))) If link()(TYPE_FILENAME) already exists, it is opened. If it does not exist, a named pipe is created and opened. Beginning with socat version 1.4.3, the named pipe is removed when the address is closed (but see option link(unlink-close)(OPTION_UNLINK_CLOSE)nl() Note: When a pipe is used for both reading and writing, it works as echo service.nl() Note: When a pipe is used for both reading and writing, and socat tries to write more bytes than the pipe can buffer (Linux 2.4: 2048 bytes), socat might block. Consider using socat option, e.g., code(-b 2048) nl() Option groups: link(FD)(GROUP_FD),link(NAMED)(GROUP_NAMED),link(OPEN)(GROUP_OPEN) nl() Useful options: link(rdonly)(OPTION_RDONLY), link(nonblock)(OPTION_NONBLOCK), link(group)(OPTION_GROUP), link(user)(OPTION_USER), link(mode)(OPTION_MODE), link(unlink-early)(OPTION_UNLINK_EARLY)nl() See also: link(unnamed pipe)(ADDRESS_UNNAMED_PIPE) label(ADDRESS_UNNAMED_PIPE)dit(bf(tt(PIPE))) Creates an unnamed pipe and uses it for reading and writing. It works as an echo, because everything written to it appeares immediately as read data.nl() Note: When socat tries to write more bytes than the pipe can queue (Linux 2.4: 2048 bytes), socat might block. Consider, e.g., using option code(-b 2048) nl() Option groups: link(FD)(GROUP_FD) nl() See also: link(named pipe)(ADDRESS_NAMED_PIPE) label(ADDRESS_PROXY_CONNECT)dit(bf(tt(PROXY:::))) Connects to an HTTP proxy server on port 8080 using TCP/IP version 4 or 6 depending on address specification, name resolution, or option link(pf)(OPTION_PROTOCOL_FAMILY), and sends a CONNECT request for hostname:port. If the proxy grants access and succeeds to connect to the target, data transfer between socat and the target can start. Note that the traffic need not be HTTP but can be an arbitrary protocol. nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(HTTP)(GROUP_HTTP),link(RETRY)(GROUP_RETRY) nl() Useful options: link(proxyport)(OPTION_PROXYPORT), link(ignorecr)(OPTION_IGNORECR), link(proxyauth)(OPTION_PROXY_AUTHORIZATION), link(resolve)(OPTION_PROXY_RESOLVE), link(crnl)(OPTION_CRNL), link(bind)(OPTION_BIND), link(connect-timeout)(OPTION_CONNECT_TIMEOUT), link(mss)(OPTION_MSS), link(sourceport)(OPTION_SOURCEPORT), link(retry)(OPTION_RETRY) nl() See also: link(SOCKS)(ADDRESS_SOCKS4), link(TCP)(ADDRESS_TCP_CONNECT) label(ADDRESS_PTY)dit(bf(tt(PTY))) Generates a pseudo terminal (pty) and uses its master side. Another process may open the pty's slave side using it like a serial line or terminal. (link(example)(EXAMPLE_ADDRESS_PTY)). If both the ptmx and the openpty mechanisms are available, ptmx is used (POSIX).nl() Option groups: link(FD)(GROUP_FD),link(NAMED)(GROUP_NAMED),link(PTY)(GROUP_PTY),link(TERMIOS)(GROUP_TERMIOS) nl() Useful options: link(link)(OPTION_SYMBOLIC_LINK), link(openpty)(OPTION_OPENPTY), link(wait-slave)(OPTION_PTY_WAIT_SLAVE), link(mode)(OPTION_MODE), link(user)(OPTION_USER), link(group)(OPTION_GROUP)nl() See also: link(UNIX-LISTEN)(ADDRESS_UNIX_LISTEN), link(PIPE)(ADDRESS_NAMED_PIPE), link(EXEC)(ADDRESS_EXEC), link(SYSTEM)(ADDRESS_SYSTEM) label(ADDRESS_READLINE)dit(bf(tt(READLINE))) Uses GNU readline and history on stdio to allow editing and reusing input lines (link(example)(EXAMPLE_ADDRESS_READLINE)). This requires the GNU readline and history libraries. Note that stdio should be a (pseudo) terminal device, otherwise readline does not seem to work.nl() Option groups: link(FD)(GROUP_FD),link(READLINE)(GROUP_READLINE),link(TERMIOS)(GROUP_TERMIOS) nl() Useful options: link(history)(OPTION_HISTORY), link(noecho)(OPTION_NOECHO)nl() See also: link(STDIO)(ADDRESS_STDIO) label(ADDRESS_SCTP_CONNECT)dit(bf(tt(SCTP-CONNECT::))) Establishes an SCTP stream connection to the specified [link(IP address)(TYPE_IP_ADDRESS)] and [link(TCP service)(TYPE_TCP_SERVICE)] using TCP/IP version 4 or 6 depending on address specification, name resolution, or option link(pf)(OPTION_PROTOCOL_FAMILY).nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(SCTP)(GROUP_SCTP),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl() Useful options: link(bind)(OPTION_BIND), link(pf)(OPTION_PROTOCOL_FAMILY), link(connect-timeout)(OPTION_CONNECT_TIMEOUT), link(tos)(OPTION_TOS), link(mtudiscover)(OPTION_MTUDISCOVER), link(sctp-maxseg)(OPTION_SCTP_MAXSEG), link(sctp-nodelay)(OPTION_SCTP_NODELAY), link(nonblock)(OPTION_NONBLOCK), link(sourceport)(OPTION_SOURCEPORT), link(retry)(OPTION_RETRY), link(readbytes)(OPTION_READBYTES)nl() See also: link(SCTP4-CONNECT)(ADDRESS_SCTP4_CONNECT), link(SCTP6-CONNECT)(ADDRESS_SCTP6_CONNECT), link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN), link(TCP-CONNECT)(ADDRESS_TCP_CONNECT) label(ADDRESS_SCTP4_CONNECT)dit(bf(tt(SCTP4-CONNECT::))) Like link(SCTP-CONNECT)(ADDRESS_SCTP_CONNECT), but only supports IPv4 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(SCTP)(GROUP_SCTP),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_SCTP6_CONNECT)dit(bf(tt(SCTP6-CONNECT::))) Like link(SCTP-CONNECT)(ADDRESS_SCTP_CONNECT), but only supports IPv6 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6),link(SCTP)(GROUP_SCTP),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_SCTP_LISTEN)dit(bf(tt(SCTP-LISTEN:))) Listens on [link(TCP service)(TYPE_TCP_SERVICE)] and accepts a TCP/IP connection. The IP version is 4 or the one specified with address option link(pf)(OPTION_PROTOCOL_FAMILY), socat option (link(-4)(option_4), link(-6)(option_6)), or environment variable link(SOCAT_DEFAULT_LISTEN_IP)(ENV_SOCAT_DEFAULT_LISTEN_IP). Note that opening this address usually blocks until a client connects.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(SCTP)(GROUP_SCTP),link(RETRY)(GROUP_RETRY) nl() Useful options: link(crnl)(OPTION_CRNL), link(fork)(OPTION_FORK), link(bind)(OPTION_BIND), link(range)(OPTION_RANGE), link(tcpwrap)(OPTION_TCPWRAPPERS), link(pf)(OPTION_PROTOCOL_FAMILY), link(max-children)(OPTION_MAX_CHILDREN), link(backlog)(OPTION_BACKLOG), link(sctp-maxseg)(OPTION_SCTP_MAXSEG), link(sctp-nodelay)(OPTION_SCTP_NODELAY), link(su)(OPTION_SUBSTUSER), link(reuseaddr)(OPTION_REUSEADDR), link(retry)(OPTION_RETRY), link(cool-write)(OPTION_COOL_WRITE)nl() See also: link(SCTP4-LISTEN)(ADDRESS_SCTP4_LISTEN), link(SCTP6-LISTEN)(ADDRESS_SCTP6_LISTEN), link(TCP-LISTEN)(ADDRESS_TCP_LISTEN), link(SCTP-CONNECT)(ADDRESS_SCTP_CONNECT) label(ADDRESS_SCTP4_LISTEN)dit(bf(tt(SCTP4-LISTEN:))) Like link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN), but only supports IPv4 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP4)(GROUP_IP4),link(SCTP)(GROUP_SCTP),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_SCTP6_LISTEN)dit(bf(tt(SCTP6-LISTEN:))) Like link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN), but only supports IPv6 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP6)(GROUP_IP6),link(SCTP)(GROUP_SCTP),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_SOCKET_CONNECT)dit(bf(tt(SOCKET-CONNECT:::))) Creates a stream socket using the first and second given socket parameters and tt(SOCK_STREAM) (see man socket\(2)) and connects to the remote-address. The two socket parameters have to be specified by link(int)(TYPE_INT) numbers. Consult your OS documentation and include files to find the appropriate values. The remote-address must be the link(data)(TYPE_DATA) representation of a sockaddr structure without sa_family and (BSD) sa_len components.nl() Please note that you can - beyond the options of the specified groups - also use options of higher level protocols when you apply socat option link(-g)(option_g).nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY)nl() Useful options: link(bind)(OPTION_BIND), link(setsockopt-int)(OPTION_SETSOCKOPT_INT), link(setsockopt-bin)(OPTION_SETSOCKOPT_BIN), link(setsockopt-string)(OPTION_SETSOCKOPT_STRING) nl() See also: link(TCP)(ADDRESS_TCP_CONNECT), link(UDP-CONNECT)(ADDRESS_UDP_CONNECT), link(UNIX-CONNECT)(ADDRESS_UNIX_CONNECT), link(SOCKET-LISTEN)(ADDRESS_SOCKET_LISTEN), link(SOCKET-SENDTO)(ADDRESS_SOCKET_SENDTO) label(ADDRESS_SOCKET_DATAGRAM)dit(bf(tt(SOCKET-DATAGRAM::::))) Creates a datagram socket using the first three given socket parameters (see man socket\(2)) and sends outgoing data to the remote-address. The three socket parameters have to be specified by link(int)(TYPE_INT) numbers. Consult your OS documentation and include files to find the appropriate values. The remote-address must be the link(data)(TYPE_DATA) representation of a sockaddr structure without sa_family and (BSD) sa_len components.nl() Please note that you can - beyond the options of the specified groups - also use options of higher level protocols when you apply socat option link(-g)(option_g).nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(RANGE)(GROUP_RANGE)nl() Useful options: link(bind)(OPTION_BIND), link(range)(OPTION_RANGE), link(setsockopt-int)(OPTION_SETSOCKOPT_INT), link(setsockopt-bin)(OPTION_SETSOCKOPT_BIN), link(setsockopt-string)(OPTION_SETSOCKOPT_STRING) nl() See also: link(UDP-DATAGRAM)(ADDRESS_UDP_DATAGRAM), link(IP-DATAGRAM)(ADDRESS_IP_DATAGRAM), link(SOCKET-SENDTO)(ADDRESS_SOCKET_SENDTO), link(SOCKET-RECV)(ADDRESS_SOCKET_RECV), link(SOCKET-RECVFROM)(ADDRESS_SOCKET_RECVFROM) label(ADDRESS_SOCKET_LISTEN)dit(bf(tt(SOCKET-LISTEN:::))) Creates a stream socket using the first and second given socket parameters and tt(SOCK_STREAM) (see man socket\(2)) and waits for incoming connections on local-address. The two socket parameters have to be specified by link(int)(TYPE_INT) numbers. Consult your OS documentation and include files to find the appropriate values. The local-address must be the link(data)(TYPE_DATA) representation of a sockaddr structure without sa_family and (BSD) sa_len components.nl() Please note that you can - beyond the options of the specified groups - also use options of higher level protocols when you apply socat option link(-g)(option_g).nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(RANGE)(GROUP_RANGE),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY)nl() Useful options: link(setsockopt-int)(OPTION_SETSOCKOPT_INT), link(setsockopt-bin)(OPTION_SETSOCKOPT_BIN), link(setsockopt-string)(OPTION_SETSOCKOPT_STRING) nl() See also: link(TCP)(ADDRESS_TCP_LISTEN), link(UDP-CONNECT)(ADDRESS_UDP_LISTEN), link(UNIX-CONNECT)(ADDRESS_UNIX_LISTEN), link(SOCKET-LISTEN)(ADDRESS_SOCKET_CONNECT), link(SOCKET-SENDTO)(ADDRESS_SOCKET_RECVFROM), link(SOCKET-SENDTO)(ADDRESS_SOCKET_RECV) label(ADDRESS_SOCKET_RECV)dit(bf(tt(SOCKET-RECV::::))) Creates a socket using the three given socket parameters (see man socket\(2)) and binds it to . Receives arriving data. The three parameters have to be specified by link(int)(TYPE_INT) numbers. Consult your OS documentation and include files to find the appropriate values. The local-address must be the link(data)(TYPE_DATA) representation of a sockaddr structure without sa_family and (BSD) sa_len components.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(RANGE)(GROUP_RANGE)nl() Useful options: link(range)(OPTION_RANGE), link(setsockopt-int)(OPTION_SETSOCKOPT_INT), link(setsockopt-bin)(OPTION_SETSOCKOPT_BIN), link(setsockopt-string)(OPTION_SETSOCKOPT_STRING) nl() See also: link(UDP-RECV)(ADDRESS_UDP_RECV), link(IP-RECV)(ADDRESS_IP_RECV), link(UNIX-RECV)(ADDRESS_UNIX_RECV), link(SOCKET-DATAGRAM)(ADDRESS_SOCKET_DATAGRAM), link(SOCKET-SENDTO)(ADDRESS_SOCKET_SENDTO), link(SOCKET-RECVFROM)(ADDRESS_SOCKET_RECVFROM) label(ADDRESS_SOCKET_RECVFROM)dit(bf(tt(SOCKET-RECVFROM::::))) Creates a socket using the three given socket parameters (see man socket\(2)) and binds it to . Receives arriving data and sends replies back to the sender. The first three parameters have to be specified as link(int)(TYPE_INT) numbers. Consult your OS documentation and include files to find the appropriate values. The local-address must be the link(data)(TYPE_DATA) representation of a sockaddr structure without sa_family and (BSD) sa_len components.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE)nl() Useful options: link(fork)(OPTION_FORK), link(range)(OPTION_RANGE), link(setsockopt-int)(OPTION_SETSOCKOPT_INT), link(setsockopt-bin)(OPTION_SETSOCKOPT_BIN), link(setsockopt-string)(OPTION_SETSOCKOPT_STRING) nl() See also: link(UDP-RECVFROM)(ADDRESS_UDP_RECVFROM), link(IP-RECVFROM)(ADDRESS_IP_RECVFROM), link(UNIX-RECVFROM)(ADDRESS_UNIX_RECVFROM), link(SOCKET-DATAGRAM)(ADDRESS_SOCKET_DATAGRAM), link(SOCKET-SENDTO)(ADDRESS_SOCKET_SENDTO), link(SOCKET-RECV)(ADDRESS_SOCKET_RECV) label(ADDRESS_SOCKET_SENDTO)dit(bf(tt(SOCKET-SENDTO::::))) Creates a socket using the three given socket parameters (see man socket\(2)). Sends outgoing data to the given address and receives replies. The three parameters have to be specified as link(int)(TYPE_INT) numbers. Consult your OS documentation and include files to find the appropriate values. The remote-address must be the link(data)(TYPE_DATA) representation of a sockaddr structure without sa_family and (BSD) sa_len components.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET)nl() Useful options: link(bind)(OPTION_BIND), link(setsockopt-int)(OPTION_SETSOCKOPT_INT), link(setsockopt-bin)(OPTION_SETSOCKOPT_BIN), link(setsockopt-string)(OPTION_SETSOCKOPT_STRING) nl() See also: link(UDP-SENDTO)(ADDRESS_UDP_SENDTO), link(IP-SENDTO)(ADDRESS_IP_SENDTO), link(UNIX-SENDTO)(ADDRESS_UNIX_SENDTO), link(SOCKET-DATAGRAM)(ADDRESS_SOCKET_DATAGRAM), link(SOCKET-RECV)(ADDRESS_SOCKET_RECV) link(SOCKET-RECVFROM)(ADDRESS_SOCKET_RECVFROM) label(ADDRESS_SOCKS4)dit(bf(tt(SOCKS4:::))) Connects via [link(IP address)(TYPE_IP_ADDRESS)] to [link(IPv4 address)(TYPE_IPV4_ADDRESS)] on [link(TCP service)(TYPE_TCP_SERVICE)], using socks version 4 protocol over IP version 4 or 6 depending on address specification, name resolution, or option link(pf)(OPTION_PROTOCOL_FAMILY) (link(example)(EXAMPLE_ADDRESS_SOCKS4)).nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(SOCKS4)(GROUP_SOCKS),link(RETRY)(GROUP_RETRY) nl() Useful options: link(socksuser)(OPTION_SOCKSUSER), link(socksport)(OPTION_SOCKSPORT), link(sourceport)(OPTION_SOURCEPORT), link(pf)(OPTION_PROTOCOL_FAMILY), link(retry)(OPTION_RETRY)nl() See also: link(SOCKS4A)(ADDRESS_SOCKS4A), link(PROXY)(ADDRESS_PROXY_CONNECT), link(TCP)(ADDRESS_TCP_CONNECT) label(ADDRESS_SOCKS4A)dit(bf(tt(SOCKS4A:::))) like link(SOCKS4)(ADDRESS_SOCKS4), but uses socks protocol version 4a, thus leaving host name resolution to the socks server.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(SOCKS4)(GROUP_SOCKS),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_STDERR)dit(bf(tt(STDERR))) Uses file descriptor 2.nl() Option groups: link(FD)(GROUP_FD) (link(TERMIOS)(GROUP_TERMIOS),link(REG)(GROUP_REG),link(SOCKET)(GROUP_SOCKET)) nl() See also: link(FD)(ADDRESS_FD) label(ADDRESS_STDIN)dit(bf(tt(STDIN))) Uses file descriptor 0.nl() Option groups: link(FD)(GROUP_FD) (link(TERMIOS)(GROUP_TERMIOS),link(REG)(GROUP_REG),link(SOCKET)(GROUP_SOCKET)) nl() Useful options: link(readbytes)(OPTION_READBYTES)nl() See also: link(FD)(ADDRESS_FD) label(ADDRESS_STDIO)dit(bf(tt(STDIO))) Uses file descriptor 0 for reading, and 1 for writing.nl() Option groups: link(FD)(GROUP_FD) (link(TERMIOS)(GROUP_TERMIOS),link(REG)(GROUP_REG),link(SOCKET)(GROUP_SOCKET)) nl() Useful options: link(readbytes)(OPTION_READBYTES)nl() See also: link(FD)(ADDRESS_FD) label(ADDRESS_STDOUT)dit(bf(tt(STDOUT))) Uses file descriptor 1.nl() Option groups: link(FD)(GROUP_FD) (link(TERMIOS)(GROUP_TERMIOS),link(REG)(GROUP_REG),link(SOCKET)(GROUP_SOCKET)) nl() See also: link(FD)(ADDRESS_FD) label(ADDRESS_SYSTEM)dit(bf(tt(SYSTEM:))) Forks a sub process that establishes communication with its parent process and invokes the specified program with code(system()). Please note that [link(string)(TYPE_STRING)] must not contain ',' or "!!", and that shell meta characters may have to be protected. After successful program start, socat() writes data to stdin of the process and reads from its stdout.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(EXEC)(GROUP_EXEC),link(FORK)(GROUP_FORK),link(TERMIOS)(GROUP_TERMIOS) nl() Useful options: link(path)(OPTION_PATH), link(fdin)(OPTION_FDIN), link(fdout)(OPTION_FDOUT), link(chroot)(OPTION_CHROOT), link(su)(OPTION_SUBSTUSER), link(su-d)(OPTION_SUBSTUSER_DELAYED), link(nofork)(OPTION_NOFORK), link(pty)(OPTION_PTY), link(stderr)(OPTION_STDERR), link(ctty)(OPTION_CTTY), link(setsid)(OPTION_SETSID), link(pipes)(OPTION_PIPES), link(sigint)(OPTION_SIGINT), link(sigquit)(OPTION_SIGQUIT)nl() See also: link(EXEC)(ADDRESS_EXEC) label(ADDRESS_TCP_CONNECT)dit(bf(tt(TCP::))) Connects to [link(TCP service)(TYPE_TCP_SERVICE)] on [link(IP address)(TYPE_IP_ADDRESS)] using TCP/IP version 4 or 6 depending on address specification, name resolution, or option link(pf)(OPTION_PROTOCOL_FAMILY).nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(RETRY)(GROUP_RETRY) nl() Useful options: link(crnl)(OPTION_CRNL), link(bind)(OPTION_BIND), link(pf)(OPTION_PROTOCOL_FAMILY), link(connect-timeout)(OPTION_CONNECT_TIMEOUT), link(tos)(OPTION_TOS), link(mtudiscover)(OPTION_MTUDISCOVER), link(mss)(OPTION_MSS), link(nodelay)(OPTION_NODELAY), link(nonblock)(OPTION_NONBLOCK), link(sourceport)(OPTION_SOURCEPORT), link(retry)(OPTION_RETRY), link(readbytes)(OPTION_READBYTES)nl() See also: link(TCP4)(ADDRESS_TCP4_CONNECT), link(TCP6)(ADDRESS_TCP6_CONNECT), link(TCP-LISTEN)(ADDRESS_TCP_LISTEN), link(UDP)(ADDRESS_UDP_CONNECT), link(SCTP-CONNECT)(ADDRESS_SCTP_CONNECT), link(UNIX-CONNECT)(ADDRESS_UNIX_CONNECT) label(ADDRESS_TCP4_CONNECT)dit(bf(tt(TCP4::))) Like link(TCP)(ADDRESS_TCP_CONNECT), but only supports IPv4 protocol (link(example)(EXAMPLE_ADDRESS_TCP4_CONNECT)).nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(TCP)(GROUP_TCP),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_TCP6_CONNECT)dit(bf(tt(TCP6::))) Like link(TCP)(ADDRESS_TCP_CONNECT), but only supports IPv6 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_TCP_LISTEN)dit(bf(tt(TCP-LISTEN:))) Listens on [link(TCP service)(TYPE_TCP_SERVICE)] and accepts a TCP/IP connection. The IP version is 4 or the one specified with address option link(pf)(OPTION_PROTOCOL_FAMILY), socat option (link(-4)(option_4), link(-6)(option_6)), or environment variable link(SOCAT_DEFAULT_LISTEN_IP)(ENV_SOCAT_DEFAULT_LISTEN_IP). Note that opening this address usually blocks until a client connects.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(RETRY)(GROUP_RETRY) nl() Useful options: link(crnl)(OPTION_CRNL), link(fork)(OPTION_FORK), link(bind)(OPTION_BIND), link(range)(OPTION_RANGE), link(tcpwrap)(OPTION_TCPWRAPPERS), link(pf)(OPTION_PROTOCOL_FAMILY), link(max-children)(OPTION_MAX_CHILDREN), link(backlog)(OPTION_BACKLOG), link(mss)(OPTION_MSS), link(su)(OPTION_SUBSTUSER), link(reuseaddr)(OPTION_REUSEADDR), link(retry)(OPTION_RETRY), link(cool-write)(OPTION_COOL_WRITE)nl() See also: link(TCP4-LISTEN)(ADDRESS_TCP4_LISTEN), link(TCP6-LISTEN)(ADDRESS_TCP6_LISTEN), link(UDP-LISTEN)(ADDRESS_UDP_LISTEN), link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN), link(UNIX-LISTEN)(ADDRESS_UNIX_LISTEN), link(OPENSSL-LISTEN)(ADDRESS_OPENSSL_LISTEN), link(TCP-CONNECT)(ADDRESS_TCP_CONNECT) label(ADDRESS_TCP4_LISTEN)dit(bf(tt(TCP4-LISTEN:))) Like link(TCP-LISTEN)(ADDRESS_TCP_LISTEN), but only supports IPv4 protocol (link(example)(EXAMPLE_ADDRESS_TCP4_LISTEN)).nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP4)(GROUP_IP4),link(TCP)(GROUP_TCP),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_TCP6_LISTEN)dit(bf(tt(TCP6-LISTEN:))) Like link(TCP-LISTEN)(ADDRESS_TCP_LISTEN), but only supports IPv6 protocol.nl() Additional useful option: link(ipv6only)(OPTION_IPV6_V6ONLY)nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_TUN)dit(bf(tt(TUN[:/]))) Creates a Linux TUN/TAP device and optionally assignes it the address and netmask given by the parameters. The resulting network interface is almost ready for use by other processes; socat serves its "wire side". This address requires read and write access to the tunnel cloning device, usually code(/dev/net/tun), as well as permission to set some tt(ioctl()s). bf(Option iff-up is required to immediately activate the interface!)nl() Option groups: link(FD)(GROUP_FD),link(NAMED)(GROUP_NAMED),link(OPEN)(GROUP_OPEN),link(TUN)(GROUP_TUN) nl() Useful options: link(iff-up)(OPTION_IFF_UP), link(tun-device)(OPTION_TUN_DEVICE), link(tun-name)(OPTION_TUN_NAME), link(tun-type)(OPTION_TUN_TYPE), link(iff-no-pi)(OPTION_IFF_NO_PI) nl() See also: link(ip-recv)(ADDRESS_IP_RECV) label(ADDRESS_UDP_CONNECT)dit(bf(tt(UDP::))) Connects to [link(UDP service)(TYPE_UDP_SERVICE)] on [link(IP address)(TYPE_IP_ADDRESS)] using UDP/IP version 4 or 6 depending on address specification, name resolution, or option link(pf)(OPTION_PROTOCOL_FAMILY).nl() Please note that, due to UDP protocol properties, no real connection is established; data has to be sent for `connecting' to the server, and no end-of-file condition can be transported.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6) nl() Useful options: link(ttl)(OPTION_TTL), link(tos)(OPTION_TOS), link(bind)(OPTION_BIND), link(sourceport)(OPTION_SOURCEPORT), link(pf)(OPTION_PROTOCOL_FAMILY)nl() See also: link(UDP4)(ADDRESS_UDP4_CONNECT), link(UDP6)(ADDRESS_UDP6_CONNECT), link(UDP-LISTEN)(ADDRESS_UDP_LISTEN), link(TCP)(ADDRESS_TCP_CONNECT), link(IP)(ADDRESS_IP_SENDTO) label(ADDRESS_UDP4_CONNECT)dit(bf(tt(UDP4::))) Like link(UDP)(ADDRESS_UDP_CONNECT), but only supports IPv4 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4) nl() label(ADDRESS_UDP6_CONNECT)dit(bf(tt(UDP6::))) Like link(UDP)(ADDRESS_UDP_CONNECT), but only supports IPv6 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6) nl() label(ADDRESS_UDP_DATAGRAM)dit(bf(tt(UDP-DATAGRAM:
:))) Sends outgoing data to the specified address which may in particular be a broadcast or multicast address. Packets arriving on the local socket are checked for the correct remote port and if their source addresses match link(RANGE)(OPTION_RANGE) or link(TCPWRAP)(OPTION_TCPWRAPPERS) options. This address type can for example be used for implementing symmetric or asymmetric broadcast or multicast communications.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE) nl() Useful options: link(bind)(OPTION_BIND), link(range)(OPTION_RANGE), link(tcpwrap)(OPTION_TCPWRAPPERS), link(broadcast)(OPTION_SO_BROADCAST), link(ip-multicast-loop)(OPTION_IP_MULTICAST_LOOP), link(ip-multicast-ttl)(OPTION_IP_MULTICAST_TTL), link(ip-multicast-if)(OPTION_IP_MULTICAST_IF), link(ip-add-membership)(OPTION_IP_ADD_MEMBERSHIP), link(ttl)(OPTION_TTL), link(tos)(OPTION_TOS), link(sourceport)(OPTION_SOURCEPORT), link(pf)(OPTION_PROTOCOL_FAMILY)nl() See also: link(UDP4-DATAGRAM)(ADDRESS_UDP4_DATAGRAM), link(UDP6-DATAGRAM)(ADDRESS_UDP6_DATAGRAM), link(UDP-SENDTO)(ADDRESS_UDP_SENDTO), link(UDP-RECVFROM)(ADDRESS_UDP_RECVFROM), link(UDP-RECV)(ADDRESS_UDP_RECV), link(UDP-CONNECT)(ADDRESS_UDP_CONNECT), link(UDP-LISTEN)(ADDRESS_UDP_LISTEN), link(IP-DATAGRAM)(ADDRESS_IP_DATAGRAM) label(ADDRESS_UDP4_DATAGRAM)dit(bf(tt(UDP4-DATAGRAM:
:))) Like link(UDP-DATAGRAM)(ADDRESS_UDP_DATAGRAM), but only supports IPv4 protocol (link(example1)(EXAMPLE_ADDRESS_UDP4_BROADCAST_CLIENT), link(example2)(EXAMPLE_ADDRESS_UDP4_MULTICAST)).nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4), link(RANGE)(GROUP_RANGE) label(ADDRESS_UDP6_DATAGRAM)dit(bf(tt(UDP6-DATAGRAM:
:))) Like link(UDP-DATAGRAM)(ADDRESS_UDP_DATAGRAM), but only supports IPv6 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE) label(ADDRESS_UDP_LISTEN)dit(bf(tt(UDP-LISTEN:))) Waits for a UDP/IP packet arriving on [link(UDP service)(TYPE_UDP_SERVICE)] and `connects' back to sender. The accepted IP version is 4 or the one specified with option link(pf)(OPTION_PROTOCOL_FAMILY). Please note that, due to UDP protocol properties, no real connection is established; data has to arrive from the peer first, and no end-of-file condition can be transported. Note that opening this address usually blocks until a client connects.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6) nl() Useful options: link(fork)(OPTION_FORK), link(bind)(OPTION_BIND), link(range)(OPTION_RANGE), link(pf)(OPTION_PROTOCOL_FAMILY) nl() See also: link(UDP)(ADDRESS_UDP_CONNECT), link(UDP4-LISTEN)(ADDRESS_UDP4_LISTEN), link(UDP6-LISTEN)(ADDRESS_UDP6_LISTEN), link(TCP-LISTEN)(ADDRESS_TCP_LISTEN) label(ADDRESS_UDP4_LISTEN)dit(bf(tt(UDP4-LISTEN:))) Like link(UDP-LISTEN)(ADDRESS_UDP_LISTEN), but only support IPv4 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP4)(GROUP_IP4) nl() label(ADDRESS_UDP6_LISTEN)dit(bf(tt(UDP6-LISTEN:))) Like link(UDP-LISTEN)(ADDRESS_UDP_LISTEN), but only support IPv6 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP6)(GROUP_IP6) nl() label(ADDRESS_UDP_SENDTO)dit(bf(tt(UDP-SENDTO::))) Communicates with the specified peer socket, defined by [link(UDP service)(TYPE_UDP_SERVICE)] on [link(IP address)(TYPE_IP_ADDRESS)], using UDP/IP version 4 or 6 depending on address specification, name resolution, or option link(pf)(OPTION_PROTOCOL_FAMILY). It sends packets to and receives packets from that peer socket only. This address effectively implements a datagram client. It works well with socat UDP-RECVFROM and UDP-RECV address peers.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6) nl() Useful options: link(ttl)(OPTION_TTL), link(tos)(OPTION_TOS), link(bind)(OPTION_BIND), link(sourceport)(OPTION_SOURCEPORT), link(pf)(OPTION_PROTOCOL_FAMILY)nl() See also: link(UDP4-SENDTO)(ADDRESS_UDP4_SENDTO), link(UDP6-SENDTO)(ADDRESS_UDP6_SENDTO), link(UDP-RECVFROM)(ADDRESS_UDP_RECVFROM), link(UDP-RECV)(ADDRESS_UDP_RECV), link(UDP-CONNECT)(ADDRESS_UDP_CONNECT), link(UDP-LISTEN)(ADDRESS_UDP_LISTEN), link(IP-SENDTO)(ADDRESS_IP_SENDTO) label(ADDRESS_UDP4_SENDTO)dit(bf(tt(UDP4-SENDTO::))) Like link(UDP-SENDTO)(ADDRESS_UDP_SENDTO), but only supports IPv4 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4) label(ADDRESS_UDP6_SENDTO)dit(bf(tt(UDP6-SENDTO::))) Like link(UDP-SENDTO)(ADDRESS_UDP_SENDTO), but only supports IPv6 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6) label(ADDRESS_UDP_RECVFROM)dit(bf(tt(UDP-RECVFROM:))) Creates a UDP socket on [link(UDP service)(TYPE_UDP_SERVICE)] using UDP/IP version 4 or 6 depending on option link(pf)(OPTION_PROTOCOL_FAMILY). It receives one packet from an unspecified peer and may send one or more answer packets to that peer. This mode is particularly useful with fork option where each arriving packet - from arbitrary peers - is handled by its own sub process. This allows a behaviour similar to typical UDP based servers like ntpd or named. This address works well with socat UDP-SENDTO address peers.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) nl() Useful options: link(fork)(OPTION_FORK), link(ttl)(OPTION_TTL), link(tos)(OPTION_TOS), link(bind)(OPTION_BIND), link(sourceport)(OPTION_SOURCEPORT), link(pf)(OPTION_PROTOCOL_FAMILY)nl() See also: link(UDP4-RECVFROM)(ADDRESS_UDP4_RECVFROM), link(UDP6-RECVFROM)(ADDRESS_UDP6_RECVFROM), link(UDP-SENDTO)(ADDRESS_UDP_SENDTO), link(UDP-RECV)(ADDRESS_UDP_RECV), link(UDP-CONNECT)(ADDRESS_UDP_CONNECT), link(UDP-LISTEN)(ADDRESS_UDP_LISTEN), link(IP-RECVFROM)(ADDRESS_IP_RECVFROM), link(UNIX-RECVFROM)(ADDRESS_UNIX_RECVFROM) label(ADDRESS_UDP4_RECVFROM)dit(bf(tt(UDP4-RECVFROM:))) Like link(UDP-RECVFROM)(ADDRESS_UDP_RECVFROM), but only supports IPv4 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) label(ADDRESS_UDP6_RECVFROM)dit(bf(tt(UDP6-RECVFROM:))) Like link(UDP-RECVFROM)(ADDRESS_UDP_RECVFROM), but only supports IPv6 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) label(ADDRESS_UDP_RECV)dit(bf(tt(UDP-RECV:))) Creates a UDP socket on [link(UDP service)(TYPE_UDP_SERVICE)] using UDP/IP version 4 or 6 depending on option link(pf)(OPTION_PROTOCOL_FAMILY). It receives packets from multiple unspecified peers and merges the data. No replies are possible. It works well with, e.g., socat UDP-SENDTO address peers; it behaves similar to a syslog server.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE) nl() Useful options: link(fork)(OPTION_FORK), link(pf)(OPTION_PROTOCOL_FAMILY), link(bind)(OPTION_BIND), link(sourceport)(OPTION_SOURCEPORT), link(ttl)(OPTION_TTL), link(tos)(OPTION_TOS)nl() See also: link(UDP4-RECV)(ADDRESS_UDP4_RECV), link(UDP6-RECV)(ADDRESS_UDP6_RECV), link(UDP-SENDTO)(ADDRESS_UDP_SENDTO), link(UDP-RECVFROM)(ADDRESS_UDP_RECVFROM), link(UDP-CONNECT)(ADDRESS_UDP_CONNECT), link(UDP-LISTEN)(ADDRESS_UDP_LISTEN), link(IP-RECV)(ADDRESS_IP_RECV), link(UNIX-RECV)(ADDRESS_UNIX_RECV) label(ADDRESS_UDP4_RECV)dit(bf(tt(UDP4-RECV:))) Like link(UDP-RECV)(ADDRESS_UDP_RECV), but only supports IPv4 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(RANGE)(GROUP_RANGE) label(ADDRESS_UDP6_RECV)dit(bf(tt(UDP6-RECV:))) Like link(UDP-RECV)(ADDRESS_UDP_RECV), but only supports IPv6 protocol.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE) label(ADDRESS_UNIX_CONNECT)dit(bf(tt(UNIX-CONNECT:))) Connects to link()(TYPE_FILENAME) assuming it is a unixdomain() socket. If does not exist, this is an error; if is not a unixdomain() socket, this is an error; if is a unixdomain() socket, but no process is listening, this is an error.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(RETRY)(GROUP_RETRY),link(UNIX)(GROUP_SOCK_UNIX) nl()) Useful options: link(bind)(OPTION_BIND)nl() See also: link(UNIX-LISTEN)(ADDRESS_UNIX_LISTEN), link(UNIX-SENDTO)(ADDRESS_UNIX_SENDTO), link(TCP)(ADDRESS_TCP_CONNECT) label(ADDRESS_UNIX_LISTEN)dit(bf(tt(UNIX-LISTEN:))) Listens on link()(TYPE_FILENAME) using a unixdomain() stream socket and accepts a connection. If exists and is not a socket, this is an error. If exists and is a unixdomain() socket, binding to the address fails (use option link(unlink-early)(OPTION_UNLINK_EARLY)!). Note that opening this address usually blocks until a client connects. Beginning with socat version 1.4.3, the file system entry is removed when this address is closed (but see option link(unlink-close)(OPTION_UNLINK_CLOSE)) (link(example)(EXAMPLE_ADDRESS_UNIX_LISTEN)).nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY),link(UNIX)(GROUP_SOCK_UNIX) nl() Useful options: link(fork)(OPTION_FORK), link(umask)(OPTION_UMASK), link(mode)(OPTION_MODE), link(user)(OPTION_USER), link(group)(OPTION_GROUP), link(unlink-early)(OPTION_UNLINK_EARLY)nl() See also: link(UNIX-CONNECT)(ADDRESS_UNIX_CONNECT), link(UNIX-RECVFROM)(ADDRESS_UNIX_RECVFROM), link(UNIX-RECV)(ADDRESS_UNIX_RECV), link(TCP-LISTEN)(ADDRESS_TCP4_LISTEN) label(ADDRESS_UNIX_SENDTO)dit(bf(tt(UNIX-SENDTO:))) Communicates with the specified peer socket, defined by [link()(TYPE_FILENAME)] assuming it is a unixdomain() datagram socket. It sends packets to and receives packets from that peer socket only. Please note that it might be neccessary to link(bind)(OPTION_BIND) the local socket to an address (e.g. tt(/tmp/sock1), which must not exist before). This address type works well with socat UNIX-RECVFROM and UNIX-RECV address peers.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(UNIX)(GROUP_SOCK_UNIX)nl() Useful options: link(bind)(OPTION_BIND)nl() See also: link(UNIX-RECVFROM)(ADDRESS_UNIX_RECVFROM), link(UNIX-RECV)(ADDRESS_UNIX_RECV), link(UNIX-CONNECT)(ADDRESS_UNIX_CONNECT), link(UDP-SENDTO)(ADDRESS_UDP_SENDTO), link(IP-SENDTO)(ADDRESS_IP_SENDTO) label(ADDRESS_UNIX_RECVFROM)dit(bf(tt(UNIX-RECVFROM:))) Creates a unixdomain() datagram socket [link()(TYPE_FILENAME)]. Receives one packet and may send one or more answer packets to that peer. This mode is particularly useful with fork option where each arriving packet - from arbitrary peers - is handled by its own sub process. This address works well with socat UNIX-SENDTO address peers.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(CHILD)(GROUP_CHILD),link(UNIX)(GROUP_SOCK_UNIX) nl() Useful options: link(fork)(OPTION_FORK)nl() See also: link(UNIX-SENDTO)(ADDRESS_UNIX_SENDTO), link(UNIX-RECV)(ADDRESS_UNIX_RECV), link(UNIX-LISTEN)(ADDRESS_UNIX_LISTEN), link(UDP-RECVFROM)(ADDRESS_UDP_RECVFROM), link(IP-RECVFROM)(ADDRESS_IP_RECVFROM) label(ADDRESS_UNIX_RECV)dit(bf(tt(UNIX-RECV:))) Creates a unixdomain() datagram socket [link()(TYPE_FILENAME)]. Receives packets from multiple unspecified peers and merges the data. No replies are possible. It can be, e.g., addressed by socat UNIX-SENDTO address peers. It behaves similar to a syslog server. Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(UNIX)(GROUP_SOCK_UNIX) nl() See also: link(UNIX-SENDTO)(ADDRESS_UNIX_SENDTO), link(UNIX-RECVFROM)(ADDRESS_UNIX_RECVFROM), link(UNIX-LISTEN)(ADDRESS_UNIX_LISTEN), link(UDP-RECV)(ADDRESS_UDP_RECV), link(IP-RECV)(ADDRESS_IP_RECV) label(ADDRESS_UNIX_CLIENT)dit(bf(tt(UNIX-CLIENT:))) Communicates with the specified peer socket, defined by [link()(TYPE_FILENAME)] assuming it is a unixdomain() socket. It first tries to connect and, if that fails, assumes it is a datagram socket, thus supporting both types.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(UNIX)(GROUP_SOCK_UNIX) nl() Useful options: link(bind)(OPTION_BIND)nl() See also: link(UNIX-CONNECT)(ADDRESS_UNIX_CONNECT), link(UNIX-SENDTO)(ADDRESS_UNIX_SENDTO), link(GOPEN)(ADDRESS_GOPEN) dit(bf(tt(ABSTRACT-CONNECT:))) dit(bf(tt(ABSTRACT-LISTEN:))) dit(bf(tt(ABSTRACT-SENDTO:))) dit(bf(tt(ABSTRACT-RECVFROM:))) dit(bf(tt(ABSTRACT-RECV:))) dit(bf(tt(ABSTRACT-CLIENT:))) The ABSTRACT addresses are almost identical to the related UNIX addresses except that they do not address file system based sockets but an alternate unixdomain() address space. To archieve this the socket address strings are prefixed with "\0" internally. This feature is available (only?) on Linux. Option groups are the same as with the related UNIX addresses, except that the ABSTRACT addresses are not member of the NAMED group. enddit() label(ADDRESS_OPTIONS) manpagesection(ADDRESS OPTIONS) Address options can be applied to address specifications to influence the process of opening the addresses and the properties of the resulting data channels. For technical reasons not every option can be applied to every address type; e.g., applying a socket option to a regular file will fail. To catch most useless combinations as early as in the open phase, the concept of em(option groups) was introduced. Each option belongs to one or more option groups. Options can be used only with address types that support at least one of their option groups (but see link(option -g)(option_g)). Address options have data types that their values must conform to. Every address option consists of just a keyword or a keyword followed by "=value", where value must conform to the options type. COMMENT(Options that trigger a call with trivial parameters are described with type BOOL which might be misleading.) Some address options manipulate parameters of system calls; e.g., option sync sets the code(O_SYNC) flag with the code(open()) call. Other options cause a system or library call; e.g., with option `ttl=value' the code(setsockopt(fd, SOL_IP, IP_TTL, value, sizeof(int))) call is applied. Other options set internal socat() variables that are used during data transfer; e.g., `crnl' causes explicit character conversions. A few options have more complex implementations; e.g., su-d (substuser-delayed) inquires some user and group infos, stores them, and applies them later after a possible code(chroot()) call. If multiple options are given to an address, their sequence in the address specification has (almost) no effect on the sequence of their execution/application. Instead, socat() has built in an em(option phase) model that tries to bring the options in a useful order. Some options exist in different forms (e.g., unlink, unlink-early, unlink-late) to control the time of their execution. If the same option is specified more than once within one address specification, with equal or different values, the effect depends on the kind of option. Options resulting in function calls like code(setsockopt()) cause multiple invocations. With options that set parameters for a required call like code(open()) or set internal flags, the value of the last option occurrence is effective. The existence or semantics of many options are system dependent. Socat() usually does NOT try to emulate missing libc or kernel features, it just provides an interface to the underlying system. So, if an operating system lacks a feature, the related option is simply not available on this platform. The following paragraphs introduce just the more common address options. For a more comprehensive reference and to find information about canonical option names, alias names, option phases, and platforms see file file(xio.help). nl() nl() startdit()enddit()nl() label(GROUP_FD)em(bf(FD option group)) This option group contains options that are applied to a unix() style file descriptor, no matter how it was generated. Because all current socat() address types are file descriptor based, these options may be applied to any address. nl() Note: Some of these options are also member of another option group, that provides an other, non-fd based mechanism. For these options, it depends on the actual address type and its option groups which mechanism is used. The second, non-fd based mechanism is prioritized. startdit() label(OPTION_CLOEXEC)dit(bf(tt(cloexec=))) Sets the code(FD_CLOEXEC) flag with the code(fcntl()) system call to value link()(TYPE_BOOL). If set, the file descriptor is closed on code(exec()) family function calls. Socat() internally handles this flag for the fds it controls, so in most cases there will be no need to apply this option. label(OPTION_SETLK_WR)dit(bf(tt(setlk))) Tries to set a discretionary write lock to the whole file using the code(fcntl(fd, F_SETLK, ...)) system call. If the file is already locked, this call results in an error. On Linux, when the file permissions for group are "S" (g-x,g+s), and the file system is locally mounted with the "mand" option, the lock is mandatory, i.e. prevents other processes from opening the file. label(OPTION_SETLKW_WR)dit(bf(tt(setlkw))) Tries to set a discretionary waiting write lock to the whole file using the code(fcntl(fd, F_SETLKW, ...)) system call. If the file is already locked, this call blocks. See option link(setlk)(OPTION_SETLK_WR) for information about making this lock mandatory. label(OPTION_SETLK_RD)dit(bf(tt(setlk-rd))) Tries to set a discretionary read lock to the whole file using the code(fcntl(fd, F_SETLK, ...)) system call. If the file is already write locked, this call results in an error. See option link(setlk)(OPTION_SETLK_WR) for information about making this lock mandatory. label(OPTION_SETLKW_RD)dit(bf(tt(setlkw-rd))) Tries to set a discretionary waiting read lock to the whole file using the code(fcntl(fd, F_SETLKW, ...)) system call. If the file is already write locked, this call blocks. See option link(setlk)(OPTION_SETLK_WR) for information about making this lock mandatory. label(OPTION_FLOCK_EX)dit(bf(tt(flock-ex))) Tries to set a blocking exclusive advisory lock to the file using the code(flock(fd, LOCK_EX)) system call. Socat() hangs in this call if the file is locked by another process. label(OPTION_FLOCK_EX_NB)dit(bf(tt(flock-ex-nb))) Tries to set a nonblocking exclusive advisory lock to the file using the code(flock(fd, LOCK_EX|LOCK_NB)) system call. If the file is already locked, this option results in an error. label(OPTION_FLOCK_SH)dit(bf(tt(flock-sh))) Tries to set a blocking shared advisory lock to the file using the code(flock(fd, LOCK_SH)) system call. Socat() hangs in this call if the file is locked by another process. label(OPTION_FLOCK_SH_NB)dit(bf(tt(flock-sh-nb))) Tries to set a nonblocking shared advisory lock to the file using the code(flock(fd, LOCK_SH|LOCK_NB)) system call. If the file is already locked, this option results in an error. label(OPTION_LOCK)dit(bf(tt(lock))) Sets a blocking lock on the file. Uses the setlk or flock mechanism depending on availability on the particular platform. If both are available, the POSIX variant (setlkw) is used. label(OPTION_USER)dit(bf(tt(user=))) Sets the link()(TYPE_USER) (owner) of the stream. If the address is member of the NAMED option group, socat() uses the code(chown()) system call after opening the file or binding to the unixdomain() socket (race condition!). Without filesystem entry, socat() sets the user of the stream using the code(fchown()) system call. These calls might require root privilege. label(OPTION_USER_LATE)dit(bf(tt(user-late=))) Sets the owner of the fd to link()(TYPE_USER) with the code(fchown()) system call after opening or connecting the channel. This is useful only on file system entries. label(OPTION_GROUP)dit(bf(tt(group=))) Sets the link()(TYPE_GROUP) of the stream. If the address is member of the NAMED option group, socat() uses the code(chown()) system call after opening the file or binding to the unixdomain() socket (race condition!). Without filesystem entry, socat() sets the group of the stream with the code(fchown()) system call. These calls might require group membership or root privilege. label(OPTION_GROUP_LATE)dit(bf(tt(group-late=))) Sets the group of the fd to link()(TYPE_GROUP) with the code(fchown()) system call after opening or connecting the channel. This is useful only on file system entries. label(OPTION_MODE)dit(bf(tt(mode=))) Sets the [link(mode_t)(TYPE_MODE_T)] (permissions) of the stream. If the address is member of the NAMED option group and uses the code(open()) or code(creat()) call, the mode is applied with these. If the address is member of the NAMED option group without using these system calls, socat() uses the code(chmod()) system call after opening the filesystem entry or binding to the unixdomain() socket (race condition!). Otherwise, socat() sets the mode of the stream using code(fchmod()). These calls might require ownership or root privilege. label(OPTION_PERM_LATE)dit(bf(tt(perm-late=))) Sets the permissions of the fd to value [link(mode_t)(TYPE_MODE_T)] using the code(fchmod()) system call after opening or connecting the channel. This is useful only on file system entries. label(OPTION_APPEND)dit(bf(tt(append=))) Always writes data to the actual end of file. If the address is member of the OPEN option group, socat() uses the code(O_APPEND) flag with the code(open()) system call (link(example)(EXAMPLE_OPTION_APPEND)). Otherwise, socat() applies the code(fcntl(fd, F_SETFL, O_APPEND)) call. label(OPTION_NONBLOCK)dit(bf(tt(nonblock=))) Tries to open or use file in nonblocking mode. Its only effects are that the code(connect()) call of TCP addresses does not block, and that opening a named pipe for reading does not block. If the address is member of the OPEN option group, socat() uses the code(O_NONBLOCK) flag with the code(open()) system call. Otherwise, socat() applies the code(fcntl(fd, F_SETFL, O_NONBLOCK)) call. COMMENT(label(OPTION_NDELAY)dit(bf(tt(ndelay=))) Tries to open or use file in nonblocking mode. Has no effect because socat() works with code(select()).) COMMENT(label(OPTION_ASYNC)dit(bf(tt(async=))) Enables SIGIO for this fd. Has no effect, because socat() ignores SIGIO.) label(OPTION_O_BINARY)dit(bf(tt(binary))) Opens the file in binary mode to avoid implicit line terminator conversions (Cygwin). label(OPTION_O_TEXT)dit(bf(tt(text))) Opens the file in text mode to force implicit line terminator conversions (Cygwin). label(OPTION_O_NOINHERIT)dit(bf(tt(noinherit))) Does not keep this file open in a spawned process (Cygwin). label(OPTION_COOL_WRITE)dit(bf(tt(cool-write))) Takes it easy when write fails with EPIPE or ECONNRESET and logs the message with em(notice) level instead of em(error). This prevents the log file from being filled with useless error messages when socat is used as a high volume server or proxy where clients often abort the connection.nl() This option is experimental. label(OPTION_END_CLOSE)dit(bf(tt(end-close))) Changes the (address dependent) method of ending a connection to just close the file descriptors. This is useful when the connection is to be reused by or shared with other processes (link(example)(EXAMPLE_END_CLOSE)).nl() Normally, socket connections will be ended with tt(shutdown(2)) which terminates the socket even if it is shared by multiple processes. tt(close(2)) "unlinks" the socket from the process but keeps it active as long as there are still links from other processes.nl() Similarly, when an address of type EXEC or SYSTEM is ended, socat usually will explicitely kill the sub process. With this option, it will just close the file descriptors. label(OPTION_SHUT_NONE)dit(bf(tt(shut-none))) Changes the (address dependent) method of shutting down the write part of a connection to not do anything. label(OPTION_SHUT_DOWN)dit(bf(tt(shut-down))) Changes the (address dependent) method of shutting down the write part of a connection to tt(shutdown\(fd, SHUT_WR)). Is only useful with sockets. label(OPTION_SHUT_CLOSE)dit(bf(tt(shut-close))) Changes the (address dependent) method of shutting down the write part of a connection to tt(close\(fd)). label(OPTION_SHUT_NULL)dit(bf(tt(shut-null))) When one address indicates EOF, socat() will send a zero sized packet to the write channel of the other address to transfer the EOF condition. This is useful with UDP and other datagram protocols. Has been tested against netcat and socat with option link(null-eof)(OPTION_NULL_EOF). label(OPTION_NULL_EOF)dit(bf(tt(null-eof))) Normally socat() will ignore empty (zero size payload) packets arriving on datagram sockets, so it survives port scans. With this option socat() interprets empty datagram packets as EOF indicator (see link(shut-null)(OPTION_SHUT_NULL)). label(OPTION_IOCTL_VOID)dit(bf(tt(ioctl-void=))) Calls tt(ioctl()) with the request value as second argument and NULL as third argument. This option allows to utilize ioctls that are not explicitely implemented in socat. label(OPTION_IOCTL_INT)dit(bf(tt(ioctl-int=:))) Calls tt(ioctl()) with the request value as second argument and the integer value as third argument. label(OPTION_IOCTL_INTP)dit(bf(tt(ioctl-intp=:))) Calls tt(ioctl()) with the request value as second argument and a pointer to the integer value as third argument. label(OPTION_IOCTL_BIN)dit(bf(tt(ioctl-bin=:))) Calls tt(ioctl()) with the request value as second argument and a pointer to the given data value as third argument. This data must be specified in link()(TYPE_DATA) form. label(OPTION_IOCTL_STRING)dit(bf(tt(ioctl-string=:))) Calls tt(ioctl()) with the request value as second argument and a pointer to the given string as third argument. link()(TYPE_DATA) form. enddit() startdit()enddit()nl() label(GROUP_NAMED)em(bf(NAMED option group)) These options work on file system entries.nl() See also options link(user)(OPTION_USER), link(group)(OPTION_GROUP), and link(mode)(OPTION_MODE). startdit() label(OPTION_USER_EARLY)dit(bf(tt(user-early=))) Changes the link()(TYPE_USER) (owner) of the file system entry before accessing it, using the code(chown()) system call. This call might require root privilege. label(OPTION_GROUP_EARLY)dit(bf(tt(group-early=))) Changes the link()(TYPE_GROUP) of the file system entry before accessing it, using the code(chown()) system call. This call might require group membership or root privilege. label(OPTION_PERM_EARLY)dit(bf(tt(perm-early=))) Changes the [link(mode_t)(TYPE_MODE_T)] of the file system entry before accessing it, using the code(chmod()) system call. This call might require ownership or root privilege. label(OPTION_UMASK)dit(bf(tt(umask=))) Sets the umask of the process to [link(mode_t)(TYPE_MODE_T)] before accessing the file system entry (useful with unixdomain() sockets!). This call might affect all further operations of the socat() process! label(OPTION_UNLINK_EARLY)dit(bf(tt(unlink-early))) Unlinks (removes) the file before opening it and even before applying user-early etc. label(OPTION_UNLINK)dit(bf(tt(unlink))) Unlinks (removes) the file before accessing it, but after user-early etc. label(OPTION_UNLINK_LATE)dit(bf(tt(unlink-late))) Unlinks (removes) the file after opening it to make it inaccessible for other processes after a short race condition. label(OPTION_UNLINK_CLOSE)dit(bf(tt(unlink-close))) Removes the addresses file system entry when closing the address. For link(named pipes)(ADDRESS_NAMED_PIPE), link(listening unix domain sockets)(ADDRESS_UNIX_LISTEN), and the link(symbolic links)(OPTION_SYMBOLIC_LINK) of link(pty addresses)(ADDRESS_PTY), the default is 1; for link(created files)(ADDRESS_CREAT), link(opened files)(ADDRESS_OPEN), link(generic opened files)(ADDRESS_GOPEN), and link(client unix domain sockets)(ADDRESS_UNIX_CONNECT) the default is 0. enddit() startdit()enddit()nl() label(GROUP_OPEN)em(bf(OPEN option group)) The OPEN group options allow to set flags with the code(open()) system call. E.g., option `creat' sets the code(O_CREAT) flag.nl() See also options link(append)(OPTION_APPEND) and link(nonblock)(OPTION_NONBLOCK). startdit() label(OPTION_O_CREAT)dit(bf(tt(creat=))) Creates the file if it does not exist (link(example)(EXAMPLE_OPTION_CREAT)). label(OPTION_DSYNC)dit(bf(tt(dsync=))) Blocks code(write()) calls until metainfo is physically written to media. label(OPTION_EXCL)dit(bf(tt(excl=))) With option creat, if file exists this is an error. label(OPTION_LARGEFILE)dit(bf(tt(largefile=))) On 32 bit systems, allows a file larger than 2^31 bytes. label(OPTION_O_NOATIME)dit(bf(tt(noatime))) Sets the O_NOATIME options, so reads do not change the access timestamp. label(OPTION_NOCTTY)dit(bf(tt(noctty=))) Does not make this file the controlling terminal. label(OPTION_NOFOLLOW)dit(bf(tt(nofollow=))) Does not follow symbolic links. label(OPTION_NSHARE)dit(bf(tt(nshare=))) Does not allow to share this file with other processes. label(OPTION_RSHARE)dit(bf(tt(rshare=))) Does not allow other processes to open this file for writing. label(OPTION_RSYNC)dit(bf(tt(rsync=))) Blocks code(write()) until metainfo is physically written to media. label(OPTION_SYNC)dit(bf(tt(sync=))) Blocks code(write()) until data is physically written to media. COMMENT(label(OPTION_DEFER)dit(bf(tt(defer=))) Temporarily stores write data in paging space.) COMMENT(label(OPTION_DELAY)dit(bf(tt(delay=))) Blocks code(open()) until share conditions are fulfilled.) COMMENT(label(OPTION_DIRECT)dit(bf(tt(direct=)))) COMMENT(label(OPTION_DIRECTORY)dit(bf(tt(directory=))) Fails if file is not a directory. Not useful with socat().) label(OPTION_RDONLY)dit(bf(tt(rdonly=))) Opens the file for reading only. COMMENT(label(OPTION_RDWR)dit(bf(tt(rdwr=))) Opens the file for reading and writing.) label(OPTION_WRONLY)dit(bf(tt(wronly=))) Opens the file for writing only. label(OPTION_O_TRUNC)dit(bf(tt(trunc))) Truncates the file to size 0 during opening it. enddit() startdit()enddit()nl() label(GROUP_REG)em(bf(REG and BLK option group)) These options are usually applied to a unix() file descriptor, but their semantics make sense only on a file supporting random access. startdit() label(OPTION_SEEK)dit(bf(tt(seek=))) Applies the code(lseek(fd, , SEEK_SET)) (or code(lseek64)) system call, thus positioning the file pointer absolutely to [link(off_t)(TYPE_OFF) or link(off64_t)(TYPE_OFF64)]. Please note that a missing value defaults to 1, not 0. label(OPTION_SEEK_CUR)dit(bf(tt(seek-cur=))) Applies the code(lseek(fd, , SEEK_CUR)) (or code(lseek64)) system call, thus positioning the file pointer [link(off_t)(TYPE_OFF) or link(off64_t)(TYPE_OFF64)] bytes relatively to its current position (which is usually 0). Please note that a missing value defaults to 1, not 0. label(OPTION_SEEK_END)dit(bf(tt(seek-end=))) Applies the code(lseek(fd, , SEEK_END)) (or code(lseek64)) system call, thus positioning the file pointer [link(off_t)(TYPE_OFF) or link(off64_t)(TYPE_OFF64)] bytes relatively to the files current end. Please note that a missing value defaults to 1, not 0. label(OPTION_FTRUNCATE)dit(bf(tt(ftruncate=))) Applies the code(ftruncate(fd, )) (or code(ftruncate64) if available) system call, thus truncating the file at the position [link(off_t)(TYPE_OFF) or link(off64_t)(TYPE_OFF64)]. Please note that a missing value defaults to 1, not 0. label(OPTION_EXT2_SECRM_FL)dit(bf(tt(secrm=))) label(OPTION_EXT2_UNRM)dit(bf(tt(unrm=))) label(OPTION_EXT2_COMPR)dit(bf(tt(compr=))) label(OPTION_EXT2_SYNC)dit(bf(tt(ext2-sync=))) label(OPTION_EXT2_IMMUTABLE)dit(bf(tt(immutable=))) label(OPTION_EXT2_APPEND)dit(bf(tt(ext2-append=))) label(OPTION_EXT2_NODUMP)dit(bf(tt(nodump=))) label(OPTION_EXT2_NOATIME)dit(bf(tt(ext2-noatime=))) label(OPTION_EXT2_JOURNAL_DATA)dit(bf(tt(journal-data=))) label(OPTION_EXT2_NOTAIL)dit(bf(tt(notail=))) label(OPTION_EXT2_DIRSYNC)dit(bf(tt(dirsync=))) These options change non standard file attributes on operating systems and file systems that support these features, like Linux with ext2fs, ext3fs, or reiserfs. See man 1 chattr for information on these options. Please note that there might be a race condition between creating the file and applying these options. enddit() startdit()enddit()nl() label(GROUP_PROCESS)em(bf(PROCESS option group)) Options of this group change the process properties instead of just affecting one data channel. For EXEC and SYSTEM addresses and for LISTEN and CONNECT type addresses with option FORK, these options apply to the child processes instead of the main socat process. startdit() label(OPTION_CHROOT)dit(bf(tt(chroot=))) Performs a code(chroot()) operation to link()(TYPE_DIRECTORY) after processing the address (link(example)(EXAMPLE_OPTION_CHROOT)). This call might require root privilege. label(OPTION_CHROOT_EARLY)dit(bf(tt(chroot-early=))) Performs a code(chroot()) operation to link()(TYPE_DIRECTORY) before opening the address. This call might require root privilege. label(OPTION_SETGID)dit(bf(tt(setgid=))) Changes the primary link()(TYPE_GROUP) of the process after processing the address. This call might require root privilege. Please note that this option does not drop other group related privileges. label(OPTION_SETGID_EARLY)dit(bf(tt(setgid-early=))) Like link(setgit)(OPTION_SETGID) but is performed before opening the address. label(OPTION_SETUID)dit(bf(tt(setuid=))) Changes the link()(TYPE_USER) (owner) of the process after processing the address. This call might require root privilege. Please note that this option does not drop group related privileges. Check if option link(su)(OPTION_SUBSTUSER) better fits your needs. label(OPTION_SETUID_EARLY)dit(bf(tt(setuid-early=))) Like link(setuid)(OPTION_SETUID) but is performed before opening the address. label(OPTION_SUBSTUSER)dit(bf(tt(su=))) Changes the link()(TYPE_USER) (owner) and groups of the process after processing the address (link(example)(EXAMPLE_OPTION_SUBSTUSER)). This call might require root privilege. label(OPTION_SUBSTUSER_DELAYED)dit(bf(tt(su-d=))) Short name for tt(substuser-delayed). COMMENT(Short name for bf(tt(substuser-delayed) ).) Changes the link()(TYPE_USER) (owner) and groups of the process after processing the address (link(example)(EXAMPLE_OPTION_SUBSTUSER_DELAYED)). The user and his groups are retrieved em(before) a possible code(chroot()). This call might require root privilege. label(OPTION_SETPGID)dit(bf(tt(setpgid=))) Makes the process a member of the specified process group link()(TYPE_PID_T). If no value is given, or if the value is 0 or 1, the process becomes leader of a new process group. label(OPTION_SETSID)dit(bf(tt(setsid))) Makes the process the leader of a new session (link(example)(EXAMPLE_OPTION_SETSID)). enddit() startdit()enddit()nl() label(GROUP_READLINE)em(bf(READLINE option group)) These options apply to the readline address type. startdit() label(OPTION_HISTORY)dit(bf(tt(history=))) Reads and writes history from/to link()(TYPE_FILENAME) (link(example)(EXAMPLE_OPTION_HISTORY)). label(OPTION_NOPROMPT)dit(bf(tt(noprompt))) Since version 1.4.0, socat per default tries to determine a prompt - that is then passed to the readline call - by remembering the last incomplete line of the output. With this option, socat does not pass a prompt to readline, so it begins line editing in the first column of the terminal. label(OPTION_NOECHO)dit(bf(tt(noecho=))) Specifies a regular pattern for a prompt that prevents the following input line from being displayed on the screen and from being added to the history. The prompt is defined as the text that was output to the readline address after the lastest newline character and before an input character was typed. The pattern is a regular expression, e.g. "^[Pp]assword:.*$" or "([Uu]ser:|[Pp]assword:)". See regex\(7) for details. (link(example)(EXAMPLE_OPTION_NOECHO)) label(OPTION_PROMPT)dit(bf(tt(prompt=))) Passes the string as prompt to the readline function. readline prints this prompt when stepping through the history. If this string matches a constant prompt issued by an interactive program on the other socat address, consistent look and feel can be archieved. enddit() startdit()enddit()nl() label(GROUP_APPLICATION)em(bf(APPLICATION option group)) This group contains options that work at data level. Note that these options only apply to the "raw" data transferred by socat, but not to protocol data used by addresses like link(PROXY)(ADDRESS_PROXY_CONNECT). startdit() label(OPTION_CR)dit(bf(tt(cr))) Converts the default line termination character NL ('\n', 0x0a) to/from CR ('\r', 0x0d) when writing/reading on this channel. label(OPTION_CRNL)dit(bf(tt(crnl))) Converts the default line termination character NL ('\n', 0x0a) to/from CRNL ("\r\n", 0x0d0a) when writing/reading on this channel (link(example)(EXAMPLE_OPTION_CRNL)). Note: socat simply strips all CR characters. label(OPTION_IGNOREEOF)dit(bf(tt(ignoreeof))) When EOF occurs on this channel, socat() ignores it and tries to read more data (like "tail -f") (link(example)(EXAMPLE_OPTION_IGNOREEOF)). label(OPTION_READBYTES)dit(bf(tt(readbytes=))) socat() reads only so many bytes from this address (the address provides only so many bytes for transfer and pretends to be at EOF afterwards). Must be greater than 0. label(OPTION_LOCKFILE)dit(bf(tt(lockfile=))) If lockfile exists, exits with error. If lockfile does not exist, creates it and continues, unlinks lockfile on exit. label(OPTION_WAITLOCK)dit(bf(tt(waitlock=))) If lockfile exists, waits until it disappears. When lockfile does not exist, creates it and continues, unlinks lockfile on exit. label(OPTION_ESCAPE)dit(bf(tt(escape=))) Specifies the numeric code of a character that triggers EOF on the input stream. It is useful with a terminal in raw mode (link(example)(EXAMPLE_OPTION_ESCAPE)). enddit() startdit()enddit()nl() label(GROUP_SOCKET)em(bf(SOCKET option group)) These options are intended for all kinds of sockets, e.g. IP or unixdomain(). Most are applied with a code(setsockopt()) call. startdit() label(OPTION_BIND)dit(bf(tt(bind=))) Binds the socket to the given socket address using the code(bind()) system call. The form of is socket domain dependent: IP4 and IP6 allow the form [hostname|hostaddress][:(service|port)] (link(example)(EXAMPLE_OPTION_BIND_TCP4)), unixdomain() sockets require link()(TYPE_FILENAME). label(OPTION_CONNECT_TIMEOUT)dit(bf(tt(connect-timeout=))) Abort the connection attempt after [link(timeval)(TYPE_TIMEVAL)] with error status. label(OPTION_SO_BINDTODEVICE)dit(bf(tt(so-bindtodevice=))) Binds the socket to the given link()(TYPE_INTERFACE). This option might require root privilege. label(OPTION_SO_BROADCAST)dit(bf(tt(broadcast))) For datagram sockets, allows sending to broadcast addresses and receiving packets addressed to broadcast addresses. COMMENT(label(OPTION_BSDCOMPAT)dit(bf(tt(bsdcompat))) Emulates some (old?) bugs of the BSD socket implementation.) label(OPTION_DEBUG)dit(bf(tt(debug))) Enables socket debugging. label(OPTION_DONTROUTE)dit(bf(tt(dontroute))) Only communicates with directly connected peers, does not use routers. label(OPTION_KEEPALIVE)dit(bf(tt(keepalive))) Enables sending keepalives on the socket. label(OPTION_LINGER)dit(bf(tt(linger=))) Blocks code(shutdown()) or code(close()) until data transfers have finished or the given timeout [link(int)(TYPE_INT)] expired. COMMENT(label(OPTION_NOREUSEADDR)dit(bf(tt(noreuseaddr))) Set the code(SO_NOREUSEADDR) socket option.) label(OPTION_OOBINLINE)dit(bf(tt(oobinline))) Places out-of-band data in the input data stream. label(OPTION_PRIORITY)dit(bf(tt(priority=))) Sets the protocol defined [link()(TYPE_INT)] for outgoing packets. label(OPTION_RCVBUF)dit(bf(tt(rcvbuf=))) Sets the size of the receive buffer after the code(socket()) call to [link(int)(TYPE_INT)]. With TCP sockets, this value corresponds to the socket's maximal window size. label(OPTION_RCVBUF_LATE)dit(bf(tt(rcvbuf-late=))) Sets the size of the receive buffer when the socket is already connected to [link(int)(TYPE_INT)]. With TCP sockets, this value corresponds to the socket's maximal window size. label(OPTION_RCVLOWAT)dit(bf(tt(rcvlowat=))) Specifies the minimum number of received bytes [link(int)(TYPE_INT)] until the socket layer will pass the buffered data to socat(). label(OPTION_RCVTIMEO)dit(bf(tt(rcvtimeo=))) Sets the receive timeout [link(timeval)(TYPE_TIMEVAL)]. label(OPTION_REUSEADDR)dit(bf(tt(reuseaddr))) Allows other sockets to bind to an address even if parts of it (e.g. the local port) are already in use by socat() (link(example)(EXAMPLE_OPTION_REUSEADDR)). label(OPTION_SNDBUF)dit(bf(tt(sndbuf=))) Sets the size of the send buffer after the code(socket()) call to [link(int)(TYPE_INT)]. label(OPTION_SNDBUF_LATE)dit(bf(tt(sndbuf-late=))) Sets the size of the send buffer when the socket is connected to [link(int)(TYPE_INT)]. label(OPTION_SNDLOWAT)dit(bf(tt(sndlowat=))) Specifies the minimum number of bytes in the send buffer until the socket layer will send the data to [link(int)(TYPE_INT)]. label(OPTION_SNDTIMEO)dit(bf(tt(sndtimeo=))) Sets the send timeout to seconds [link(timeval)(TYPE_TIMEVAL)]. label(OPTION_PROTOCOL_FAMILY)dit(bf(tt(pf=))) Forces the use of the specified IP version or protocol. can be something like "ip4" or "ip6". The resulting value is used as first argument to the code(socket()) or code(socketpair()) calls. This option affects address resolution and the required syntax of bind and range options. label(OPTION_SO_TYPE)dit(bf(tt(type=))) Sets the type of the socket, specified as second argument to the code(socket()) or code(socketpair()) calls, to [link(int)(TYPE_INT)]. Address resolution is not affected by this option. Under Linux, 1 means stream oriented socket, 2 means datagram socket, and 3 means raw socket. label(OPTION_SO_PROTOTYPE)dit(bf(tt(prototype))) Sets the protocol of the socket, specified as third argument to the code(socket()) or code(socketpair()) calls, to [link(int)(TYPE_INT)]. Address resolution is not affected by this option. 6 means TCP, 17 means UDP. COMMENT(label(OPTION_USELOOPBACK)dit(bf(tt(useloopback))) Sets the code(SO_USELOOPBACK) socket option.) COMMENT(label(OPTION_ACCEPTCONN)dit(bf(tt(acceptconn))) Tries to set the code(SO_ACCEPTCONN) socket option.) COMMENT(label(OPTION_ATTACHFILTER)dit(bf(tt(attachfilter))) Tries to set the code(SO_ATTACH_FILTER) socket option.) COMMENT(label(OPTION_AUDIT)dit(bf(tt(audit))) Sets the code(SO_AUDIT) socket option.) COMMENT(label(OPTION_CHSUMRECV)dit(bf(tt(cksumrecv))) Sets the code(SO_CKSUMRECV) socket option.) COMMENT(label(OPTION_DETACHFILTER)dit(bf(tt(detachfilter))) Tries to set the code(SO_DETACH_FILTER) socket option.) COMMENT(label(OPTION_DGRAMERRIND)dit(bf(tt(dgramerrind))) Sets the code(SO_DGRAM_ERRIND) socket option.) COMMENT(label(OPTION_DONTLINGER)dit(bf(tt(dontlinger))) Sets the code(SO_DONTLINGER) socket option.) COMMENT(label(OPTION_ERROR)dit(bf(tt(error))) Tries to set this read only socket option.) COMMENT(label(OPTION_FIOSETOWN)dit(bf(tt(fiosetown=))) Sets the receiver of SIGIO.) COMMENT(label(OPTION_KERNACCEPT)dit(bf(tt(kernaccept))) Sets the code(SO_KERNACCEPT) socket option.) COMMENT(label(OPTION_NOCHECK)dit(bf(tt(nocheck))) Sets the code(SO_NO_CHECK) socket option. Undocumented...) COMMENT(label(OPTION_PASSCRED)dit(bf(tt(passcred))) Set the code(SO_PASSCRED) socket option.) COMMENT(label(OPTION_PEERCRED)dit(bf(tt(peercred))) This is a read-only socket option.) COMMENT(label(OPTION_REUSEPORT)dit(bf(tt(reuseport))) Set the code(SO_REUSEPORT) socket option.) COMMENT(label(OPTION_SECUTIYAUTHENTICATION)dit(bf(tt(securityauthentication))) Set the code(SO_SECURITY_AUTHENTICATION) socket option.) COMMENT(label(OPTION_SECURITYENCRYPTIONNETWORK)dit(bf(tt(securityencryptionnetwork))) Set the code(SO_SECURITY_ENCRYPTION_NETWORK) socket option.) COMMENT(label(OPTION_SECURITYENCRYPTIONTRANSPORT)dit(bf(tt(securityencryptiontransport))) Set the code(SO_SECURITY_ENCRYPTION_TRANSPORT) socket option.) COMMENT(label(OPTION_SIOCSPGRP)dit(bf(tt(siocspgrp=))) Set the SIOCSPGRP with code(ioclt()) to enable SIGIO.) COMMENT(label(OPTION_USEIFBUFS)dit(bf(tt(useifbufs))) Set the code(SO_USE_IFBUFS) socket option.) label(OPTION_SO_TIMESTAMP)dit(bf(tt(so-timestamp))) Sets the SO_TIMESTAMP socket option. This enables receiving and logging of timestamp ancillary messages. label(OPTION_SETSOCKOPT_INT)dit(bf(tt(setsockopt-int=::))) Invokes tt(setsockopt()) for the socket with the given parameters. tt(level) [link(int)(TYPE_INT)] is used as second argument to tt(setsockopt()) and specifies the layer, e.g. SOL_TCP for TCP (6 on Linux), or SOL_SOCKET for the socket layer (1 on Linux). tt(optname) [link(int)(TYPE_INT)] is the third argument to tt(setsockopt()) and tells which socket option is to be set. For the actual numbers you might have to look up the appropriate include files of your system. The 4th tt(setsockopt()) parameter, tt(value) [link(int)(TYPE_INT)], is passed to the function per pointer, and for the length parameter sizeof\(int) is taken implicitely. label(OPTION_SETSOCKOPT_BIN)dit(bf(tt(setsockopt-bin=::))) Like tt(setsockopt-int), but must be provided in link(dalan)(TYPE_DATA) format and specifies an arbitrary sequence of bytes; the length parameter is automatically derived from the data. label(OPTION_SETSOCKOPT_STRING)dit(bf(tt(setsockopt-string=::))) Like tt(setsockopt-int), but must be a link(string)(TYPE_STRING). This string is passed to the function with trailing null character, and the length parameter is automatically derived from the data. enddit() startdit()enddit()nl() label(GROUP_SOCK_UNIX)em(bf(UNIX option group)) These options apply to UNIX domain based addresses. startdit() label(OPTION_UNIX_TIGHTSOCKLEN)dit(bf(tt(unix-tightsocklen=[0|1]))) On socket operations, pass a socket address length that does not include the whole code(struct sockaddr_un) record but (besides other components) only the relevant part of the filename or abstract string. Default is 1. enddit() label(GROUP_IP4) label(GROUP_IP)em(bf(IP4 and IP6 option groups)) These options can be used with IPv4 and IPv6 based sockets. startdit() label(OPTION_TOS)dit(bf(tt(tos=))) Sets the TOS (type of service) field of outgoing packets to [link(byte)(TYPE_BYTE)] (see RFC 791). label(OPTION_TTL)dit(bf(tt(ttl=))) Sets the TTL (time to live) field of outgoing packets to [link(byte)(TYPE_BYTE)]. label(OPTION_IPOPTIONS)dit(bf(tt(ip-options=))) Sets IP options like source routing. Must be given in binary form, recommended format is a leading "x" followed by an even number of hex digits. This option may be used multiple times, data are appended. E.g., to connect to host 10.0.0.1 via some gateway using a loose source route, use the gateway as address parameter and set a loose source route using the option code(ip-options=x8307040a000001).nl() IP options are defined in RFC 791. COMMENT(, RFC 2113)nl() COMMENT( x00 end of option list x01 no operation (nop) x0211 security x03 loose source route x09 strict source route x07 record route x0804 stream ID x44 internet timestamp) label(OPTION_MTUDISCOVER)dit(bf(tt(mtudiscover=<0|1|2>))) Takes 0, 1, 2 to never, want, or always use path MTU discover on this socket. COMMENT(label(OPTION_HRDINCL)dit(bf(tt(ip-hdrincl))) Tell the raw socket that the application data includes the IP header.) COMMENT(label(OPTION_IP_MULTICAST_LOOP)dit(bf(tt(ip-multicastloop))) Allow looping back outgoing multicast to the local interface.) COMMENT(label(OPTION_IP_MULTICAST_TTL)dit(bf(tt(ip-multicastttl))) Set the TTL for outgoing multicast packets.) label(OPTION_IP_PKTINFO)dit(bf(tt(ip-pktinfo))) Sets the IP_PKTINFO socket option. This enables receiving and logging of ancillary messages containing destination address and interface (Linux) (link(example)(EXAMPLE_ANCILLARY)). COMMENT(label(OPTION_PKTOPTS)dit(bf(tt(ip-pktopts))) Set the IP_PKTOPTIONS socket option.) label(OPTION_IP_RECVERR)dit(bf(tt(ip-recverr))) Sets the IP_RECVERR socket option. This enables receiving and logging of ancillary messages containing detailled error information. label(OPTION_IP_RECVOPTS)dit(bf(tt(ip-recvopts))) Sets the IP_RECVOPTS socket option. This enables receiving and logging of IP options ancillary messages (Linux, *BSD). label(OPTION_IP_RECVTOS)dit(bf(tt(ip-recvtos))) Sets the IP_RECVTOS socket option. This enables receiving and logging of TOS (type of service) ancillary messages (Linux). label(OPTION_IP_RECVTTL)dit(bf(tt(ip-recvttl))) Sets the IP_RECVTTL socket option. This enables receiving and logging of TTL (time to live) ancillary messages (Linux, *BSD). COMMENT(label(OPTION_RETOPTS)dit(bf(tt(ip-retopts))) Set the IP_RETOPTS socket option.) label(OPTION_IP_RECVDSTADDR)dit(bf(tt(ip-recvdstaddr))) Sets the IP_RECVDSTADDR socket option. This enables receiving and logging of ancillary messages containing destination address (*BSD) (link(example)(EXAMPLE_ANCILLARY)). label(OPTION_IP_RECVIF)dit(bf(tt(ip-recvif))) Sets the IP_RECVIF socket option. This enables receiving and logging of interface ancillary messages (*BSD) (link(example)(EXAMPLE_ANCILLARY)). COMMENT(label(OPTION_ROUTERALERT)dit(bf(tt(routeralert))) Set the IP_ROUTER_ALERT socket option.) label(OPTION_IP_ADD_MEMBERSHIP) dit(bf(tt(ip-add-membership=))) dit(bf(tt(ip-add-membership=))) dit(bf(tt(ip-add-membership=))) dit(bf(tt(ip-add-membership=))) dit(bf(tt(ip-add-membership=))) Makes the socket member of the specified multicast group. This is currently only implemented for IPv4. The option takes the IP address of the multicast group and info about the desired network interface. The most common syntax is the first one, while the others are only available on systems that provide tt(struct mreqn) (Linux).nl() The indices of active network interfaces can be shown using the utility procan(). label(OPTION_IP_MULTICAST_IF) dit(bf(tt(ip-multicast-if=))) Specifies hostname or address of the network interface to be used for multicast traffic. label(OPTION_IP_MULTICAST_LOOP) dit(bf(tt(ip-multicast-loop=))) Specifies if outgoing multicast traffic should loop back to the interface. label(OPTION_IP_MULTICAST_TTL) dit(bf(tt(ip-multicast-ttl=))) Sets the TTL used for outgoing multicast traffic. Default is 1. label(OPTION_RES_DEBUG)dit(bf(tt(res-debug))) label(OPTION_RES_AAONLY)dit(bf(tt(res-aaonly))) label(OPTION_RES_USEVC)dit(bf(tt(res-usevc))) label(OPTION_RES_PRIMARY)dit(bf(tt(res-primary))) label(OPTION_RES_IGNTC)dit(bf(tt(res-igntc))) label(OPTION_RES_RECURSE)dit(bf(tt(res-recurse))) label(OPTION_RES_DEFNAMES)dit(bf(tt(res-defnames))) label(OPTION_RES_STAYOPEN)dit(bf(tt(res-stayopen))) label(OPTION_RES_DNSRCH)dit(bf(tt(res-dnsrch))) These options set the corresponding resolver (name resolution) option flags. Append "=0" to clear a default option. See man resolver\(5) for more information on these options. Note: these options are valid only for the address they are applied to. enddit() startdit()enddit()nl() label(GROUP_IP6)em(bf(IP6 option group)) These options can only be used on IPv6 based sockets. See link(IP options)(GROUP_IP) for options that can be applied to both IPv4 and IPv6 sockets. startdit() label(OPTION_IPV6_V6ONLY)dit(bf(tt(ipv6only=))) Sets the IPV6_V6ONLY socket option. If 0, the TCP stack will also accept connections using IPv4 protocol on the same port. The default is system dependent. label(OPTION_IPV6_RECVDSTOPTS)dit(bf(tt(ipv6-recvdstopts))) Sets the IPV6_RECVDSTOPTS socket option. This enables receiving and logging of ancillary messages containing the destination options. label(OPTION_IPV6_RECVHOPLIMIT)dit(bf(tt(ipv6-recvhoplimit))) Sets the IPV6_RECVHOPLIMIT socket option. This enables receiving and logging of ancillary messages containing the hoplimit. label(OPTION_IPV6_RECVHOPOPTS)dit(bf(tt(ipv6-recvhopopts))) Sets the IPV6_RECVHOPOPTS socket option. This enables receiving and logging of ancillary messages containing the hop options. label(OPTION_IPV6_RECVPKTINFO)dit(bf(tt(ipv6-recvpktinfo))) Sets the IPV6_RECVPKTINFO socket option. This enables receiving and logging of ancillary messages containing destination address and interface. label(OPTION_IPV6_UNICAST_HOPS)dit(bf(tt(ipv6-unicast-hops=link(TYPE_INT)()))) Sets the IPV6_UNICAST_HOPS socket option. This sets the hop count limit (TTL) for outgoing unicast packets. label(OPTION_IPV6_RECVRTHDR)dit(bf(tt(ipv6-recvrthdr))) Sets the IPV6_RECVRTHDR socket option. This enables receiving and logging of ancillary messages containing routing information. label(OPTION_IPV6_TCLASS)dit(bf(tt(ipv6-tclass))) Sets the IPV6_TCLASS socket option. This sets the transfer class of outgoing packets. label(OPTION_IPV6_RECVTCLASS)dit(bf(tt(ipv6-recvtclass))) Sets the IPV6_RECVTCLASS socket option. This enables receiving and logging of ancillary messages containing the transfer class. enddit() startdit()enddit()nl() label(GROUP_TCP)em(bf(TCP option group)) These options may be applied to TCP sockets. They work by invoking code(setsockopt()) with the appropriate parameters. startdit() label(OPTION_CORK)dit(bf(tt(cork))) Doesn't send packets smaller than MSS (maximal segment size). label(OPTION_DEFER-ACCEPT)dit(bf(tt(defer-accept))) While listening, accepts connections only when data from the peer arrived. label(OPTION_KEEPCNT)dit(bf(tt(keepcnt=))) Sets the number of keepalives before shutting down the socket to [link(int)(TYPE_INT)]. label(OPTION_KEEPIDLE)dit(bf(tt(keepidle=))) Sets the idle time before sending the first keepalive to [link(int)(TYPE_INT)]. label(OPTION_KEEPINTVL)dit(bf(tt(keepintvl=))) Sets the interval between two keepalives to [link(int)(TYPE_INT)]. label(OPTION_LINGER2)dit(bf(tt(linger2=))) Sets the time to keep the socket in FIN-WAIT-2 state to [link(int)(TYPE_INT)]. label(OPTION_MSS)dit(bf(tt(mss=))) Sets the MSS (maximum segment size) after the code(socket()) call to [link(int)(TYPE_INT)]. This value is then proposed to the peer with the SYN or SYN/ACK packet (link(example)(EXAMPLE_OPTION_MSS)). label(OPTION_MSS_LATE)dit(bf(tt(mss-late=))) Sets the MSS of the socket after connection has been established to [link(int)(TYPE_INT)]. label(OPTION_NODELAY)dit(bf(tt(nodelay))) Turns off the Nagle algorithm for measuring the RTT (round trip time). label(OPTION_RFC1323)dit(bf(tt(rfc1323))) Enables RFC1323 TCP options: TCP window scale, round-trip time measurement (RTTM), and protect against wrapped sequence numbers (PAWS) (AIX). label(OPTION_STDURG)dit(bf(tt(stdurg))) Enables RFC1122 compliant urgent pointer handling (AIX). label(OPTION_SYNCNT)dit(bf(tt(syncnt=))) Sets the maximal number of SYN retransmits during connect to [link(int)(TYPE_INT)]. COMMENT(label(OPTION_INFO)dit(bf(tt(info))) Tries to set the read-only TCP_INFO socket option.) COMMENT(label(OPTION_WINDOW_CLAMP)dit(bf(tt(window-clamp))) Sets the TCP_WINDOW_CLAMP socket option.) label(OPTION_TCP_MD5SIG)dit(bf(tt(md5sig))) Enables generation of MD5 digests on the packets (FreeBSD). label(OPTION_TCP_NOOPT)dit(bf(tt(noopt))) Disables use of TCP options (FreeBSD, MacOSX). label(OPTION_TCP_NOPUSH)dit(bf(tt(nopush))) sets the TCP_NOPUSH socket option (FreeBSD, MacOSX). label(OPTION_TCP_SACK_DISABLE)dit(bf(tt(sack-disable))) Disables use the selective acknowledge feature (OpenBSD). label(OPTION_TCP_SIGNATURE_ENABLE)dit(bf(tt(signature-enable))) Enables generation of MD5 digests on the packets (OpenBSD). label(OPTION_TCP_ABORT_THRESHOLD)dit(bf(tt(abort-threshold=))) Sets the time to wait for an answer of the peer on an established connection (HP-UX). label(OPTION_TCP_CONN_ABORT_THRESHOLD)dit(bf(tt(conn-abort-threshold=))) Sets the time to wait for an answer of the server during the initial connect (HP-UX). label(OPTION_TCP_KEEPINIT)dit(bf(tt(keepinit))) Sets the time to wait for an answer of the server during connect\() before giving up. Value in half seconds, default is 150 (75s) (Tru64). label(OPTION_TCP_PAWS)dit(bf(tt(paws))) Enables the "protect against wrapped sequence numbers" feature (Tru64). label(OPTION_TCP_SACKENA)dit(bf(tt(sackena))) Enables selective acknowledge (Tru64). label(OPTION_TCP_TSOPTENA)dit(bf(tt(tsoptena))) Enables the time stamp option that allows RTT recalculation on existing connections (Tru64). enddit() startdit()enddit()nl() label(GROUP_SCTP)em(bf(SCTP option group)) These options may be applied to SCTP stream sockets. startdit() label(OPTION_SCTP_NODELAY)dit(bf(tt(sctp-nodelay))) Sets the SCTP_NODELAY socket option that disables the Nagle algorithm. label(OPTION_SCTP_MAXSEG)dit(bf(tt(sctp-maxseg=))) Sets the SCTP_MAXSEG socket option to [link(int)(TYPE_INT)]. This value is then proposed to the peer with the SYN or SYN/ACK packet. enddit() startdit()enddit()nl() em(bf(UDP, TCP, and SCTP option groups)) Here we find options that are related to the network port mechanism and thus can be used with UDP, TCP, and SCTP client and server addresses. startdit() label(OPTION_SOURCEPORT)dit(bf(tt(sourceport=))) For outgoing (client) TCP and UDP connections, it sets the source link()(TYPE_PORT) using an extra code(bind()) call. With TCP or UDP listen addresses, socat immediately shuts down the connection if the client does not use this sourceport (link(example)(EXAMPLE_OPTION_SOURCEPORT)). label(OPTION_LOWPORT)dit(bf(tt(lowport))) Outgoing (client) TCP and UDP connections with this option use an unused random source port between 640 and 1023 incl. On UNIX class operating systems, this requires root privilege, and thus indicates that the client process is authorized by local root. TCP and UDP listen addresses with this option immediately shut down the connection if the client does not use a sourceport <= 1023. This mechanism can provide limited authorization under some circumstances. enddit() startdit()enddit()nl() label(GROUP_SOCKS)em(bf(SOCKS option group)) When using SOCKS type addresses, some socks specific options can be set. startdit() label(OPTION_SOCKSPORT)dit(bf(tt(socksport=))) Overrides the default "socks" service or port 1080 for the socks server port with link()(TYPE_TCP_SERVICE). label(OPTION_SOCKSUSER)dit(bf(tt(socksuser=))) Sends the [link(string)(TYPE_STRING)] in the username field to the socks server. Default is the actual user name ($LOGNAME or $USER) (link(example)(EXAMPLE_OPTION_SOCKSUSER)). enddit() startdit()enddit()nl() label(GROUP_HTTP)em(bf(HTTP option group)) Options that can be provided with HTTP type addresses. The only HTTP address currently implemented is link(proxy-connect)(ADDRESS_PROXY_CONNECT). startdit() label(OPTION_PROXYPORT)dit(bf(tt(proxyport=))) Overrides the default HTTP proxy port 8080 with link()(TYPE_TCP_SERVICE). label(OPTION_IGNORECR)dit(bf(tt(ignorecr))) The HTTP protocol requires the use of CR+NL as line terminator. When a proxy server violates this standard, socat might not understand its answer. This option directs socat to interprete NL as line terminator and to ignore CR in the answer. Nevertheless, socat sends CR+NL to the proxy. label(OPTION_PROXY_AUTHORIZATION)dit(bf(tt(proxyauth=:))) Provide "basic" authentication to the proxy server. The argument to the option is used with a "Proxy-Authorization: Base" header in base64 encoded form.nl() Note: username and password are visible for every user on the local machine in the process list; username and password are transferred to the proxy server unencrypted (base64 encoded) and might be sniffed. label(OPTION_PROXY_RESOLVE)dit(bf(tt(resolve))) Per default, socat sends to the proxy a CONNECT request containing the target hostname. With this option, socat resolves the hostname locally and sends the IP address. Please note that, according to RFC 2396, only name resolution to IPv4 addresses is implemented. enddit() startdit()enddit()nl() label(GROUP_RANGE)em(bf(RANGE option group)) These options check if a connecting client should be granted access. They can be applied to listening and receiving network sockets. tcp-wrappers options fall into this group. startdit() label(OPTION_RANGE)dit(bf(tt(range=))) After accepting a connection, tests if the peer is within em(range). For IPv4 addresses, address-range takes the form address/bits, e.g. 10.0.0.0/8, or address:mask, e.g. 10.0.0.0:255.0.0.0 (link(example)(EXAMPLE_OPTION_RANGE)); for IPv6, it is [ip6-address/bits], e.g. [::1/128]. If the client address does not match, socat() issues a warning and keeps listening/receiving. label(OPTION_TCPWRAPPERS)dit(bf(tt(tcpwrap[=]))) Uses Wietse Venema's libwrap (tcpd) library to determine if the client is allowed to connect. The configuration files are /etc/hosts.allow and /etc/hosts.deny per default, see "man 5 hosts_access" for more information. The optional (type link(string)(TYPE_STRING)) is passed to the wrapper functions as daemon process name (link(example)(EXAMPLE_OPTION_TCPWRAPPERS)). If omitted, the basename of socats invocation (argv[0]) is passed. If both tcpwrap and range options are applied to an address, both conditions must be fulfilled to allow the connection. label(OPTION_TCPWRAP_HOSTS_ALLOW_TABLE)dit(bf(tt(allow-table=))) Takes the specified file instead of /etc/hosts.allow. label(OPTION_TCPWRAP_HOSTS_DENY_TABLE)dit(bf(tt(deny-table=))) Takes the specified file instead of /etc/hosts.deny. label(OPTION_TCPWRAP_ETC)dit(bf(tt(tcpwrap-etc=))) Looks for hosts.allow and hosts.deny in the specified directory. Is overridden by options link(hosts-allow)(OPTION_TCPWRAP_HOSTS_ALLOW_TABLE) and link(hosts-deny)(OPTION_TCPWRAP_HOSTS_DENY_TABLE). enddit() startdit()enddit()nl() label(GROUP_LISTEN)em(bf(LISTEN option group)) Options specific to listening sockets. startdit() label(OPTION_BACKLOG)dit(bf(tt(backlog=))) Sets the backlog value passed with the code(listen()) system call to [link(int)(TYPE_INT)]. Default is 5. label(OPTION_MAX_CHILDREN)dit(bf(tt(max-children=))) Limits the number of concurrent child processes [link(int)(TYPE_INT)]. Default is no limit. enddit() startdit()enddit()nl() label(GROUP_CHILD)em(bf(CHILD option group)) Options for addresses with multiple connections via child processes. startdit() label(OPTION_FORK)dit(bf(tt(fork))) After establishing a connection, handles its channel in a child process and keeps the parent process attempting to produce more connections, either by listening or by connecting in a loop (link(example)(EXAMPLE_OPTION_FORK)).nl() SSL-CONNECT and SSL-LISTEN differ in when they actually fork off the child: SSL-LISTEN forks em(before) the SSL handshake, while SSL-CONNECT forks em(afterwards). RETRY and FOREVER options are not inherited by the child process.nl() On some operating systems (e.g. FreeBSD) this option does not work for UDP-LISTEN addresses.nl() enddit() startdit()enddit()nl() label(GROUP_EXEC)em(bf(EXEC option group)) Options for addresses that invoke a program. startdit() label(OPTION_PATH)dit(bf(tt(path=))) Overrides the PATH environment variable for searching the program with link()(TYPE_STRING). This code($PATH) value is effective in the child process too. label(OPTION_LOGIN)dit(bf(tt(login))) Prefixes code(argv[0]) for the code(execvp()) call with '-', thus making a shell behave as login shell. enddit() startdit()enddit()nl() label(GROUP_FORK)em(bf(FORK option group)) EXEC or SYSTEM addresses invoke a program using a child process and transfer data between socat() and the program. The interprocess communication mechanism can be influenced with the following options. Per default, a code(socketpair()) is created and assigned to stdin and stdout of the child process, while stderr is inherited from the socat() process, and the child process uses file descriptors 0 and 1 for communicating with the main socat process. startdit() label(OPTION_NOFORK)dit(bf(tt(nofork))) Does not fork a subprocess for executing the program, instead calls execvp\() or system\() directly from the actual socat instance. This avoids the overhead of another process between the program and its peer, but introduces a lot of restrictions: startit() it() this option can only be applied to the second socat() address. it() it cannot be applied to a part of a link(dual)(ADDRESS_DUAL) address. it() the first socat address cannot be OPENSSL or READLINE it() socat options -b, -t, -D, -l, -v, -x become useless it() for both addresses, options ignoreeof, cr, and crnl become useless it() for the second address (the one with option nofork), options append, metaCOMMENT(async,) cloexec, flock, user, group, mode, nonblock, perm-late, setlk, and setpgid cannot be applied. Some of these could be used on the first address though. endit() label(OPTION_PIPES)dit(bf(tt(pipes))) Creates a pair of unnamed pipes for interprocess communication instead of a socket pair. label(OPTION_OPENPTY)dit(bf(tt(openpty))) Establishes communication with the sub process using a pseudo terminal created with code(openpty()) instead of the default (socketpair or ptmx). label(OPTION_PTMX)dit(bf(tt(ptmx))) Establishes communication with the sub process using a pseudo terminal created by opening file(/dev/ptmx) or file(/dev/ptc) instead of the default (socketpair). label(OPTION_PTY)dit(bf(tt(pty))) Establishes communication with the sub process using a pseudo terminal instead of a socket pair. Creates the pty with an available mechanism. If openpty and ptmx are both available, it uses ptmx because this is POSIX compliant (link(example)(EXAMPLE_OPTION_PTY)). label(OPTION_CTTY)dit(bf(tt(ctty))) Makes the pty the controlling tty of the sub process (link(example)(EXAMPLE_OPTION_CTTY)). label(OPTION_STDERR)dit(bf(tt(stderr))) Directs stderr of the sub process to its output channel by making stderr a code(dup()) of stdout (link(example)(EXAMPLE_OPTION_STDERR)). label(OPTION_FDIN)dit(bf(tt(fdin=))) Assigns the sub processes input channel to its file descriptor link()(TYPE_FDNUM) instead of stdin (0). The program started from the subprocess has to use this fd for reading data from socat() (link(example)(EXAMPLE_OPTION_FDIN)). label(OPTION_FDOUT)dit(bf(tt(fdout=))) Assigns the sub processes output channel to its file descriptor link()(TYPE_FDNUM) instead of stdout (1). The program started from the subprocess has to use this fd for writing data to socat() (link(example)(EXAMPLE_OPTION_FDOUT)). label(OPTION_SIGHUP)label(OPTION_SIGINT)label(OPTION_SIGQUIT)dit(bf(tt(sighup)), bf(tt(sigint)), bf(tt(sigquit))) Has socat() pass signals of this type to the sub process. If no address has this option, socat terminates on these signals. enddit() startdit()enddit()nl() label(GROUP_TERMIOS)em(bf(TERMIOS option group)) For addresses that work on a tty (e.g., stdio, file:/dev/tty, exec:...,pty), the terminal parameters defined in the unix() termios mechanism are made available as address option parameters. Please note that changes of the parameters of your interactive terminal remain effective after socat()'s termination, so you might have to enter "reset" or "stty sane" in your shell afterwards. For EXEC and SYSTEM addresses with option PTY, these options apply to the pty by the child processes. startdit() label(OPTION_B0)dit(bf(tt(b0))) Disconnects the terminal. label(OPTION_B19200)dit(bf(tt(b19200))) Sets the serial line speed to 19200 baud. Some other rates are possible; use something like tt(socat -hh |grep ' b[1-9]') to find all speeds supported by your implementation.nl() Note: On some operating systems, these options may not be available. Use link(ispeed)(OPTION_ISPEED) or link(ospeed)(OPTION_OSPEED) instead. label(OPTION_ECHO)dit(bf(tt(echo=))) Enables or disables local echo. label(OPTION_ICANON)dit(bf(tt(icanon=))) Sets or clears canonical mode, enabling line buffering and some special characters. label(OPTION_RAW)dit(bf(tt(raw))) Sets raw mode, thus passing input and output almost unprocessed. This option is obsolete, use option link(rawer)(OPTION_TERMIOS_RAWER) or link(cfmakeraw)(OPTION_TERMIOS_CFMAKERAW) instead. label(OPTION_TERMIOS_RAWER)dit(bf(tt(rawer))) Makes terminal rawer than link(raw)(OPTION_RAW) option. This option implicitly turns off echo. (link(example)(EXAMPLE_OPTION_TERMIOS_RAWER)). label(OPTION_TERMIOS_CFMAKERAW)dit(bf(tt(cfmakeraw))) Sets raw mode by invoking tt(cfmakeraw()) or by simulating this call. This option implicitly turns off echo. label(OPTION_IGNBRK)dit(bf(tt(ignbrk=))) Ignores or interpretes the BREAK character (e.g., ^C) label(OPTION_BRKINT)dit(bf(tt(brkint=))) label(OPTION_BS0)dit(bf(tt(bs0))) label(OPTION_BS1)dit(bf(tt(bs1))) label(OPTION_BSDLY)dit(bf(tt(bsdly=<0|1>))) label(OPTION_CLOCAL)dit(bf(tt(clocal=))) label(OPTION_CR0)label(OPTION_CR1)label(OPTION_CR2)label(OPTION_CR3) mancommand(\.LP) mancommand(\.nf) mancommand(\fBcr0 cr1 cr2 cr3\fP) mancommand(\.fi) mancommand(\.IP) htmlcommand(
cr0
cr1
cr2
cr3
) Sets the carriage return delay to 0, 1, 2, or 3, respectively. 0 means no delay, the other values are terminal dependent. label(OPTION_CRDLY)dit(bf(tt(crdly=<0|1|2|3>))) label(OPTION_CREAD)dit(bf(tt(cread=))) label(OPTION_CRTSCTS)dit(bf(tt(crtscts=))) label(OPTION_CS5)label(OPTION_CS6)label(OPTION_CS7)label(OPTION_CS8) mancommand(\.LP) mancommand(\.nf) mancommand(\fBcs5 cs6 cs7 cs8\fP) mancommand(\.fi) mancommand(\.IP) htmlcommand(
cs5
cs6
cs7
cs8
) Sets the character size to 5, 6, 7, or 8 bits, respectively. label(OPTION_CSIZE)dit(bf(tt(csize=<0|1|2|3>))) label(OPTION_CSTOPB)dit(bf(tt(cstopb=))) Sets two stop bits, rather than one. label(OPTION_VDSUSP)dit(bf(tt(dsusp=))) Sets the value for the VDSUSP character that suspends the current foreground process and reactivates the shell (all except Linux). label(OPTION_ECHOCTL)dit(bf(tt(echoctl=))) Echos control characters in hat notation (e.g. ^A) label(OPTION_ECHOE)dit(bf(tt(echoe=))) label(OPTION_ECHOK)dit(bf(tt(echok=))) label(OPTION_ECHOKE)dit(bf(tt(echoke=))) label(OPTION_ECHONL)dit(bf(tt(echonl=))) label(OPTION_ECHOPRT)dit(bf(tt(echoprt=))) label(OPTION_EOF)dit(bf(tt(eof=))) label(OPTION_EOL)dit(bf(tt(eol=))) label(OPTION_EOL2)dit(bf(tt(eol2=))) label(OPTION_ERASE)dit(bf(tt(erase=))) label(OPTION_DISCARD)dit(bf(tt(discard=))) label(OPTION_FF0)dit(bf(tt(ff0))) label(OPTION_FF1)dit(bf(tt(ff1))) label(OPTION_FFDLY)dit(bf(tt(ffdly=))) label(OPTION_FLUSHO)dit(bf(tt(flusho=))) label(OPTION_HUPCL)dit(bf(tt(hupcl=))) label(OPTION_ICRNL)dit(bf(tt(icrnl=))) label(OPTION_IEXTEN)dit(bf(tt(iexten=))) label(OPTION_IGNCR)dit(bf(tt(igncr=))) label(OPTION_IGNPAR)dit(bf(tt(ignpar=))) label(OPTION_IMAXBEL)dit(bf(tt(imaxbel=))) label(OPTION_INLCR)dit(bf(tt(inlcr=))) label(OPTION_INPCK)dit(bf(tt(inpck=))) label(OPTION_INTR)dit(bf(tt(intr=))) label(OPTION_ISIG)dit(bf(tt(isig=))) label(OPTION_ISPEED)dit(bf(tt(ispeed=))) Set the baud rate for incoming data on this line.nl() See also: link(ospeed)(OPTION_OSPEED), link(b19200)(OPTION_B19200) label(OPTION_ISTRIP)dit(bf(tt(istrip=))) label(OPTION_IUCLC)dit(bf(tt(iuclc=))) label(OPTION_IXANY)dit(bf(tt(ixany=))) label(OPTION_IXOFF)dit(bf(tt(ixoff=))) label(OPTION_IXON)dit(bf(tt(ixon=))) label(OPTION_KILL)dit(bf(tt(kill=))) label(OPTION_LNEXT)dit(bf(tt(lnext=))) label(OPTION_MIN)dit(bf(tt(min=))) label(OPTION_NL0)dit(bf(tt(nl0))) Sets the newline delay to 0. label(OPTION_NL1)dit(bf(tt(nl1))) label(OPTION_NLDLY)dit(bf(tt(nldly=))) label(OPTION_NOFLSH)dit(bf(tt(noflsh=))) label(OPTION_OCRNL)dit(bf(tt(ocrnl=))) label(OPTION_OFDEL)dit(bf(tt(ofdel=))) label(OPTION_OFILL)dit(bf(tt(ofill=))) label(OPTION_OLCUC)dit(bf(tt(olcuc=))) label(OPTION_ONLCR)dit(bf(tt(onlcr=))) label(OPTION_ONLRET)dit(bf(tt(onlret=))) label(OPTION_ONOCR)dit(bf(tt(onocr=))) label(OPTION_OPOST)dit(bf(tt(opost=))) Enables or disables output processing; e.g., converts NL to CR-NL. label(OPTION_OSPEED)dit(bf(tt(ospeed=))) Set the baud rate for outgoing data on this line.nl() See also: link(ispeed)(OPTION_ISPEED), link(b19200)(OPTION_B19200) label(OPTION_PARENB)dit(bf(tt(parenb=))) Enable parity generation on output and parity checking for input. label(OPTION_PARMRK)dit(bf(tt(parmrk=))) label(OPTION_PARODD)dit(bf(tt(parodd=))) label(OPTION_PENDIN)dit(bf(tt(pendin=))) label(OPTION_QUIT)dit(bf(tt(quit=))) label(OPTION_REPRINT)dit(bf(tt(reprint=))) label(OPTION_SANE)dit(bf(tt(sane))) Brings the terminal to something like a useful default state. label(OPTION_START)dit(bf(tt(start=))) label(OPTION_STOP)dit(bf(tt(stop=))) label(OPTION_SUSP)dit(bf(tt(susp=))) label(OPTION_SWTC)dit(bf(tt(swtc=))) label(OPTION_TAB0)dit(bf(tt(tab0))) label(OPTION_TAB1)dit(bf(tt(tab1))) label(OPTION_TAB2)dit(bf(tt(tab2))) label(OPTION_TAB3)dit(bf(tt(tab3))) label(OPTION_TABDLY)dit(bf(tt(tabdly=))) label(OPTION_TIME)dit(bf(tt(time=))) label(OPTION_TOSTOP)dit(bf(tt(tostop=))) label(OPTION_VT0)dit(bf(tt(vt0))) label(OPTION_VT1)dit(bf(tt(vt1))) label(OPTION_VTDLY)dit(bf(tt(vtdly=))) label(OPTION_WERASE)dit(bf(tt(werase=))) label(OPTION_XCASE)dit(bf(tt(xcase=))) label(OPTION_XTABS)dit(bf(tt(xtabs))) label(OPTION_I_POP_ALL)dit(bf(tt(i-pop-all))) With UNIX System V STREAMS, removes all drivers from the stack. label(OPTION_I_PUSH)dit(bf(tt(i-push=))) With UNIX System V STREAMS, pushes the driver (module) with the given name (link(string)(TYPE_STRING)) onto the stack. For example, to make sure that a character device on Solaris supports termios etc, use the following options: tt(i-pop-all,i-push=ptem,i-push=ldterm,i-push=ttcompat) enddit() startdit()enddit()nl() label(GROUP_PTY)em(bf(PTY option group)) These options are intended for use with the link(pty)(ADDRESS_PTY) address type. startdit() label(OPTION_SYMBOLIC_LINK)dit(bf(tt(link=))) Generates a symbolic link that points to the actual pseudo terminal (pty). This might help to solve the problem that ptys are generated with more or less unpredictable names, making it difficult to directly access the socat generated pty automatically. With this option, the user can specify a "fix" point in the file hierarchy that helps him to access the actual pty (link(example)(EXAMPLE_OPTION_SYMBOLIC_LINK)). Beginning with socat() version 1.4.3, the symbolic link is removed when the address is closed (but see option link(unlink-close)(OPTION_UNLINK_CLOSE)). label(OPTION_PTY_WAIT_SLAVE)dit(bf(tt(wait-slave))) Blocks the open phase until a process opens the slave side of the pty. Usually, socat continues after generating the pty with opening the next address or with entering the transfer loop. With the wait-slave option, socat waits until some process opens the slave side of the pty before continuing. This option only works if the operating system provides the tt(poll()) system call. And it depends on an undocumented behaviour of pty's, so it does not work on all operating systems. It has successfully been tested on Linux, FreeBSD, NetBSD, and on Tru64 with openpty. label(OPTION_PTY_INTERVAL)dit(bf(tt(pty-interval=))) When the link(wait-slave)(OPTION_PTY_WAIT_SLAVE) option is set, socat periodically checks the HUP condition using tt(poll()) to find if the pty's slave side has been opened. The default polling interval is 1s. Use the pty-interval option [link(timeval)(TYPE_TIMEVAL)] to change this value. enddit() startdit()enddit()nl() label(GROUP_OPENSSL)em(bf(OPENSSL option group)) These options apply to the link(openssl)(ADDRESS_OPENSSL_CONNECT) and link(openssl-listen)(ADDRESS_OPENSSL_LISTEN) address types. startdit() label(OPTION_OPENSSL_CIPHERLIST)dit(bf(tt(cipher=))) Selects the list of ciphers that may be used for the connection. See the man page of code(ciphers), section bf(CIPHER LIST FORMAT), for detailed information about syntax, values, and default of .nl() Several cipher strings may be given, separated by ':'. Some simple cipher strings: startdit() dit(3DES) Uses a cipher suite with triple DES. dit(MD5) Uses a cipher suite with MD5. dit(aNULL) Uses a cipher suite without authentication. dit(NULL) Does not use encryption. dit(HIGH) Uses a cipher suite with "high" encryption. enddit() Note that the peer must support the selected property, or the negotiation will fail. label(OPTION_OPENSSL_METHOD)dit(bf(tt(method=))) Sets the protocol version to be used. Valid strings (not case sensitive) are: startdit() dit(tt(SSL2)) Select SSL protocol version 2. dit(tt(SSL3)) Select SSL protocol version 3. dit(tt(SSL23)) Select the best available SSL or TLS protocol. This is the default when this option is not provided. dit(tt(TLS1)) Select TLS protocol version 1. dit(tt(TLS1.1)) Select TLS protocol version 1.1. dit(tt(TLS1.2)) Select TLS protocol version 1.2. dit(tt(DTLS1)) Select DTLS protocol version 1. enddit() label(OPTION_OPENSSL_VERIFY)dit(bf(tt(verify=))) Controls check of the peer's certificate. Default is 1 (true). Disabling verify might open your socket for everyone, making the encryption useless! label(OPTION_OPENSSL_CERTIFICATE)dit(bf(tt(cert=))) Specifies the file with the certificate and private key for authentication. The certificate must be in OpenSSL format (*.pem). With openssl-listen, use of this option is strongly recommended. Except with cipher aNULL, "no shared ciphers" error will occur when no certificate is given. label(OPTION_OPENSSL_KEY)dit(bf(tt(key=))) Specifies the file with the private key. The private key may be in this file or in the file given with the link(cert)(OPTION_OPENSSL_CERTIFICATE) option. The party that has to proof that it is the owner of a certificate needs the private key. label(OPTION_OPENSSL_DHPARAMS)dit(bf(tt(dhparams=))) Specifies the file with the Diffie Hellman parameters. These parameters may also be in the file given with the link(cert)(OPTION_OPENSSL_CERTIFICATE) option in which case the dhparams option is not needed. label(OPTION_OPENSSL_CAFILE)dit(bf(tt(cafile=))) Specifies the file with the trusted (root) authority certificates. The file must be in PEM format and should contain one or more certificates. The party that checks the authentication of its peer trusts only certificates that are in this file. label(OPTION_OPENSSL_CAPATH)dit(bf(tt(capath=))) Specifies the directory with the trusted (root) certificates. The directory must contain certificates in PEM format and their hashes (see OpenSSL documentation) label(OPTION_OPENSSL_EGD)dit(bf(tt(egd=))) On some systems, openssl requires an explicit source of random data. Specify the socket name where an entropy gathering daemon like egd provides random data, e.g. /dev/egd-pool. label(OPTION_OPENSSL_PSEUDO)dit(bf(tt(pseudo))) On systems where openssl cannot find an entropy source and where no entropy gathering daemon can be utilized, this option activates a mechanism for providing pseudo entropy. This is archieved by taking the current time in microseconds for feeding the libc pseudo random number generator with an initial value. openssl is then feeded with output from random\() calls.nl() NOTE:This mechanism is not sufficient for generation of secure keys! label(OPTION_OPENSSL_COMPRESS)dit(bf(tt(compress))) Enable or disable the use of compression for a connection. Setting this to "none" disables compression, setting it to "auto" lets OpenSSL choose the best available algorithm supported by both parties. The default is to not touch any compression-related settings. NOTE: Requires OpenSSL 0.9.8 or higher and disabling compression with OpenSSL 0.9.8 affects all new connections in the process. label(OPTION_OPENSSL_COMMONNAME)dit(bf(tt(commonname=))) Specify the commonname that the peer certificate must match. With link(OPENSSL-CONNECT)(ADDRESS_OPENSSL_CONNECT) address this overrides the given hostname or IP target address; with link(OPENSSL-LISTEN)(ADDRESS_OPENSSL_LISTEN) this turns on check of peer certificates commonname. This option has only meaning when option link(verify)(OPTION_OPENSSL_VERIFY) is not disabled and the choosen cipher provides a peer certificate. label(OPTION_OPENSSL_FIPS)dit(bf(tt(fips))) Enables FIPS mode if compiled in. For info about the FIPS encryption implementation standard see lurl(http://oss-institute.org/fips-faq.html). This mode might require that the involved certificates are generated with a FIPS enabled version of openssl. Setting or clearing this option on one socat address affects all OpenSSL addresses of this process. enddit() startdit()enddit()nl() label(GROUP_RETRY)em(bf(RETRY option group)) Options that control retry of some system calls, especially connection attempts. startdit() label(OPTION_RETRY)dit(bf(tt(retry=))) Number of retries before the connection or listen attempt is aborted. Default is 0, which means just one attempt. label(OPTION_INTERVAL)dit(bf(tt(interval=))) Time between consecutive attempts (seconds, [link(timespec)(TYPE_TIMESPEC)]). Default is 1 second. label(OPTION_FOREVER)dit(bf(tt(forever))) Performs an unlimited number of retry attempts. enddit() startdit()enddit()nl() label(GROUP_TUN)em(bf(TUN option group)) Options that control Linux TUN/TAP interface device addresses. startdit() label(OPTION_TUN_DEVICE)dit(bf(tt(tun-device=))) Instructs socat to take another path for the TUN clone device. Default is tt(/dev/net/tun). label(OPTION_TUN_NAME)dit(bf(tt(tun-name=))) Gives the resulting network interface a specific name instead of the system generated (tun0, tun1, etc.) label(OPTION_TUN_TYPE)dit(bf(tt(tun-type=[tun|tap]))) Sets the type of the TUN device; use this option to generate a TAP device. See the Linux docu for the difference between these types. When you try to establish a tunnel between two TUN devices, their types should be the same. label(OPTION_IFF_NO_PI)dit(bf(tt(iff-no-pi))) Sets the IFF_NO_PI flag which controls if the device includes additional packet information in the tunnel. When you try to establish a tunnel between two TUN devices, these flags should have the same values. label(OPTION_IFF_UP)dit(bf(tt(iff-up))) Sets the TUN network interface status UP. Strongly recommended. label(OPTION_IFF_BROADCAST)dit(bf(tt(iff-broadcast))) Sets the BROADCAST flag of the TUN network interface. label(OPTION_IFF_DEBUG)dit(bf(tt(iff-debug))) Sets the DEBUG flag of the TUN network interface. label(OPTION_IFF_LOOPBACK)dit(bf(tt(iff-loopback))) Sets the LOOPBACK flag of the TUN network interface. label(OPTION_IFF_POINTOPOINT)dit(bf(tt(iff-pointopoint))) Sets the POINTOPOINT flag of the TUN device. label(OPTION_IFF_NOTRAILERS)dit(bf(tt(iff-notrailers))) Sets the NOTRAILERS flag of the TUN device. label(OPTION_IFF_RUNNING)dit(bf(tt(iff-running))) Sets the RUNNING flag of the TUN device. label(OPTION_IFF_NOARP)dit(bf(tt(iff-noarp))) Sets the NOARP flag of the TUN device. label(OPTION_IFF_PROMISC)dit(bf(tt(iff-promisc))) Sets the PROMISC flag of the TUN device. label(OPTION_IFF_ALLMULTI)dit(bf(tt(iff-allmulti))) Sets the ALLMULTI flag of the TUN device. label(OPTION_IFF_MASTER)dit(bf(tt(iff-master))) Sets the MASTER flag of the TUN device. label(OPTION_IFF_SLAVE)dit(bf(tt(iff-slave))) Sets the SLAVE flag of the TUN device. label(OPTION_IFF_MULTICAST)dit(bf(tt(iff-multicast))) Sets the MULTICAST flag of the TUN device. label(OPTION_IFFPORTSEL_)dit(bf(tt(iff-portsel))) Sets the PORTSEL flag of the TUN device. label(OPTION_IFF_AUTOMEDIA)dit(bf(tt(iff-automedia))) Sets the AUTOMEDIA flag of the TUN device. label(OPTION_IFF_DYNAMIC)dit(bf(tt(iff-dynamic))) Sets the DYNAMIC flag of the TUN device. enddit() startdit()enddit()nl() label(VALUES) manpagesection(DATA VALUES) This section explains the different data types that address parameters and address options can take. startdit() label(TYPE_ADDRESS_RANGE)dit(address-range) Is currently only implemented for IPv4 and IPv6. See address-option link(`range')(OPTION_RANGE) label(TYPE_BOOL)dit(bool) "0" or "1"; if value is omitted, "1" is taken. label(TYPE_BYTE)dit(byte) An unsigned int number, read with code(strtoul()), lower or equal to code(UCHAR_MAX). label(TYPE_COMMAND_LINE)dit(command-line) A string specifying a program name and its arguments, separated by single spaces. label(TYPE_DATA)dit(data) A raw data specification following em(dalan) syntax. Currently the only valid form is a string starting with 'x' followed by an even number of hex digits, specifying a sequence of bytes. label(TYPE_DIRECTORY)dit(directory) A string with usual unix() directory name semantics. label(TYPE_FACILITY)dit(facility) The name of a syslog facility in lower case characters. label(TYPE_FDNUM)dit(fdnum) An unsigned int type, read with code(strtoul()), specifying a unix() file descriptor. label(TYPE_FILENAME)dit(filename) A string with usual unix() filename semantics. label(TYPE_GROUP)dit(group) If the first character is a decimal digit, the value is read with code(strtoul()) as unsigned integer specifying a group id. Otherwise, it must be an existing group name. label(TYPE_INT)dit(int) A number following the rules of the code(strtol()) function with base "0", i.e. decimal number, octal number with leading "0", or hexadecimal number with leading "0x". The value must fit into a C int. label(TYPE_INTERFACE)dit(interface) A string specifying the device name of a network interface as shown by ifconfig or procan, e.g. "eth0". label(TYPE_IP_ADDRESS)dit(IP address) An IPv4 address in numbers-and-dots notation, an IPv6 address in hex notation enclosed in brackets, or a hostname that resolves to an IPv4 or an IPv6 address.nl() Examples: 127.0.0.1, [::1], www.dest-unreach.org, dns1 label(TYPE_IPV4_ADDRESS)dit(IPv4 address) An IPv4 address in numbers-and-dots notation or a hostname that resolves to an IPv4 address.nl() Examples: 127.0.0.1, www.dest-unreach.org, dns2 label(TYPE_IPV6_ADDRESS)dit(IPv6 address) An iPv6 address in hexnumbers-and-colons notation enclosed in brackets, or a hostname that resolves to an IPv6 address.nl() Examples: [::1], [1234:5678:9abc:def0:1234:5678:9abc:def0], ip6name.domain.org label(TYPE_LONG)dit(long) A number read with code(strtol()). The value must fit into a C long. label(TYPE_LONGLONG)dit(long long) A number read with code(strtoll()). The value must fit into a C long long. label(TYPE_OFF)dit(off_t) An implementation dependend signed number, usually 32 bits, read with strtol or strtoll. label(TYPE_OFF64)dit(off64_t) An implementation dependend signed number, usually 64 bits, read with strtol or strtoll. label(TYPE_MODE_T)dit(mode_t) An unsigned integer, read with code(strtoul()), specifying mode (permission) bits. label(TYPE_PID_T)dit(pid_t) A number, read with code(strtol()), specifying a process id. label(TYPE_PORT)dit(port) A uint16_t (16 bit unsigned number) specifying a TCP or UDP port, read with code(strtoul()). label(TYPE_PROTOCOL)dit(protocol) An unsigned 8 bit number, read with code(strtoul()). label(TYPE_SIZE_T)dit(size_t) An unsigned number with size_t limitations, read with code(strtoul). label(TYPE_SOCKNAME)dit(sockname) A socket address. See address-option link(`bind')(OPTION_BIND) label(TYPE_STRING)dit(string) A sequence of characters, not containing '\0' and, depending on the position within the command line, ':', ',', or "!!". Note that you might have to escape shell meta characters in the command line. label(TYPE_TCP_SERVICE)dit(TCP service) A service name, not starting with a digit, that is resolved by code(getservbyname()), or an unsigned int 16 bit number read with code(strtoul()). label(TYPE_TIMEVAL)dit(timeval) A double float specifying seconds; the number is mapped into a struct timeval, consisting of seconds and microseconds. label(TYPE_TIMESPEC)dit(timespec) A double float specifying seconds; the number is mapped into a struct timespec, consisting of seconds and nanoseconds. label(TYPE_UDP_SERVICE)dit(UDP service) A service name, not starting with a digit, that is resolved by code(getservbyname()), or an unsigned int 16 bit number read with code(strtoul()). label(TYPE_UNSIGNED_INT)dit(unsigned int) A number read with code(strtoul()). The value must fit into a C unsigned int. label(TYPE_USER)dit(user) If the first character is a decimal digit, the value is read with code(strtoul()) as unsigned integer specifying a user id. Otherwise, it must be an existing user name. enddit() label(EXAMPLES) manpagesection(EXAMPLES) startdit() label(EXAMPLE_ADDRESS_TCP4_CONNECT) dit(bf(tt(socat - TCP4:www.domain.org:80))) transfers data between link(STDIO)(ADDRESS_STDIO) (-) and a link(TCP4)(ADDRESS_TCP4_CONNECT) connection to port 80 of host www.domain.org. This example results in an interactive connection similar to telnet or netcat. The stdin terminal parameters are not changed, so you may close the relay with ^D or abort it with ^C. label(EXAMPLE_ADDRESS_READLINE) label(EXAMPLE_OPTION_HISTORY) mancommand(\.LP) mancommand(\.nf) mancommand(\fBsocat -d -d READLINE,history=$HOME/.http_history \\ TCP4:www.domain.org:www,crnl\fP) mancommand(\.fi) htmlcommand(
socat -d -d READLINE,history=$HOME/.http_history \
TCP4:www.domain.org:www,crnl
) this is similar to the previous example, but you can edit the current line in a bash like manner (link(READLINE)(ADDRESS_READLINE)) and use the link(history)(OPTION_HISTORY) file .http_history; socat() prints messages about progress (link(-d -d)(option_d_d)). The port is specified by service name (www), and correct network line termination characters (link(crnl)(OPTION_CRNL)) instead of NL are used. label(EXAMPLE_ADDRESS_TCP4_LISTEN) dit(bf(tt(socat TCP4-LISTEN:www TCP4:www.domain.org:www))) installs a simple TCP port forwarder. With link(TCP4-LISTEN)(ADDRESS_TCP4_LISTEN) it listens on local port "www" until a connection comes in, accepts it, then connects to the remote host (link(TCP4)(ADDRESS_TCP4_CONNECT)) and starts data transfer. It will not accept a econd connection. label(EXAMPLE_OPTION_BIND_TCP4) label(EXAMPLE_OPTION_REUSEADDR) label(EXAMPLE_OPTION_FORK) label(EXAMPLE_OPTION_SUBSTUSER) label(EXAMPLE_OPTION_RANGE) mancommand(\.LP) mancommand(\.nf) mancommand(\fBsocat -d -d -lmlocal2 \\ TCP4-LISTEN:80,bind=myaddr1,reuseaddr,fork,su=nobody,range=10.0.0.0/8 \\ TCP4:www.domain.org:80,bind=myaddr2\fP) mancommand(\.fi) htmlcommand(
socat -d -d -lmlocal2 \
TCP4-LISTEN:80,bind=myaddr1,su=nobody,fork,range=10.0.0.0/8,reuseaddr \
TCP4:www.domain.org:80,bind=myaddr2
) TCP port forwarder, each side bound to another local IP address (link(bind)(OPTION_BIND)). This example handles an almost arbitrary number of parallel or consecutive connections by link(fork)(OPTION_FORK)'ing a new process after each code(accept()). It provides a little security by link(su)(OPTION_SUBSTUSER)'ing to user nobody after forking; it only permits connections from the private 10 network (link(range)(OPTION_RANGE)); due to link(reuseaddr)(OPTION_REUSEADDR), it allows immediate restart after master process's termination, even if some child sockets are not completely shut down. With link(-lmlocal2)(option_lm), socat logs to stderr until successfully reaching the accept loop. Further logging is directed to syslog with facility local2. label(EXAMPLE_ADDRESS_EXEC) label(EXAMPLE_OPTION_TCPWRAPPERS) label(EXAMPLE_OPTION_CHROOT) label(EXAMPLE_OPTION_SUBSTUSER_DELAYED) label(EXAMPLE_OPTION_PTY) label(EXAMPLE_OPTION_STDERR) mancommand(\.LP) mancommand(\.nf) mancommand(\fBsocat TCP4-LISTEN:5555,fork,tcpwrap=script \\ EXEC:/bin/myscript,chroot=/home/sandbox,su-d=sandbox,pty,stderr\fP) mancommand(\.fi) htmlcommand(
socat TCP4-LISTEN:5555,fork,tcpwrap=script \
EXEC:/bin/myscript,chroot=/home/sandbox,su-d=sandbox,pty,stderr
) a simple server that accepts connections (link(TCP4-LISTEN)(ADDRESS_TCP4_LISTEN)) and link(fork)(OPTION_FORK)'s a new child process for each connection; every child acts as single relay. The client must match the rules for daemon process name "script" in /etc/hosts.allow and /etc/hosts.deny, otherwise it is refused access (see "man 5 hosts_access"). For link(EXEC)(ADDRESS_EXEC)'uting the program, the child process link(chroot)(OPTION_CHROOT)'s to file(/home/sandbox), link(su)(OPTION_SUBSTUSER)'s to user sandbox, and then starts the program file(/home/sandbox/bin/myscript). Socat() and myscript communicate via a pseudo tty (link(pty)(OPTION_PTY)); myscript's link(stderr)(OPTION_STDERR) is redirected to stdout, so its error messages are transferred via socat() to the connected client. label(EXAMPLE_OPTION_FDIN) label(EXAMPLE_OPTION_FDOUT) label(EXAMPLE_OPTION_CRNL) label(EXAMPLE_OPTION_MSS) mancommand(\.LP) mancommand(\.nf) mancommand(\fBsocat EXEC:"mail.sh target@domain.com",fdin=3,fdout=4 \\ TCP4:mail.relay.org:25,crnl,bind=alias1.server.org,mss=512\fP) mancommand(\.fi) htmlcommand(
socat EXEC:"mail.sh target@domain.com",fdin=3,fdout=4 \
TCP4:mail.relay.org:25,crnl,bind=alias1.server.org,mss=512
) file(mail.sh) is a shell script, distributed with socat(), that implements a simple SMTP client. It is programmed to "speak" SMTP on its FDs 3 (in) and 4 (out). The link(fdin)(OPTION_FDIN) and link(fdout)(OPTION_FDOUT) options tell socat() to use these FDs for communication with the program. Because mail.sh inherits stdin and stdout while socat() does not use them, the script can read a mail body from stdin. Socat() makes alias1 your local source address (link(bind)(OPTION_BIND)), cares for correct network line termination (link(crnl)(OPTION_CRNL)) and sends at most 512 data bytes per packet (link(mss)(OPTION_MSS)). label(EXAMPLE_ADDRESS_GOPEN) label(EXAMPLE_OPTION_TERMIOS_RAWER) label(EXAMPLE_OPTION_ESCAPE) dit(bf(tt(socat -,escape=0x0f /dev/ttyS0,rawer,crnl))) opens an interactive connection via the serial line, e.g. for talking with a modem. link(rawer)(OPTION_TERMIOS_RAWER) sets the console's and ttyS0's terminal parameters to practicable values, link(crnl)(OPTION_CRNL) converts to correct newline characters. link(escape)(OPTION_ESCAPE) allows to terminate the socat process with character control-O. Consider using link(READLINE)(ADDRESS_READLINE) instead of the first address. label(EXAMPLE_ADDRESS_UNIX_LISTEN) label(EXAMPLE_ADDRESS_SOCKS4) label(EXAMPLE_OPTION_SOCKSUSER) label(EXAMPLE_OPTION_SOURCEPORT) mancommand(\.LP) mancommand(\.nf) mancommand(\fBsocat UNIX-LISTEN:/tmp/.X11-unix/X1,fork \\ SOCKS4:host.victim.org:127.0.0.1:6000,socksuser=nobody,sourceport=20\fP) mancommand(\.fi) htmlcommand(
socat UNIX-LISTEN:/tmp/.X11-unix/X1,fork \
SOCKS4:host.victim.org:127.0.0.1:6000,socksuser=nobody,sourceport=20
) with link(UNIX-LISTEN)(ADDRESS_UNIX_LISTEN), socat() opens a listening unixdomain() socket file(/tmp/.X11-unix/X1). This path corresponds to local XWindow display :1 on your machine, so XWindow client connections to DISPLAY=:1 are accepted. Socat() then speaks with the link(SOCKS4)(ADDRESS_SOCKS4) server host.victim.org that might permit link(sourceport)(OPTION_SOURCEPORT) 20 based connections due to an FTP related weakness in its static IP filters. Socat() pretends to be invoked by link(socksuser)(OPTION_SOCKSUSER) nobody, and requests to be connected to loopback port 6000 (only weak sockd configurations will allow this). So we get a connection to the victims XWindow server and, if it does not require MIT cookies or Kerberos authentication, we can start work. Please note that there can only be one connection at a time, because TCP can establish only one session with a given set of addresses and ports. label(EXAMPLE_option_u) label(EXAMPLE_OPTION_IGNOREEOF) dit(bf(tt(socat -u /tmp/readdata,seek-end=0,ignoreeof -))) this is an example for unidirectional data transfer (link(-u)(option_u)). Socat() transfers data from file /tmp/readdata (implicit address link(GOPEN)(ADDRESS_GOPEN)), starting at its current end (link(seek-end)(OPTION_SEEK_END)=0 lets socat() start reading at current end of file; use link(seek)(OPTION_SEEK)=0 or no seek option to first read the existing data) in a "tail -f" like mode (link(ignoreeof)(OPTION_IGNOREEOF)). The "file" might also be a listening unixdomain() socket (do not use a seek option then). label(EXAMPLE_OPTION_SETSID) label(EXAMPLE_OPTION_CTTY) mancommand(\.LP) mancommand(\.nf) mancommand(\fB(sleep 5; echo PASSWORD; sleep 5; echo ls; sleep 1) | socat - EXEC:'ssh -l user server',pty,setsid,ctty\fP) mancommand(\.fi) htmlcommand(
(sleep 5; echo PASSWORD; sleep 5; echo ls; sleep 1) |
socat - EXEC:'ssh -l user server',pty,setsid,ctty
) link(EXEC)(ADDRESS_EXEC)'utes an ssh session to server. Uses a link(pty)(OPTION_PTY) for communication between socat() and ssh, makes it ssh's controlling tty (link(ctty)(OPTION_CTTY)), and makes this pty the owner of a new process group (link(setsid)(OPTION_SETSID)), so ssh accepts the password from socat(). label(EXAMPLE_ADDRESS_OPEN) label(EXAMPLE_OPTION_CREAT) label(EXAMPLE_OPTION_APPEND) mancommand(\.LP) mancommand(\.nf) mancommand(\fBsocat -u TCP4-LISTEN:3334,reuseaddr,fork \\ OPEN:/tmp/in.log,creat,append\fP) mancommand(\.fi) htmlcommand(
socat -u TCP4-LISTEN:3334,reuseaddr,fork \
OPEN:/tmp/in.log,creat,append
) implements a simple network based message collector. For each client connecting to port 3334, a new child process is generated (option link(fork)(OPTION_FORK)). All data sent by the clients are link(append)(OPTION_APPEND)'ed to the file /tmp/in.log. If the file does not exist, socat link(creat)(OPTION_O_CREAT)'s it. Option link(reuseaddr)(OPTION_REUSEADDR) allows immediate restart of the server process. COMMENT( dit(bf(tt(socat TCP4-LISTEN:3335,reuseaddr,fork OPEN:/tmp/motd,rdonly))) implements a simple network based motd server. For each client connecting to port 3335, a new child process is generated (option link(fork)(OPTION_FORK)). The contents of the file /tmp/motd is sent to each client. Messages sent by clients result in an error due to option link(rdonly)(OPTION_RDONLY). Option link(reuseaddr)(OPTION_REUSEADDR) allows immediate restart of the server process. ) COMMENT( dit(bf(tt(socat - TCP4-LISTEN:8080,mtudiscover=0,rcvbuf=2048))) changes some socket parameters to confuse active OS fingerprinting methods. link(mtudiscover)(OPTION_MTUDISCOVER)=0 sets the DF (don'ft fragment flag) in the IP packets to 0 and link(rcvbuf)(OPTION_RCVBUF) changes the initial TCP window size. ) label(EXAMPLE_OPTION_NOECHO) dit(bf(tt(socat READLINE,noecho='[Pp]assword:' EXEC:'ftp ftp.server.com',pty,setsid,ctty))) wraps a command line history (link(READLINE)(ADDRESS_READLINE)) around the link(EXEC)(ADDRESS_EXEC)'uted ftp client utility. This allows editing and reuse of FTP commands for relatively comfortable browsing through the ftp directory hierarchy. The password is echoed! link(pty)(OPTION_PTY) is required to have ftp issue a prompt. Nevertheless, there may occur some confusion with the password and FTP prompts. label(EXAMPLE_ADDRESS_PTY) label(EXAMPLE_OPTION_SYMBOLIC_LINK) label(EXAMPLE_OPTION_WAIT_SLAVE) label(EXAMPLE_OPTION_NONBLOCK) mancommand(\.LP) mancommand(\.nf) mancommand(\fBsocat PTY,link=$HOME/dev/vmodem0,rawer,wait-slave \\\bf) mancommand(\fBEXEC:"ssh modemserver.us.org socat - /dev/ttyS0,nonblock,rawer"\fP) mancommand(\.fi) htmlcommand(
socat PTY,link=$HOME/dev/vmodem0,rawer,wait-slave \
EXEC:'"ssh modemserver.us.org socat - /dev/ttyS0,nonblock,rawer"'
) generates a pseudo terminal device (link(PTY)(ADDRESS_PTY)) on the client that can be reached under the symbolic link(link)(OPTION_SYMBOLIC_LINK) file($HOME/dev/vmodem0). An application that expects a serial line or modem can be configured to use file($HOME/dev/vmodem0); its traffic will be directed to a modemserver via ssh where another socat instance links it to file(/dev/ttyS0). mancommand(\.LP) mancommand(\.nf) mancommand(\fBsocat TCP4-LISTEN:2022,reuseaddr,fork \\ PROXY:proxy:www.domain.org:22,proxyport=3128,proxyauth=user:pass\fP) mancommand(\.fi) htmlcommand(
socat TCP4-LISTEN:2022,reuseaddr,fork \
PROXY:proxy:www.domain.org:22,proxyport=3128,proxyauth=user:pass
) starts a forwarder that accepts connections on port 2022, and directs them through the link(proxy)(ADDRESS_PROXY_CONNECT) daemon listening on port 3128 (link(proxyport)(OPTION_PROXYPORT)) on host proxy, using the CONNECT method, where they are authenticated as "user" with "pass" (link(proxyauth)(OPTION_PROXY_AUTHORIZATION)). The proxy should establish connections to host www.domain.org on port 22 then. label(EXAMPLE_ADDRESS_OPENSSL_CONNECT) dit(bf(tt(socat - SSL:server:4443,cafile=server.crt,cert=client.pem))) is an OpenSSL client that tries to establish a secure connection to an SSL server. Option link(cafile)(OPTION_OPENSSL_CAFILE) specifies a file that contains trust certificates: we trust the server only when it presents one of these certificates and proofs that it owns the related private key. Otherwise the connection is terminated. With link(cert)(OPTION_OPENSSL_CERTIFICATE) a file containing the client certificate and the associated private key is specified. This is required in case the server wishes a client authentication; many Internet servers do not.nl() The first address ('-') can be replaced by almost any other socat address. label(EXAMPLE_ADDRESS_OPENSSL_LISTEN) dit(bf(tt(socat SSL-LISTEN:4443,reuseaddr,pf=ip4,fork,cert=server.pem,cafile=client.crt PIPE))) is an OpenSSL server that accepts TCP connections, presents the certificate from the file server.pem and forces the client to present a certificate that is verified against cafile.crt.nl() The second address ('PIPE') can be replaced by almost any other socat address.nl() For instructions on generating and distributing OpenSSL keys and certificates see the additional socat docu tt(socat-openssl.txt). dit(bf(tt(echo |socat -u - file:/tmp/bigfile,create,largefile,seek=100000000000))) creates a 100GB sparse file; this requires a file system type that supports this (ext2, ext3, reiserfs, jfs; not minix, vfat). The operation of writing 1 byte might take long (reiserfs: some minutes; ext2: "no" time), and the resulting file can consume some disk space with just its inodes (reiserfs: 2MB; ext2: 16KB). dit(bf(tt(socat tcp-l:7777,reuseaddr,fork system:'filan -i 0 -s >&2',nofork))) listens for incoming TCP connections on port 7777. For each accepted connection, invokes a shell. This shell has its stdin and stdout directly connected to the TCP socket (link(nofork)(OPTION_NOFORK)). The shell starts filan and lets it print the socket addresses to stderr (your terminal window). dit(bf(tt(echo -e "\0\14\0\0\c" |socat -u - file:/usr/bin/squid.exe,seek=0x00074420))) functions as primitive binary editor: it writes the 4 bytes 000 014 000 000 to the executable /usr/bin/squid at offset 0x00074420 (this is a real world patch to make the squid executable from Cygwin run under Windows, actual per May 2004). dit(bf(tt(socat - tcp:www.blackhat.org:31337,readbytes=1000))) connects to an unknown service and prevents being flooded. label(EXAMPLE_END_CLOSE) dit(bf(tt(socat -U TCP:target:9999,end-close TCP-L:8888,reuseaddr,fork))) merges data arriving from different TCP streams on port 8888 to just one stream to target:9999. The link(end-close)(OPTION_END_CLOSE) option prevents the child processes forked off by the second address from terminating the shared connection to 9999 (close\(2) just unlinks the inode which stays active as long as the parent process lives; shutdown\(2) would actively terminate the connection). label(EXAMPLE_ADDRESS_UDP4_BROADCAST_CLIENT) dit(bf(tt(socat - UDP4-DATAGRAM:192.168.1.0:123,sp=123,broadcast,range=192.168.1.0/24))) sends a broadcast to the network 192.168.1.0/24 and receives the replies of the timeservers there. Ignores NTP packets from hosts outside this network. label(EXAMPLE_ADDRESS_GENERIC_CLIENT) dit(bf(tt(socat - SOCKET-DATAGRAM:2:2:17:x007bxc0a80100x0000000000000000,bind=x007bx00000000x0000000000000000,setsockopt-int=1:6:1,range=x0000xc0a80100x0000000000000000:x0000xffffff00x0000000000000000))) is semantically equivalent to the link(previous example)(EXAMPLE_ADDRESS_UDP4_BROADCAST_CLIENT), but all parameters are specified in generic form. the value 6 of setsockopt-int is the Linux value for tt(SO_BROADCAST). label(EXAMPLE_ADDRESS_IP4_BROADCAST_CLIENT) dit(bf(tt(socat - IP4-DATAGRAM:255.255.255.255:44,broadcast,range=10.0.0.0/8))) sends a broadcast to the local network\(s) using protocol 44. Accepts replies from the private address range only. label(EXAMPLE_ADDRESS_UDP4_MULTICAST) dit(bf(tt(socat - UDP4-DATAGRAM:224.255.0.1:6666,bind=:6666,ip-add-membership=224.255.0.1:eth0))) transfers data from stdin to the specified multicast address using UDP. Both local and remote ports are 6666. Tells the interface eth0 to also accept multicast packets of the given group. Multiple hosts on the local network can run this command, so all data sent by any of the hosts will be received by all the other ones. Note that there are many possible reasons for failure, including IP-filters, routing issues, wrong interface selection by the operating system, bridges, or a badly configured switch. label(EXAMPLE_ADDRESS_TUN) dit(bf(tt(socat TCP:host2:4443 TUN:192.168.255.1/24,up))) establishes one side of a virtual (but not private!) network with host2 where a similar process might run, with UDP-L and tun address 192.168.255.2. They can reach each other using the addresses 192.168.255.1 and 192.168.255.2. Note that streaming eg. via TCP or SSL does not guarantee to retain packet boundaries and may thus cause packet loss. label(EXAMPLE_INTERFACE) dit(bf(tt(socat PTY,link=/var/run/ppp,rawer INTERFACE:hdlc0))) circumvents the problem that pppd requires a serial device and thus might not be able to work on a synchronous line that is represented by a network device. socat creates a PTY to make pppd happy, binds to the network link(interface)(ADDRESS_INTERFACE) tt(hdlc0), and can transfer data between both devices. Use pppd on device tt(/var/run/ppp) then. label(EXAMPLE_HTTPECHO) dit(bf(tt(socat -T 1 -d -d TCP-L:10081,reuseaddr,fork,crlf SYSTEM:"echo -e \"\\\"HTTP/1.0 200 OK\\\nDocumentType: text/plain\\\n\\\ndate: \$\(date\)\\\nserver:\$SOCAT_SOCKADDR:\$SOCAT_SOCKPORT\\\nclient: \$SOCAT_PEERADDR:\$SOCAT_PEERPORT\\\n\\\"\"; cat; echo -e \"\\\"\\\n\\\"\""))) creates a simple HTTP echo server: each HTTP client that connects gets a valid HTTP reply that contains information about the client address and port as it is seen by the server host, the host address (which might vary on multihomed servers), and the original client request. label(EXAMPLE_ANCILLARY) dit(bf(tt(socat -d -d UDP4-RECVFROM:9999,so-broadcast,so-timestamp,ip-pktinfo,ip-recverr,ip-recvopts,ip-recvtos,ip-recvttl!!- SYSTEM:'export; sleep 1' |grep SOCAT))) waits for an incoming UDP packet on port 9999 and prints the environment variables provided by socat. On BSD based systems you have to replace link(tt(ip-pktinfo))(OPTION_IP_PKTINFO) with link(tt(ip-recvdstaddr))(OPTION_IP_RECVDSTADDR),link(tt(ip-recvif))(OPTION_IP_RECVIF). Especially interesting is SOCAT_IP_DSTADDR: it contains the target address of the packet which may be a unicast, multicast, or broadcast address. dit(bf(tt())) enddit() label(DIAGNOSTICS) manpagediagnostics() Socat() uses a logging mechanism that allows to filter messages by severity. The severities provided are more or less compatible to the appropriate syslog priority. With one or up to four occurrences of the -d command line option, the lowest priority of messages that are issued can be selected. Each message contains a single uppercase character specifying the messages severity (one of F, E, W, N, I, or D) description( dit(FATAL:) Conditions that require unconditional and immediate program termination. dit(ERROR:) Conditions that prevent proper program processing. Usually the program is terminated (see link(option -s)(option_s)). dit(WARNING:) Something did not function correctly or is in a state where correct further processing cannot be guaranteed, but might be possible. dit(NOTICE:) Interesting actions of the program, e.g. for supervising socat() in some kind of server mode. dit(INFO:) Description of what the program does, and maybe why it happens. Allows to monitor the lifecycles of file descriptors. dit(DEBUG:) Description of how the program works, all system or library calls and their results. ) Log messages can be written to stderr, to a file, or to syslog. On exit, socat() gives status 0 if it terminated due to EOF or inactivity timeout, with a positive value on error, and with a negative value on fatal error. label(FILES) manpagefiles() /usr/bin/socat nl() /usr/bin/filan nl() /usr/bin/procan label(ENVIRONMENT_VARIABLES) manpagesection(ENVIRONMENT VARIABLES) Input variables carry information from the environment to socat, output variables are set by socat for use in executed scripts and programs. In the output variables beginning with "SOCAT" this prefix is actually replaced by the upper case name of the executable or the value of option link(-lp)(option_lp). startdit() label(ENV_SOCAT_DEFAULT_LISTEN_IP) dit(bf(SOCAT_DEFAULT_LISTEN_IP) (input)) (Values 4 or 6) Sets the IP version to be used for listen, recv, and recvfrom addresses if no link(pf)(OPTION_PROTOCOL_FAMILY) (protocol-family) option is given. Is overridden by socat options link(-4)(option_4) or link(-6)(option_6). dit(bf(SOCAT_PREFERRED_RESOLVE_IP) (input)) (Values 0, 4, or 6) Sets the IP version to be used when resolving target host names when version is not specified by address type, option link(pf)(OPTION_PROTOCOL_FAMILY) (protocol-family), or address format. If name resolution does not return a matching entry, the first result (with differing IP version) is taken. With value 0, socat always selects the first record and its IP version. dit(bf(SOCAT_FORK_WAIT) (input)) Specifies the time (seconds) to sleep the parent and child processes after successful fork\(). Useful for debugging. dit(bf(SOCAT_VERSION) (output)) Socat sets this variable to its version string, e.g. tt("1.7.0.0") for released versions or e.g. tt("1.6.0.1+envvar") for temporary versions; can be used in scripts invoked by socat. dit(bf(SOCAT_PID) (output)) Socat sets this variable to its process id. In case of link(fork)(OPTION_FORK) address option, SOCAT_PID gets the child processes id. Forking for link(exec)(ADDRESS_EXEC) and link(system)(ADDRESS_SYSTEM) does not change SOCAT_PID. dit(bf(SOCAT_PPID) (output)) Socat sets this variable to its process id. In case of link(fork)(OPTION_FORK), SOCAT_PPID keeps the pid of the master process. dit(bf(SOCAT_PEERADDR) (output)) With passive socket addresses (all LISTEN and RECVFROM addresses), this variable is set to a string describing the peers socket address. Port information is not included. dit(bf(SOCAT_PEERPORT) (output)) With appropriate passive socket addresses (TCP, UDP, and SCTP - LISTEN and RECVFROM), this variable is set to a string containing the number of the peer port. dit(bf(SOCAT_SOCKADDR) (output)) With all LISTEN addresses, this variable is set to a string describing the local socket address. Port information is not included link(example)(EXAMPLE_HTTPECHO) dit(bf(SOCAT_SOCKPORT) (output)) With link(TCP-LISTEN)(ADDRESS_TCP_LISTEN), link(UDP-LISTEN)(ADDRESS_UDP_LISTEN), and link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN) addresses, this variable is set to the local port. dit(bf(SOCAT_TIMESTAMP) (output)) With all RECVFROM addresses where address option link(so-timestamp)(OPTION_SO_TIMESTAMP) is applied, socat sets this variable to the resulting timestamp. dit(bf(SOCAT_IP_OPTIONS) (output)) With all IPv4 based RECVFROM addresses where address option link(ip-recvopts)(OPTION_IP_RECVOPTS) is applied, socat fills this variable with the IP options of the received packet. dit(bf(SOCAT_IP_DSTADDR) (output)) With all IPv4 based RECVFROM addresses where address option link(ip-recvdstaddr)(OPTION_IP_RECVDSTADDR) (BSD) or link(ip-pktinfo)(OPTION_IP_PKTINFO) (other platforms) is applied, socat sets this variable to the destination address of the received packet. This is particularly useful to identify broadcast and multicast addressed packets. dit(bf(SOCAT_IP_IF) (output)) With all IPv4 based RECVFROM addresses where address option link(ip-recvif)(OPTION_IP_RECVIF) (BSD) or link(ip-pktinfo)(OPTION_IP_PKTINFO) (other platforms) is applied, socat sets this variable to the name of the interface where the packet was received. dit(bf(SOCAT_IP_LOCADDR) (output)) With all IPv4 based RECVFROM addresses where address option link(ip-pktinfo)(OPTION_IP_PKTINFO) is applied, socat sets this variable to the address of the interface where the packet was received. dit(bf(SOCAT_IP_TOS) (output)) With all IPv4 based RECVFROM addresses where address option link(ip-recvtos)(OPTION_IP_RECVTOS) is applied, socat sets this variable to the TOS (type of service) of the received packet. dit(bf(SOCAT_IP_TTL) (output)) With all IPv4 based RECVFROM addresses where address option link(ip-recvttl)(OPTION_IP_RECVTTL) is applied, socat sets this variable to the TTL (time to live) of the received packet. dit(bf(SOCAT_IPV6_HOPLIMIT) (output)) With all IPv6 based RECVFROM addresses where address option link(ipv6-recvhoplimit)(OPTION_IPV6_RECVHOPLIMIT) is applied, socat sets this variable to the hoplimit value of the received packet. dit(bf(SOCAT_IPV6_DSTADDR) (output)) With all IPv6 based RECVFROM addresses where address option link(ipv6-recvpktinfo)(OPTION_IPV6_RECVPKTINFO) is applied, socat sets this variable to the destination address of the received packet. dit(bf(SOCAT_IPV6_TCLASS) (output)) With all IPv6 based RECVFROM addresses where address option link(ipv6-recvtclass)(OPTION_IPV6_RECVTCLASS) is applied, socat sets this variable to the transfer class of the received packet. dit(bf(SOCAT_OPENSSL_X509_ISSUER) (output)) Issuer field from peer certificate dit(bf(SOCAT_OPENSSL_X509_SUBJECT) (output)) Subject field from peer certificate dit(bf(SOCAT_OPENSSL_X509_COMMONNAME) (output)) commonName entries from peer certificates subject. Multiple values are separated by " // ". dit(bf(SOCAT_OPENSSL_X509_*) (output)) all other entries from peer certificates subject dit(bf(SOCAT_OPENSSL_X509V3_DNS) (output)) DNS entries from peer certificates extensions - subjectAltName field. Multiple values are separated by " // ". dit(bf(HOSTNAME) (input)) Is used to determine the hostname for logging (see link(-lh)(option_lh)). dit(bf(LOGNAME) (input)) Is used as name for the socks client user name if no link(socksuser)(OPTION_SOCKSUSER) is given.nl() With options link(su)(OPTION_SUBSTUSER) and link(su-d)(OPTION_SUBSTUSER_DELAYED), LOGNAME is set to the given user name. dit(bf(USER) (input)) Is used as name for the socks client user name if no link(socksuser)(OPTION_SOCKSUSER) is given and LOGNAME is empty.nl() With options link(su)(OPTION_SUBSTUSER) and link(su-d)(OPTION_SUBSTUSER_DELAYED), USER is set to the given user name. dit(bf(SHELL) (output)) With options link(su)(OPTION_SUBSTUSER) and link(su-d)(OPTION_SUBSTUSER_DELAYED), SHELL is set to the login shell of the given user. dit(bf(PATH) (output)) Can be set with option link(path)(OPTION_PATH) for link(exec)(ADDRESS_EXEC) and link(system)(ADDRESS_SYSTEM) addresses. dit(bf(HOME) (output)) With options link(su)(OPTION_SUBSTUSER) and link(su-d)(OPTION_SUBSTUSER_DELAYED), HOME is set to the home directory of the given user. enddit() label(CREDITS) manpagesection(CREDITS) The work of the following groups and organizations was invaluable for this project: The em(FSF) (GNU, lurl(http://www.fsf.org/) project with their free and portable development software and lots of other useful tools and libraries. The em(Linux developers community) (lurl(http://www.linux.org/)) for providing a free, open source operating system. The em(Open Group) (lurl(http://www.unix-systems.org/)) for making their standard specifications available on the Internet for free. label(VERSION) manpagesection(VERSION) This man page describes version 1.7.3 of socat(). label(BUGS) manpagebugs() Addresses cannot be nested, so a single socat process cannot, e.g., drive ssl over socks. Address option ftruncate without value uses default 1 instead of 0. Verbose modes (-x and/or -v) display line termination characters inconsistently when address options cr or crnl are used: They show the data em(after) conversion in either direction. The data transfer blocksize setting (-b) is ignored with address readline. Send bug reports to label(SEEALSO) manpageseealso() COMMENT(procan\(1), filan\(1), ) nc\(1), netcat6\(1), sock\(1), rinetd\(8), cage\(1), socks.conf\(5), openssl\(1), stunnel\(8), pty\(1), rlwrap\(1), setsid\(1) Socat() home page lurl(http://www.dest-unreach.org/socat/) label(AUTHOR) manpageauthor() Gerhard Rieger socat-1.7.3.1/doc/socat-openssltunnel.html0000644000201000020100000002047511073730010020233 0ustar gerhardgerhard Securing Traffic Between two Socat Instances Using SSL

Securing Traffic Between two Socat Instances Using SSL

Introduction

When you want to connect two socat processes running on different machines and feel that you need to protect the connection against unauthorized access, sniffing, data manipulation etc., you might want to encrypt the communications.

For this purpose socat integrates the OpenSSL library and provides SSL client and server features.

SSL is a complex protocol that provides much more features than required for protecting a single connection; in this document we present only a simple scenario that provides just the basic security requirements.

Configuring OpenSSL in socat

This section shows how the SSL addresses can be configured in socat. In this docu we only use self signed certificates for the sake of simplicity.

We assume that the server host is called server.domain.org and the server process uses port 4433. To keep it simple, we use a very simple server funtionality that just echos data (echo), and stdio on the client.

Generate a server certificate

Perform the following steps on a trusted host where OpenSSL is installed. It might as well be the client or server host themselves.

Prepare a basename for the files related to the server certificate:

FILENAME=server

Generate a public/private key pair:

openssl genrsa -out $FILENAME.key 1024

Generate a self signed certificate:

openssl req -new -key $FILENAME.key -x509 -days 3653 -out $FILENAME.crt

You will be prompted for your country code, name etc.; you may quit all prompts with the enter key.

Generate the PEM file by just appending the key and certificate files:

cat $FILENAME.key $FILENAME.crt >$FILENAME.pem

The files that contain the private key should be kept secret, thus adapt their permissions:

chmod 600 $FILENAME.key $FILENAME.pem

Now bring the file server.pem to the SSL server, e.g. to directory $HOME/etc/, using a secure channel like USB memory stick or SSH. Keep tight permissions on the file even on the target host, and remove all other instances of server.key and server.pem.

Copy the trust certificate server.crt to the SSL client host, e.g. to directory $HOME/etc/; a secure channel is not required here, and the permissions are not critical.

Generate a client certificate

First prepare a different basename for the files related to the client certificate:

FILENAME=client

Repeat the procedure for certificate generation described above. Copy client.pem to the SSL client, and client.crt to the server.

OpenSSL Server

Instead of using a tcp-listen (tcp-l) address, we use openssl-listen (ssl-l) for the server, cert=... tells the program to the file containing its ceritificate and private key, and cafile=... points to the file containing the certificate of the peer; we trust clients only if they can proof that they have the related private key (OpenSSL handles this for us):

socat openssl-listen:4433,reuseaddr,cert=$HOME/etc/server.pem,cafile=$HOME/etc/client.crt echo

After starting this command, socat should be listening on port 4433, but will require client authentication.

OpenSSL Client

Substitute your tcp-connect or tcp address keyword with openssl-connect or just ssl and here too add the cert and cafile options:

socat stdio openssl-connect:server.domain.org:4433,cert=$HOME/etc/client.pem,cafile=$HOME/etc/server.crt

This command should establish a secured connection to the server process.

TCP/IP version 6

If the communication is to go over IPv6, the above described commands have to be adapted; ip6name.domain.org is assumed to resolve to the IPv6 address of the server:

Server:

socat openssl-listen:4433,pf=ip6,reuseaddr,cert=$HOME/etc/server.pem,cafile=$HOME/etc/client.crt echo

Client:

socat stdio openssl-connect:ip6name.domain.org:4433,cert=$HOME/etc/client.pem,cafile=$HOME/etc/server.crt

Troubleshooting

Test OpenSSL Integration

If you get error messages like this:

... E unknown device/address "openssl-listen"

your socat executable probably does not have the OpenSSL library linked in. Check socat's compile time configuration with the following command:

socat -V |grep SSL

Positive output: #define WITH_OPENSSL 1
Negative output: #undef WITH_OPENSSL

In the latter case, make sure you have OpenSSL and its development package (include files) installed, and check the run of the configure script.

History

A first OpenSSL client was implemented in socat 1.2.0; it did not support client certificates and could not verify server certificates. It was rather considered as a tool for probing typical SSL secured Internet services.

From version 1.4.0 on, socat provided experimental support for SSL client and SSL server, implemented using the OpenSSL libraries. Only TCP/IPv4 transport was supported. With both SSL client and server, trust certificates for checking the peers authentication, and certificates for authentication could be specified. This allowed for non interactive secure connection establishing. The features were considered experimental; like most Internet sites, socat server did not require the client to present a certificate per default, but the client required a server certificate.

DSA certificate support is implemented since version 1.4.2.

Socat version 1.5.0 extended SSL to TCP/IPv6 transports.

With socat version 1.6.0, the SSL server per default requires the client to present a trusted certificate. socat's OpenSSL implementation still does not check the contents of a certificate like host name or host address.

This document was last modified in March 2007.

More info about socat OpenSSL

Links regarding this tutorial

address openssl-connect
address openssl-listen
option cert
option cafile

More socat options for OpenSSL addresses

OpenSSL options
TCP options
IP options
socket options
file descriptor options
retry options

For openssl-listen only:

listen options
child options
range options

References

socat home page
socat man page
OpenSSL home page
stunnel home page
secure sockets layer on Wikipedia

Copyright: Gerhard Rieger 2007
License: GNU Free Documentation License (FDL)

socat-1.7.3.1/doc/socat.html0000644000201000020100000067026312460744310015343 0ustar gerhardgerhard socat

socat

CONTENTS

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
ADDRESS SPECIFICATIONS
ADDRESS TYPES
ADDRESS OPTIONS
DATA VALUES
EXAMPLES
DIAGNOSTICS
FILES
ENVIRONMENT VARIABLES
CREDITS
VERSION
BUGS
SEE ALSO

NAME

socat - Multipurpose relay (SOcket CAT)

SYNOPSIS

socat [options] <address> <address>
socat -V
socat -h[h[h]] | -?[?[?]]
filan
procan

DESCRIPTION

Socat is a command line based utility that establishes two bidirectional byte streams and transfers data between them. Because the streams can be constructed from a large set of different types of data sinks and sources (see address types), and because lots of address options may be applied to the streams, socat can be used for many different purposes.

Filan is a utility that prints information about its active file descriptors to stdout. It has been written for debugging socat, but might be useful for other purposes too. Use the -h option to find more infos.

Procan is a utility that prints information about process parameters to stdout. It has been written to better understand some UNIX process properties and for debugging socat, but might be useful for other purposes too.

The life cycle of a socat instance typically consists of four phases.

In the init phase, the command line options are parsed and logging is initialized.

During the open phase, socat opens the first address and afterwards the second address. These steps are usually blocking; thus, especially for complex address types like socks, connection requests or authentication dialogs must be completed before the next step is started.

In the transfer phase, socat watches both streams' read and write file descriptors via select() , and, when data is available on one side and can be written to the other side, socat reads it, performs newline character conversions if required, and writes the data to the write file descriptor of the other stream, then continues waiting for more data in both directions.

When one of the streams effectively reaches EOF, the closing phase begins. Socat transfers the EOF condition to the other stream, i.e. tries to shutdown only its write stream, giving it a chance to terminate gracefully. For a defined time socat continues to transfer data in the other direction, but then closes all remaining channels and terminates.

OPTIONS

Socat provides some command line options that modify the behaviour of the program. They have nothing to do with so called address options that are used as parts of address specifications.

-V
Print version and available feature information to stdout, and exit.

-h | -?
Print a help text to stdout describing command line options and available address types, and exit.

-hh | -??
Like -h, plus a list of the short names of all available address options. Some options are platform dependend, so this output is helpful for checking the particular implementation.

-hhh | -???
Like -hh, plus a list of all available address option names.

-d
Without this option, only fatal and error messages are generated; applying this option also prints warning messages. See DIAGNOSTICS for more information.

-d -d
Prints fatal, error, warning, and notice messages.

-d -d -d
Prints fatal, error, warning, notice, and info messages.

-d -d -d -d
Prints fatal, error, warning, notice, info, and debug messages.

-D
Logs information about file descriptors before starting the transfer phase.

-ly[<facility>]
Writes messages to syslog instead of stderr; severity as defined with -d option. With optional <facility>, the syslog type can be selected, default is "daemon". Third party libraries might not obey this option.

-lf <logfile>
Writes messages to <logfile> [filename] instead of stderr. Some third party libraries, in particular libwrap, might not obey this option.

-ls
Writes messages to stderr (this is the default). Some third party libraries might not obey this option, in particular libwrap appears to only log to syslog.

-lp<progname>
Overrides the program name printed in error messages and used for constructing environment variable names.

-lu
Extends the timestamp of error messages to microsecond resolution. Does not work when logging to syslog.

-lm[<facility>]
Mixed log mode. During startup messages are printed to stderr; when socat starts the transfer phase loop or daemon mode (i.e. after opening all streams and before starting data transfer, or, with listening sockets with fork option, before the first accept call), it switches logging to syslog. With optional <facility>, the syslog type can be selected, default is "daemon".

-lh
Adds hostname to log messages. Uses the value from environment variable HOSTNAME or the value retrieved with uname() if HOSTNAME is not set.

-v
Writes the transferred data not only to their target streams, but also to stderr. The output format is text with some conversions for readability, and prefixed with "> " or "< " indicating flow directions.

-x
Writes the transferred data not only to their target streams, but also to stderr. The output format is hexadecimal, prefixed with "> " or "< " indicating flow directions. Can be combined with -v .

-b<size>
Sets the data transfer block <size> [size_t]. At most <size> bytes are transferred per step. Default is 8192 bytes.

-s
By default, socat terminates when an error occurred to prevent the process from running when some option could not be applied. With this option, socat is sloppy with errors and tries to continue. Even with this option, socat will exit on fatals, and will abort connection attempts when security checks failed.

-t<timeout>
When one channel has reached EOF, the write part of the other channel is shut down. Then, socat waits <timeout> [timeval] seconds before terminating. Default is 0.5 seconds. This timeout only applies to addresses where write and read part can be closed independently. When during the timeout interval the read part gives EOF, socat terminates without awaiting the timeout.

-T<timeout>
Total inactivity timeout: when socat is already in the transfer loop and nothing has happened for <timeout> [timeval] seconds (no data arrived, no interrupt occurred...) then it terminates. Useful with protocols like UDP that cannot transfer EOF.

-u
Uses unidirectional mode. The first address is only used for reading, and the second address is only used for writing (example).

-U
Uses unidirectional mode in reverse direction. The first address is only used for writing, and the second address is only used for reading.

-g
During address option parsing, don't check if the option is considered useful in the given address environment. Use it if you want to force, e.g., appliance of a socket option to a serial device.

-L<lockfile>
If lockfile exists, exits with error. If lockfile does not exist, creates it and continues, unlinks lockfile on exit.

-W<lockfile>
If lockfile exists, waits until it disappears. When lockfile does not exist, creates it and continues, unlinks lockfile on exit.

-4
Use IP version 4 in case that the addresses do not implicitly or explicitly specify a version; this is the default.

-6
Use IP version 6 in case that the addresses do not implicitly or explicitly specify a version.

ADDRESS SPECIFICATIONS

With the address command line arguments, the user gives socat instructions and the necessary information for establishing the byte streams.

An address specification usually consists of an address type keyword, zero or more required address parameters separated by ':' from the keyword and from each other, and zero or more address options separated by ','.

The keyword specifies the address type (e.g., TCP4, OPEN, EXEC). For some keywords there exist synonyms ('-' for STDIO, TCP for TCP4). Keywords are case insensitive. For a few special address types, the keyword may be omitted: Address specifications starting with a number are assumed to be FD (raw file descriptor) addresses; if a '/' is found before the first ':' or ',', GOPEN (generic file open) is assumed.

The required number and type of address parameters depend on the address type. E.g., TCP4 requires a server specification (name or address), and a port specification (number or service name).

Zero or more address options may be given with each address. They influence the address in some ways. Options consist of an option keyword or an option keyword and a value, separated by '='. Option keywords are case insensitive. For filtering the options that are useful with an address type, each option is member of one option group. For each address type there is a set of option groups allowed. Only options belonging to one of these address groups may be used (except with option -g).

Address specifications following the above schema are also called single address specifications. Two single addresses can be combined with "!!" to form a dual type address for one channel. Here, the first address is used by socat for reading data, and the second address for writing data. There is no way to specify an option only once for being applied to both single addresses.

Usually, addresses are opened in read/write mode. When an address is part of a dual address specification, or when option -u or -U is used, an address might be used only for reading or for writing. Considering this is important with some address types.

With socat version 1.5.0 and higher, the lexical analysis tries to handle quotes and parenthesis meaningfully and allows escaping of special characters. If one of the characters ( { [ ' is found, the corresponding closing character - ) } ] ' - is looked for; they may also be nested. Within these constructs, socats special characters and strings : , !! are not handled specially. All those characters and strings can be escaped with \ or within ""

ADDRESS TYPES

This section describes the available address types with their keywords, parameters, and semantics.

CREATE:<filename>
Opens <filename> with creat() and uses the file descriptor for writing. This address type requires write-only context, because a file opened with creat cannot be read from.
Flags like O_LARGEFILE cannot be applied. If you need them use OPEN with options create,create.
<filename> must be a valid existing or not existing path. If <filename> is a named pipe, creat() might block; if <filename> refers to a socket, this is an error.
Option groups: FD,REG,NAMED
Useful options: mode, user, group, unlink-early, unlink-late, append
See also: OPEN, GOPEN

EXEC:<command-line>
Forks a sub process that establishes communication with its parent process and invokes the specified program with execvp() . <command-line> is a simple command with arguments separated by single spaces. If the program name contains a '/', the part after the last '/' is taken as ARGV[0]. If the program name is a relative path, the execvp() semantics for finding the program via $PATH apply. After successful program start, socat writes data to stdin of the process and reads from its stdout using a UNIX domain socket generated by socketpair() per default. (example)
Option groups: FD,SOCKET,EXEC,FORK,TERMIOS
Useful options: path, fdin, fdout, chroot, su, su-d, nofork, pty, stderr, ctty, setsid, pipes, login, sigint, sigquit
See also: SYSTEM

FD:<fdnum>
Uses the file descriptor <fdnum>. It must already exist as valid UN*X file descriptor.
Option groups: FD (TERMIOS,REG,SOCKET)
See also: STDIO, STDIN, STDOUT, STDERR

GOPEN:<filename>
(Generic open) This address type tries to handle any file system entry except directories usefully. <filename> may be a relative or absolute path. If it already exists, its type is checked. In case of a UNIX domain socket, socat connects; if connecting fails, socat assumes a datagram socket and uses sendto() calls. If the entry is not a socket, socat opens it applying the O_APPEND flag. If it does not exist, it is opened with flag O_CREAT as a regular file (example).
Option groups: FD,REG,SOCKET,NAMED,OPEN
See also: OPEN, CREATE, UNIX-CONNECT

IP-SENDTO:<host>:<protocol>
Opens a raw IP socket. Depending on host specification or option pf, IP protocol version 4 or 6 is used. It uses <protocol> to send packets to <host> [IP address] and receives packets from host, ignores packets from other hosts. Protocol 255 uses the raw socket with the IP header being part of the data.
Option groups: FD,SOCKET,IP4,IP6
Useful options: pf, ttl
See also: IP4-SENDTO, IP6-SENDTO, IP-RECVFROM, IP-RECV, UDP-SENDTO, UNIX-SENDTO

INTERFACE:<interface>
Communicates with a network connected on an interface using raw packets including link level data. <interface> is the name of the network interface. Currently only available on Linux. Option groups: FD,SOCKET
Useful options: pf, type
See also: ip-recv

IP4-SENDTO:<host>:<protocol>
Like IP-SENDTO, but always uses IPv4.
Option groups: FD,SOCKET,IP4

IP6-SENDTO:<host>:<protocol>
Like IP-SENDTO, but always uses IPv6.
Option groups: FD,SOCKET,IP6

IP-DATAGRAM:<address>:<protocol>
Sends outgoing data to the specified address which may in particular be a broadcast or multicast address. Packets arriving on the local socket are checked if their source addresses match RANGE or TCPWRAP options. This address type can for example be used for implementing symmetric or asymmetric broadcast or multicast communications.
Option groups: FD, SOCKET, IP4, IP6, RANGE
Useful options: bind, range, tcpwrap, broadcast, ip-multicast-loop, ip-multicast-ttl, ip-multicast-if, ip-add-membership, ttl, tos, pf
See also: IP4-DATAGRAM, IP6-DATAGRAM, IP-SENDTO, IP-RECVFROM, IP-RECV, UDP-DATAGRAM

IP4-DATAGRAM:<host>:<protocol>
Like IP-DATAGRAM, but always uses IPv4. (example)
Option groups: FD,SOCKET,IP4,RANGE

IP6-DATAGRAM:<host>:<protocol>
Like IP-DATAGRAM, but always uses IPv6. Please note that IPv6 does not know broadcasts.
Option groups: FD,SOCKET,IP6,RANGE

IP-RECVFROM:<protocol>
Opens a raw IP socket of <protocol>. Depending on option pf, IP protocol version 4 or 6 is used. It receives one packet from an unspecified peer and may send one or more answer packets to that peer. This mode is particularly useful with fork option where each arriving packet - from arbitrary peers - is handled by its own sub process. This allows a behaviour similar to typical UDP based servers like ntpd or named.
Please note that the reply packets might be fetched as incoming traffic when sender and receiver IP address are identical because there is no port number to distinguish the sockets.
This address works well with IP-SENDTO address peers (see above). Protocol 255 uses the raw socket with the IP header being part of the data.
Option groups: FD,SOCKET,IP4,IP6,CHILD,RANGE
Useful options: pf, fork, range, ttl, broadcast
See also: IP4-RECVFROM, IP6-RECVFROM, IP-SENDTO, IP-RECV, UDP-RECVFROM, UNIX-RECVFROM

IP4-RECVFROM:<protocol>
Like IP-RECVFROM, but always uses IPv4.
Option groups: FD,SOCKET,IP4,CHILD,RANGE

IP6-RECVFROM:<protocol>
Like IP-RECVFROM, but always uses IPv6.
Option groups: FD,SOCKET,IP6,CHILD,RANGE

IP-RECV:<protocol>
Opens a raw IP socket of <protocol>. Depending on option pf, IP protocol version 4 or 6 is used. It receives packets from multiple unspecified peers and merges the data. No replies are possible. It can be, e.g., addressed by socat IP-SENDTO address peers. Protocol 255 uses the raw socket with the IP header being part of the data.
Option groups: FD,SOCKET,IP4,IP6,RANGE
Useful options: pf, range
See also: IP4-RECV, IP6-RECV, IP-SENDTO, IP-RECVFROM, UDP-RECV, UNIX-RECV

IP4-RECV:<protocol>
Like IP-RECV, but always uses IPv4.
Option groups: FD,SOCKET,IP4,RANGE

IP6-RECV:<protocol>
Like IP-RECV, but always uses IPv6.
Option groups: FD,SOCKET,IP6,RANGE

OPEN:<filename>
Opens <filename> using the open() system call (example). This operation fails on UNIX domain sockets.
Note: This address type is rarly useful in bidirectional mode.
Option groups: FD,REG,NAMED,OPEN
Useful options: creat, excl, noatime, nofollow, append, rdonly, wronly, lock, readbytes, ignoreeof
See also: CREATE, GOPEN, UNIX-CONNECT

OPENSSL:<host>:<port>
Tries to establish a SSL connection to <port> [TCP service] on <host> [IP address] using TCP/IP version 4 or 6 depending on address specification, name resolution, or option pf.
NOTE: Up to version 1.7.2.4 the server certificate was only checked for validity against the system certificate store or cafile or capath, but not for match with the server's name or its IP address. Since version 1.7.3.0 socat checks the peer certificate for match with the <host> parameter or the value of the openssl-commonname option. Socat tries to match it against the certificates subject commonName, and the certifications extension subjectAltName DNS names. Wildcards in the certificate are supported.
Option groups: FD,SOCKET,IP4,IP6,TCP,OPENSSL,RETRY
Useful options: cipher, method, verify, commonname cafile, capath, certificate, key, compress, bind, pf, connect-timeout, sourceport, retry
See also: OPENSSL-LISTEN, TCP

OPENSSL-LISTEN:<port>
Listens on tcp <port> [TCP service]. The IP version is 4 or the one specified with pf. When a connection is accepted, this address behaves as SSL server.
Note: You probably want to use the certificate option with this address.
NOTE: The client certificate is only checked for validity against cafile or capath, but not for match with the client's name or its IP address!
Option groups: FD,SOCKET,IP4,IP6,TCP,LISTEN,OPENSSL,CHILD,RANGE,RETRY
Useful options: pf, cipher, method, verify, commonname cafile, capath, certificate, key, compress, fork, bind, range, tcpwrap, su, reuseaddr, retry
See also: OPENSSL, TCP-LISTEN

PIPE:<filename>
If <filename> already exists, it is opened. If it does not exist, a named pipe is created and opened. Beginning with socat version 1.4.3, the named pipe is removed when the address is closed (but see option unlink-close
Note: When a pipe is used for both reading and writing, it works as echo service.
Note: When a pipe is used for both reading and writing, and socat tries to write more bytes than the pipe can buffer (Linux 2.4: 2048 bytes), socat might block. Consider using socat option, e.g., -b 2048
Option groups: FD,NAMED,OPEN
Useful options: rdonly, nonblock, group, user, mode, unlink-early
See also: unnamed pipe

PIPE
Creates an unnamed pipe and uses it for reading and writing. It works as an echo, because everything written to it appeares immediately as read data.
Note: When socat tries to write more bytes than the pipe can queue (Linux 2.4: 2048 bytes), socat might block. Consider, e.g., using option -b 2048
Option groups: FD
See also: named pipe

PROXY:<proxy>:<hostname>:<port>
Connects to an HTTP proxy server on port 8080 using TCP/IP version 4 or 6 depending on address specification, name resolution, or option pf, and sends a CONNECT request for hostname:port. If the proxy grants access and succeeds to connect to the target, data transfer between socat and the target can start. Note that the traffic need not be HTTP but can be an arbitrary protocol.
Option groups: FD,SOCKET,IP4,IP6,TCP,HTTP,RETRY
Useful options: proxyport, ignorecr, proxyauth, resolve, crnl, bind, connect-timeout, mss, sourceport, retry
See also: SOCKS, TCP

PTY
Generates a pseudo terminal (pty) and uses its master side. Another process may open the pty's slave side using it like a serial line or terminal. (example). If both the ptmx and the openpty mechanisms are available, ptmx is used (POSIX).
Option groups: FD,NAMED,PTY,TERMIOS
Useful options: link, openpty, wait-slave, mode, user, group
See also: UNIX-LISTEN, PIPE, EXEC, SYSTEM

READLINE
Uses GNU readline and history on stdio to allow editing and reusing input lines (example). This requires the GNU readline and history libraries. Note that stdio should be a (pseudo) terminal device, otherwise readline does not seem to work.
Option groups: FD,READLINE,TERMIOS
Useful options: history, noecho
See also: STDIO

SCTP-CONNECT:<host>:<port>
Establishes an SCTP stream connection to the specified <host> [IP address] and <port> [TCP service] using TCP/IP version 4 or 6 depending on address specification, name resolution, or option pf.
Option groups: FD,SOCKET,IP4,IP6,SCTP,CHILD,RETRY
Useful options: bind, pf, connect-timeout, tos, mtudiscover, sctp-maxseg, sctp-nodelay, nonblock, sourceport, retry, readbytes
See also: SCTP4-CONNECT, SCTP6-CONNECT, SCTP-LISTEN, TCP-CONNECT

SCTP4-CONNECT:<host>:<port>
Like SCTP-CONNECT, but only supports IPv4 protocol.
Option groups: FD,SOCKET,IP4,SCTP,CHILD,RETRY

SCTP6-CONNECT:<host>:<port>
Like SCTP-CONNECT, but only supports IPv6 protocol.
Option groups: FD,SOCKET,IP6,SCTP,CHILD,RETRY

SCTP-LISTEN:<port>
Listens on <port> [TCP service] and accepts a TCP/IP connection. The IP version is 4 or the one specified with address option pf, socat option (-4, -6), or environment variable SOCAT_DEFAULT_LISTEN_IP. Note that opening this address usually blocks until a client connects.
Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP4,IP6,SCTP,RETRY
Useful options: crnl, fork, bind, range, tcpwrap, pf, max-children, backlog, sctp-maxseg, sctp-nodelay, su, reuseaddr, retry, cool-write
See also: SCTP4-LISTEN, SCTP6-LISTEN, TCP-LISTEN, SCTP-CONNECT

SCTP4-LISTEN:<port>
Like SCTP-LISTEN, but only supports IPv4 protocol.
Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP4,SCTP,RETRY

SCTP6-LISTEN:<port>
Like SCTP-LISTEN, but only supports IPv6 protocol.
Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP6,SCTP,RETRY

SOCKET-CONNECT:<domain>:<protocol>:<remote-address>
Creates a stream socket using the first and second given socket parameters and SOCK_STREAM (see man socket\(2)) and connects to the remote-address. The two socket parameters have to be specified by int numbers. Consult your OS documentation and include files to find the appropriate values. The remote-address must be the data representation of a sockaddr structure without sa_family and (BSD) sa_len components.
Please note that you can - beyond the options of the specified groups - also use options of higher level protocols when you apply socat option -g.
Option groups: FD,SOCKET,CHILD,RETRY
Useful options: bind, setsockopt-int, setsockopt-bin, setsockopt-string
See also: TCP, UDP-CONNECT, UNIX-CONNECT, SOCKET-LISTEN, SOCKET-SENDTO

SOCKET-DATAGRAM:<domain>:<type>:<protocol>:<remote-address>
Creates a datagram socket using the first three given socket parameters (see man socket\(2)) and sends outgoing data to the remote-address. The three socket parameters have to be specified by int numbers. Consult your OS documentation and include files to find the appropriate values. The remote-address must be the data representation of a sockaddr structure without sa_family and (BSD) sa_len components.
Please note that you can - beyond the options of the specified groups - also use options of higher level protocols when you apply socat option -g.
Option groups: FD,SOCKET,RANGE
Useful options: bind, range, setsockopt-int, setsockopt-bin, setsockopt-string
See also: UDP-DATAGRAM, IP-DATAGRAM, SOCKET-SENDTO, SOCKET-RECV, SOCKET-RECVFROM

SOCKET-LISTEN:<domain>:<protocol>:<local-address>
Creates a stream socket using the first and second given socket parameters and SOCK_STREAM (see man socket\(2)) and waits for incoming connections on local-address. The two socket parameters have to be specified by int numbers. Consult your OS documentation and include files to find the appropriate values. The local-address must be the data representation of a sockaddr structure without sa_family and (BSD) sa_len components.
Please note that you can - beyond the options of the specified groups - also use options of higher level protocols when you apply socat option -g.
Option groups: FD,SOCKET,LISTEN,RANGE,CHILD,RETRY
Useful options: setsockopt-int, setsockopt-bin, setsockopt-string
See also: TCP, UDP-CONNECT, UNIX-CONNECT, SOCKET-LISTEN, SOCKET-SENDTO, SOCKET-SENDTO

SOCKET-RECV:<domain>:<type>:<protocol>:<local-address>
Creates a socket using the three given socket parameters (see man socket\(2)) and binds it to <local-address>. Receives arriving data. The three parameters have to be specified by int numbers. Consult your OS documentation and include files to find the appropriate values. The local-address must be the data representation of a sockaddr structure without sa_family and (BSD) sa_len components.
Option groups: FD,SOCKET,RANGE
Useful options: range, setsockopt-int, setsockopt-bin, setsockopt-string
See also: UDP-RECV, IP-RECV, UNIX-RECV, SOCKET-DATAGRAM, SOCKET-SENDTO, SOCKET-RECVFROM

SOCKET-RECVFROM:<domain>:<type>:<protocol>:<local-address>
Creates a socket using the three given socket parameters (see man socket\(2)) and binds it to <local-address>. Receives arriving data and sends replies back to the sender. The first three parameters have to be specified as int numbers. Consult your OS documentation and include files to find the appropriate values. The local-address must be the data representation of a sockaddr structure without sa_family and (BSD) sa_len components.
Option groups: FD,SOCKET,CHILD,RANGE
Useful options: fork, range, setsockopt-int, setsockopt-bin, setsockopt-string
See also: UDP-RECVFROM, IP-RECVFROM, UNIX-RECVFROM, SOCKET-DATAGRAM, SOCKET-SENDTO, SOCKET-RECV

SOCKET-SENDTO:<domain>:<type>:<protocol>:<remote-address>
Creates a socket using the three given socket parameters (see man socket\(2)). Sends outgoing data to the given address and receives replies. The three parameters have to be specified as int numbers. Consult your OS documentation and include files to find the appropriate values. The remote-address must be the data representation of a sockaddr structure without sa_family and (BSD) sa_len components.
Option groups: FD,SOCKET
Useful options: bind, setsockopt-int, setsockopt-bin, setsockopt-string
See also: UDP-SENDTO, IP-SENDTO, UNIX-SENDTO, SOCKET-DATAGRAM, SOCKET-RECV SOCKET-RECVFROM

SOCKS4:<socks-server>:<host>:<port>
Connects via <socks-server> [IP address] to <host> [IPv4 address] on <port> [TCP service], using socks version 4 protocol over IP version 4 or 6 depending on address specification, name resolution, or option pf (example).
Option groups: FD,SOCKET,IP4,IP6,TCP,SOCKS4,RETRY
Useful options: socksuser, socksport, sourceport, pf, retry
See also: SOCKS4A, PROXY, TCP

SOCKS4A:<socks-server>:<host>:<port>
like SOCKS4, but uses socks protocol version 4a, thus leaving host name resolution to the socks server.
Option groups: FD,SOCKET,IP4,IP6,TCP,SOCKS4,RETRY

STDERR
Uses file descriptor 2.
Option groups: FD (TERMIOS,REG,SOCKET)
See also: FD

STDIN
Uses file descriptor 0.
Option groups: FD (TERMIOS,REG,SOCKET)
Useful options: readbytes
See also: FD

STDIO
Uses file descriptor 0 for reading, and 1 for writing.
Option groups: FD (TERMIOS,REG,SOCKET)
Useful options: readbytes
See also: FD

STDOUT
Uses file descriptor 1.
Option groups: FD (TERMIOS,REG,SOCKET)
See also: FD

SYSTEM:<shell-command>
Forks a sub process that establishes communication with its parent process and invokes the specified program with system() . Please note that <shell-command> [string] must not contain ',' or "!!", and that shell meta characters may have to be protected. After successful program start, socat writes data to stdin of the process and reads from its stdout.
Option groups: FD,SOCKET,EXEC,FORK,TERMIOS
Useful options: path, fdin, fdout, chroot, su, su-d, nofork, pty, stderr, ctty, setsid, pipes, sigint, sigquit
See also: EXEC

TCP:<host>:<port>
Connects to <port> [TCP service] on <host> [IP address] using TCP/IP version 4 or 6 depending on address specification, name resolution, or option pf.
Option groups: FD,SOCKET,IP4,IP6,TCP,RETRY
Useful options: crnl, bind, pf, connect-timeout, tos, mtudiscover, mss, nodelay, nonblock, sourceport, retry, readbytes
See also: TCP4, TCP6, TCP-LISTEN, UDP, SCTP-CONNECT, UNIX-CONNECT

TCP4:<host>:<port>
Like TCP, but only supports IPv4 protocol (example).
Option groups: FD,SOCKET,IP4,TCP,RETRY

TCP6:<host>:<port>
Like TCP, but only supports IPv6 protocol.
Option groups: FD,SOCKET,IP6,TCP,RETRY

TCP-LISTEN:<port>
Listens on <port> [TCP service] and accepts a TCP/IP connection. The IP version is 4 or the one specified with address option pf, socat option (-4, -6), or environment variable SOCAT_DEFAULT_LISTEN_IP. Note that opening this address usually blocks until a client connects.
Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP4,IP6,TCP,RETRY
Useful options: crnl, fork, bind, range, tcpwrap, pf, max-children, backlog, mss, su, reuseaddr, retry, cool-write
See also: TCP4-LISTEN, TCP6-LISTEN, UDP-LISTEN, SCTP-LISTEN, UNIX-LISTEN, OPENSSL-LISTEN, TCP-CONNECT

TCP4-LISTEN:<port>
Like TCP-LISTEN, but only supports IPv4 protocol (example).
Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP4,TCP,RETRY

TCP6-LISTEN:<port>
Like TCP-LISTEN, but only supports IPv6 protocol.
Additional useful option: ipv6only
Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP6,TCP,RETRY

TUN[:<if-addr>/<bits>]
Creates a Linux TUN/TAP device and optionally assignes it the address and netmask given by the parameters. The resulting network interface is almost ready for use by other processes; socat serves its "wire side". This address requires read and write access to the tunnel cloning device, usually /dev/net/tun , as well as permission to set some ioctl()s. Option iff-up is required to immediately activate the interface!
Option groups: FD,NAMED,OPEN,TUN
Useful options: iff-up, tun-device, tun-name, tun-type, iff-no-pi
See also: ip-recv

UDP:<host>:<port>
Connects to <port> [UDP service] on <host> [IP address] using UDP/IP version 4 or 6 depending on address specification, name resolution, or option pf.
Please note that, due to UDP protocol properties, no real connection is established; data has to be sent for `connecting' to the server, and no end-of-file condition can be transported.
Option groups: FD,SOCKET,IP4,IP6
Useful options: ttl, tos, bind, sourceport, pf
See also: UDP4, UDP6, UDP-LISTEN, TCP, IP

UDP4:<host>:<port>
Like UDP, but only supports IPv4 protocol.
Option groups: FD,SOCKET,IP4

UDP6:<host>:<port>
Like UDP, but only supports IPv6 protocol.
Option groups: FD,SOCKET,IP6

UDP-DATAGRAM:<address>:<port>
Sends outgoing data to the specified address which may in particular be a broadcast or multicast address. Packets arriving on the local socket are checked for the correct remote port and if their source addresses match RANGE or TCPWRAP options. This address type can for example be used for implementing symmetric or asymmetric broadcast or multicast communications.
Option groups: FD,SOCKET,IP4,IP6,RANGE
Useful options: bind, range, tcpwrap, broadcast, ip-multicast-loop, ip-multicast-ttl, ip-multicast-if, ip-add-membership, ttl, tos, sourceport, pf
See also: UDP4-DATAGRAM, UDP6-DATAGRAM, UDP-SENDTO, UDP-RECVFROM, UDP-RECV, UDP-CONNECT, UDP-LISTEN, IP-DATAGRAM

UDP4-DATAGRAM:<address>:<port>
Like UDP-DATAGRAM, but only supports IPv4 protocol (example1, example2).
Option groups: FD,SOCKET,IP4, RANGE

UDP6-DATAGRAM:<address>:<port>
Like UDP-DATAGRAM, but only supports IPv6 protocol.
Option groups: FD,SOCKET,IP6,RANGE

UDP-LISTEN:<port>
Waits for a UDP/IP packet arriving on <port> [UDP service] and `connects' back to sender. The accepted IP version is 4 or the one specified with option pf. Please note that, due to UDP protocol properties, no real connection is established; data has to arrive from the peer first, and no end-of-file condition can be transported. Note that opening this address usually blocks until a client connects.
Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP4,IP6
Useful options: fork, bind, range, pf
See also: UDP, UDP4-LISTEN, UDP6-LISTEN, TCP-LISTEN

UDP4-LISTEN:<port>
Like UDP-LISTEN, but only support IPv4 protocol.
Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP4

UDP6-LISTEN:<port>
Like UDP-LISTEN, but only support IPv6 protocol.
Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP6

UDP-SENDTO:<host>:<port>
Communicates with the specified peer socket, defined by <port> [UDP service] on <host> [IP address], using UDP/IP version 4 or 6 depending on address specification, name resolution, or option pf. It sends packets to and receives packets from that peer socket only. This address effectively implements a datagram client. It works well with socat UDP-RECVFROM and UDP-RECV address peers.
Option groups: FD,SOCKET,IP4,IP6
Useful options: ttl, tos, bind, sourceport, pf
See also: UDP4-SENDTO, UDP6-SENDTO, UDP-RECVFROM, UDP-RECV, UDP-CONNECT, UDP-LISTEN, IP-SENDTO

UDP4-SENDTO:<host>:<port>
Like UDP-SENDTO, but only supports IPv4 protocol.
Option groups: FD,SOCKET,IP4

UDP6-SENDTO:<host>:<port>
Like UDP-SENDTO, but only supports IPv6 protocol.
Option groups: FD,SOCKET,IP6

UDP-RECVFROM:<port>
Creates a UDP socket on <port> [UDP service] using UDP/IP version 4 or 6 depending on option pf. It receives one packet from an unspecified peer and may send one or more answer packets to that peer. This mode is particularly useful with fork option where each arriving packet - from arbitrary peers - is handled by its own sub process. This allows a behaviour similar to typical UDP based servers like ntpd or named. This address works well with socat UDP-SENDTO address peers.
Option groups: FD,SOCKET,IP4,IP6,CHILD,RANGE
Useful options: fork, ttl, tos, bind, sourceport, pf
See also: UDP4-RECVFROM, UDP6-RECVFROM, UDP-SENDTO, UDP-RECV, UDP-CONNECT, UDP-LISTEN, IP-RECVFROM, UNIX-RECVFROM

UDP4-RECVFROM:<port>
Like UDP-RECVFROM, but only supports IPv4 protocol.
Option groups: FD,SOCKET,IP4,CHILD,RANGE

UDP6-RECVFROM:<port>
Like UDP-RECVFROM, but only supports IPv6 protocol.
Option groups: FD,SOCKET,IP6,CHILD,RANGE

UDP-RECV:<port>
Creates a UDP socket on <port> [UDP service] using UDP/IP version 4 or 6 depending on option pf. It receives packets from multiple unspecified peers and merges the data. No replies are possible. It works well with, e.g., socat UDP-SENDTO address peers; it behaves similar to a syslog server.
Option groups: FD,SOCKET,IP4,IP6,RANGE
Useful options: fork, pf, bind, sourceport, ttl, tos
See also: UDP4-RECV, UDP6-RECV, UDP-SENDTO, UDP-RECVFROM, UDP-CONNECT, UDP-LISTEN, IP-RECV, UNIX-RECV

UDP4-RECV:<port>
Like UDP-RECV, but only supports IPv4 protocol.
Option groups: FD,SOCKET,IP4,RANGE

UDP6-RECV:<port>
Like UDP-RECV, but only supports IPv6 protocol.
Option groups: FD,SOCKET,IP6,RANGE

UNIX-CONNECT:<filename>
Connects to <filename> assuming it is a UNIX domain socket. If <filename> does not exist, this is an error; if <filename> is not a UNIX domain socket, this is an error; if <filename> is a UNIX domain socket, but no process is listening, this is an error.
Option groups: FD,SOCKET,NAMED,RETRY,UNIX
) Useful options: bind
See also: UNIX-LISTEN, UNIX-SENDTO, TCP

UNIX-LISTEN:<filename>
Listens on <filename> using a UNIX domain stream socket and accepts a connection. If <filename> exists and is not a socket, this is an error. If <filename> exists and is a UNIX domain socket, binding to the address fails (use option unlink-early!). Note that opening this address usually blocks until a client connects. Beginning with socat version 1.4.3, the file system entry is removed when this address is closed (but see option unlink-close) (example).
Option groups: FD,SOCKET,NAMED,LISTEN,CHILD,RETRY,UNIX
Useful options: fork, umask, mode, user, group, unlink-early
See also: UNIX-CONNECT, UNIX-RECVFROM, UNIX-RECV, TCP-LISTEN

UNIX-SENDTO:<filename>
Communicates with the specified peer socket, defined by [<filename>] assuming it is a UNIX domain datagram socket. It sends packets to and receives packets from that peer socket only. Please note that it might be neccessary to bind the local socket to an address (e.g. /tmp/sock1, which must not exist before). This address type works well with socat UNIX-RECVFROM and UNIX-RECV address peers.
Option groups: FD,SOCKET,NAMED,UNIX
Useful options: bind
See also: UNIX-RECVFROM, UNIX-RECV, UNIX-CONNECT, UDP-SENDTO, IP-SENDTO

UNIX-RECVFROM:<filename>
Creates a UNIX domain datagram socket [<filename>]. Receives one packet and may send one or more answer packets to that peer. This mode is particularly useful with fork option where each arriving packet - from arbitrary peers - is handled by its own sub process. This address works well with socat UNIX-SENDTO address peers.
Option groups: FD,SOCKET,NAMED,CHILD,UNIX
Useful options: fork
See also: UNIX-SENDTO, UNIX-RECV, UNIX-LISTEN, UDP-RECVFROM, IP-RECVFROM

UNIX-RECV:<filename>
Creates a UNIX domain datagram socket [<filename>]. Receives packets from multiple unspecified peers and merges the data. No replies are possible. It can be, e.g., addressed by socat UNIX-SENDTO address peers. It behaves similar to a syslog server. Option groups: FD,SOCKET,NAMED,UNIX
See also: UNIX-SENDTO, UNIX-RECVFROM, UNIX-LISTEN, UDP-RECV, IP-RECV

UNIX-CLIENT:<filename>
Communicates with the specified peer socket, defined by [<filename>] assuming it is a UNIX domain socket. It first tries to connect and, if that fails, assumes it is a datagram socket, thus supporting both types.
Option groups: FD,SOCKET,NAMED,UNIX
Useful options: bind
See also: UNIX-CONNECT, UNIX-SENDTO, GOPEN

ABSTRACT-CONNECT:<string>

ABSTRACT-LISTEN:<string>

ABSTRACT-SENDTO:<string>

ABSTRACT-RECVFROM:<string>

ABSTRACT-RECV:<string>

ABSTRACT-CLIENT:<string>
The ABSTRACT addresses are almost identical to the related UNIX addresses except that they do not address file system based sockets but an alternate UNIX domain address space. To archieve this the socket address strings are prefixed with "\0" internally. This feature is available (only?) on Linux. Option groups are the same as with the related UNIX addresses, except that the ABSTRACT addresses are not member of the NAMED group.

ADDRESS OPTIONS

Address options can be applied to address specifications to influence the process of opening the addresses and the properties of the resulting data channels.

For technical reasons not every option can be applied to every address type; e.g., applying a socket option to a regular file will fail. To catch most useless combinations as early as in the open phase, the concept of option groups was introduced. Each option belongs to one or more option groups. Options can be used only with address types that support at least one of their option groups (but see option -g).

Address options have data types that their values must conform to. Every address option consists of just a keyword or a keyword followed by "=value", where value must conform to the options type. Some address options manipulate parameters of system calls; e.g., option sync sets the O_SYNC flag with the open() call. Other options cause a system or library call; e.g., with option `ttl=value' the setsockopt(fd, SOL_IP, IP_TTL, value, sizeof(int)) call is applied. Other options set internal socat variables that are used during data transfer; e.g., `crnl' causes explicit character conversions. A few options have more complex implementations; e.g., su-d (substuser-delayed) inquires some user and group infos, stores them, and applies them later after a possible chroot() call.

If multiple options are given to an address, their sequence in the address specification has (almost) no effect on the sequence of their execution/application. Instead, socat has built in an option phase model that tries to bring the options in a useful order. Some options exist in different forms (e.g., unlink, unlink-early, unlink-late) to control the time of their execution.

If the same option is specified more than once within one address specification, with equal or different values, the effect depends on the kind of option. Options resulting in function calls like setsockopt() cause multiple invocations. With options that set parameters for a required call like open() or set internal flags, the value of the last option occurrence is effective.

The existence or semantics of many options are system dependent. Socat usually does NOT try to emulate missing libc or kernel features, it just provides an interface to the underlying system. So, if an operating system lacks a feature, the related option is simply not available on this platform.

The following paragraphs introduce just the more common address options. For a more comprehensive reference and to find information about canonical option names, alias names, option phases, and platforms see file xio.help.


FD option group

This option group contains options that are applied to a UN*X style file descriptor, no matter how it was generated. Because all current socat address types are file descriptor based, these options may be applied to any address.
Note: Some of these options are also member of another option group, that provides an other, non-fd based mechanism. For these options, it depends on the actual address type and its option groups which mechanism is used. The second, non-fd based mechanism is prioritized.

cloexec=<bool>
Sets the FD_CLOEXEC flag with the fcntl() system call to value <bool>. If set, the file descriptor is closed on exec() family function calls. Socat internally handles this flag for the fds it controls, so in most cases there will be no need to apply this option.

setlk
Tries to set a discretionary write lock to the whole file using the fcntl(fd, F_SETLK, ...) system call. If the file is already locked, this call results in an error. On Linux, when the file permissions for group are "S" (g-x,g+s), and the file system is locally mounted with the "mand" option, the lock is mandatory, i.e. prevents other processes from opening the file.

setlkw
Tries to set a discretionary waiting write lock to the whole file using the fcntl(fd, F_SETLKW, ...) system call. If the file is already locked, this call blocks. See option setlk for information about making this lock mandatory.

setlk-rd
Tries to set a discretionary read lock to the whole file using the fcntl(fd, F_SETLK, ...) system call. If the file is already write locked, this call results in an error. See option setlk for information about making this lock mandatory.

setlkw-rd
Tries to set a discretionary waiting read lock to the whole file using the fcntl(fd, F_SETLKW, ...) system call. If the file is already write locked, this call blocks. See option setlk for information about making this lock mandatory.

flock-ex
Tries to set a blocking exclusive advisory lock to the file using the flock(fd, LOCK_EX) system call. Socat hangs in this call if the file is locked by another process.

flock-ex-nb
Tries to set a nonblocking exclusive advisory lock to the file using the flock(fd, LOCK_EX|LOCK_NB) system call. If the file is already locked, this option results in an error.

flock-sh
Tries to set a blocking shared advisory lock to the file using the flock(fd, LOCK_SH) system call. Socat hangs in this call if the file is locked by another process.

flock-sh-nb
Tries to set a nonblocking shared advisory lock to the file using the flock(fd, LOCK_SH|LOCK_NB) system call. If the file is already locked, this option results in an error.

lock
Sets a blocking lock on the file. Uses the setlk or flock mechanism depending on availability on the particular platform. If both are available, the POSIX variant (setlkw) is used.

user=<user>
Sets the <user> (owner) of the stream. If the address is member of the NAMED option group, socat uses the chown() system call after opening the file or binding to the UNIX domain socket (race condition!). Without filesystem entry, socat sets the user of the stream using the fchown() system call. These calls might require root privilege.

user-late=<user>
Sets the owner of the fd to <user> with the fchown() system call after opening or connecting the channel. This is useful only on file system entries.

group=<group>
Sets the <group> of the stream. If the address is member of the NAMED option group, socat uses the chown() system call after opening the file or binding to the UNIX domain socket (race condition!). Without filesystem entry, socat sets the group of the stream with the fchown() system call. These calls might require group membership or root privilege.

group-late=<group>
Sets the group of the fd to <group> with the fchown() system call after opening or connecting the channel. This is useful only on file system entries.

mode=<mode>
Sets the <mode> [mode_t] (permissions) of the stream. If the address is member of the NAMED option group and uses the open() or creat() call, the mode is applied with these. If the address is member of the NAMED option group without using these system calls, socat uses the chmod() system call after opening the filesystem entry or binding to the UNIX domain socket (race condition!). Otherwise, socat sets the mode of the stream using fchmod() . These calls might require ownership or root privilege.

perm-late=<mode>
Sets the permissions of the fd to value <mode> [mode_t] using the fchmod() system call after opening or connecting the channel. This is useful only on file system entries.

append=<bool>
Always writes data to the actual end of file. If the address is member of the OPEN option group, socat uses the O_APPEND flag with the open() system call (example). Otherwise, socat applies the fcntl(fd, F_SETFL, O_APPEND) call.

nonblock=<bool>
Tries to open or use file in nonblocking mode. Its only effects are that the connect() call of TCP addresses does not block, and that opening a named pipe for reading does not block. If the address is member of the OPEN option group, socat uses the O_NONBLOCK flag with the open() system call. Otherwise, socat applies the fcntl(fd, F_SETFL, O_NONBLOCK) call.

binary
Opens the file in binary mode to avoid implicit line terminator conversions (Cygwin).

text
Opens the file in text mode to force implicit line terminator conversions (Cygwin).

noinherit
Does not keep this file open in a spawned process (Cygwin).

cool-write
Takes it easy when write fails with EPIPE or ECONNRESET and logs the message with notice level instead of error. This prevents the log file from being filled with useless error messages when socat is used as a high volume server or proxy where clients often abort the connection.
This option is experimental.

end-close
Changes the (address dependent) method of ending a connection to just close the file descriptors. This is useful when the connection is to be reused by or shared with other processes (example).
Normally, socket connections will be ended with shutdown(2) which terminates the socket even if it is shared by multiple processes. close(2) "unlinks" the socket from the process but keeps it active as long as there are still links from other processes.
Similarly, when an address of type EXEC or SYSTEM is ended, socat usually will explicitely kill the sub process. With this option, it will just close the file descriptors.

shut-none
Changes the (address dependent) method of shutting down the write part of a connection to not do anything.

shut-down
Changes the (address dependent) method of shutting down the write part of a connection to shutdown\(fd, SHUT_WR). Is only useful with sockets.

shut-close
Changes the (address dependent) method of shutting down the write part of a connection to close\(fd).

shut-null
When one address indicates EOF, socat will send a zero sized packet to the write channel of the other address to transfer the EOF condition. This is useful with UDP and other datagram protocols. Has been tested against netcat and socat with option null-eof.

null-eof
Normally socat will ignore empty (zero size payload) packets arriving on datagram sockets, so it survives port scans. With this option socat interprets empty datagram packets as EOF indicator (see shut-null).

ioctl-void=<request>
Calls ioctl() with the request value as second argument and NULL as third argument. This option allows to utilize ioctls that are not explicitely implemented in socat.

ioctl-int=<request>:<value>
Calls ioctl() with the request value as second argument and the integer value as third argument.

ioctl-intp=<request>:<value>
Calls ioctl() with the request value as second argument and a pointer to the integer value as third argument.

ioctl-bin=<request>:<value>
Calls ioctl() with the request value as second argument and a pointer to the given data value as third argument. This data must be specified in <dalan> form.

ioctl-string=<request>:<value>
Calls ioctl() with the request value as second argument and a pointer to the given string as third argument. <dalan> form.


NAMED option group

These options work on file system entries.
See also options user, group, and mode.

user-early=<user>
Changes the <user> (owner) of the file system entry before accessing it, using the chown() system call. This call might require root privilege.

group-early=<group>
Changes the <group> of the file system entry before accessing it, using the chown() system call. This call might require group membership or root privilege.

perm-early=<mode>
Changes the <mode> [mode_t] of the file system entry before accessing it, using the chmod() system call. This call might require ownership or root privilege.

umask=<mode>
Sets the umask of the process to <mode> [mode_t] before accessing the file system entry (useful with UNIX domain sockets!). This call might affect all further operations of the socat process!

unlink-early
Unlinks (removes) the file before opening it and even before applying user-early etc.

unlink
Unlinks (removes) the file before accessing it, but after user-early etc.

unlink-late
Unlinks (removes) the file after opening it to make it inaccessible for other processes after a short race condition.

unlink-close
Removes the addresses file system entry when closing the address. For named pipes, listening unix domain sockets, and the symbolic links of pty addresses, the default is 1; for created files, opened files, generic opened files, and client unix domain sockets the default is 0.


OPEN option group

The OPEN group options allow to set flags with the open() system call. E.g., option `creat' sets the O_CREAT flag.
See also options append and nonblock.

creat=<bool>
Creates the file if it does not exist (example).

dsync=<bool>
Blocks write() calls until metainfo is physically written to media.

excl=<bool>
With option creat, if file exists this is an error.

largefile=<bool>
On 32 bit systems, allows a file larger than 2^31 bytes.

noatime
Sets the O_NOATIME options, so reads do not change the access timestamp.

noctty=<bool>
Does not make this file the controlling terminal.

nofollow=<bool>
Does not follow symbolic links.

nshare=<bool>
Does not allow to share this file with other processes.

rshare=<bool>
Does not allow other processes to open this file for writing.

rsync=<bool>
Blocks write() until metainfo is physically written to media.

sync=<bool>
Blocks write() until data is physically written to media.

rdonly=<bool>
Opens the file for reading only.

wronly=<bool>
Opens the file for writing only.

trunc
Truncates the file to size 0 during opening it.


REG and BLK option group

These options are usually applied to a UN*X file descriptor, but their semantics make sense only on a file supporting random access.

seek=<offset>
Applies the lseek(fd, <offset>, SEEK_SET) (or lseek64 ) system call, thus positioning the file pointer absolutely to <offset> [off_t or off64_t]. Please note that a missing value defaults to 1, not 0.

seek-cur=<offset>
Applies the lseek(fd, <offset>, SEEK_CUR) (or lseek64 ) system call, thus positioning the file pointer <offset> [off_t or off64_t] bytes relatively to its current position (which is usually 0). Please note that a missing value defaults to 1, not 0.

seek-end=<offset>
Applies the lseek(fd, <offset>, SEEK_END) (or lseek64 ) system call, thus positioning the file pointer <offset> [off_t or off64_t] bytes relatively to the files current end. Please note that a missing value defaults to 1, not 0.

ftruncate=<offset>
Applies the ftruncate(fd, <offset>) (or ftruncate64 if available) system call, thus truncating the file at the position <offset> [off_t or off64_t]. Please note that a missing value defaults to 1, not 0.

secrm=<bool>

unrm=<bool>

compr=<bool>

ext2-sync=<bool>

immutable=<bool>

ext2-append=<bool>

nodump=<bool>

ext2-noatime=<bool>

journal-data=<bool>

notail=<bool>

dirsync=<bool>
These options change non standard file attributes on operating systems and file systems that support these features, like Linux with ext2fs, ext3fs, or reiserfs. See man 1 chattr for information on these options. Please note that there might be a race condition between creating the file and applying these options.


PROCESS option group

Options of this group change the process properties instead of just affecting one data channel. For EXEC and SYSTEM addresses and for LISTEN and CONNECT type addresses with option FORK, these options apply to the child processes instead of the main socat process.

chroot=<directory>
Performs a chroot() operation to <directory> after processing the address (example). This call might require root privilege.

chroot-early=<directory>
Performs a chroot() operation to <directory> before opening the address. This call might require root privilege.

setgid=<group>
Changes the primary <group> of the process after processing the address. This call might require root privilege. Please note that this option does not drop other group related privileges.

setgid-early=<group>
Like setgit but is performed before opening the address.

setuid=<user>
Changes the <user> (owner) of the process after processing the address. This call might require root privilege. Please note that this option does not drop group related privileges. Check if option su better fits your needs.

setuid-early=<user>
Like setuid but is performed before opening the address.

su=<user>
Changes the <user> (owner) and groups of the process after processing the address (example). This call might require root privilege.

su-d=<user>
Short name for substuser-delayed. Changes the <user> (owner) and groups of the process after processing the address (example). The user and his groups are retrieved before a possible chroot() . This call might require root privilege.

setpgid=<pid_t>
Makes the process a member of the specified process group <pid_t>. If no value is given, or if the value is 0 or 1, the process becomes leader of a new process group.

setsid
Makes the process the leader of a new session (example).


READLINE option group

These options apply to the readline address type.

history=<filename>
Reads and writes history from/to <filename> (example).

noprompt
Since version 1.4.0, socat per default tries to determine a prompt - that is then passed to the readline call - by remembering the last incomplete line of the output. With this option, socat does not pass a prompt to readline, so it begins line editing in the first column of the terminal.

noecho=<pattern>
Specifies a regular pattern for a prompt that prevents the following input line from being displayed on the screen and from being added to the history. The prompt is defined as the text that was output to the readline address after the lastest newline character and before an input character was typed. The pattern is a regular expression, e.g. "^[Pp]assword:.*$" or "([Uu]ser:|[Pp]assword:)". See regex\(7) for details. (example)

prompt=<string>
Passes the string as prompt to the readline function. readline prints this prompt when stepping through the history. If this string matches a constant prompt issued by an interactive program on the other socat address, consistent look and feel can be archieved.


APPLICATION option group

This group contains options that work at data level. Note that these options only apply to the "raw" data transferred by socat, but not to protocol data used by addresses like PROXY.

cr
Converts the default line termination character NL ('\n', 0x0a) to/from CR ('\r', 0x0d) when writing/reading on this channel.

crnl
Converts the default line termination character NL ('\n', 0x0a) to/from CRNL ("\r\n", 0x0d0a) when writing/reading on this channel (example). Note: socat simply strips all CR characters.

ignoreeof
When EOF occurs on this channel, socat ignores it and tries to read more data (like "tail -f") (example).

readbytes=<bytes>
socat reads only so many bytes from this address (the address provides only so many bytes for transfer and pretends to be at EOF afterwards). Must be greater than 0.

lockfile=<filename>
If lockfile exists, exits with error. If lockfile does not exist, creates it and continues, unlinks lockfile on exit.

waitlock=<filename>
If lockfile exists, waits until it disappears. When lockfile does not exist, creates it and continues, unlinks lockfile on exit.

escape=<int>
Specifies the numeric code of a character that triggers EOF on the input stream. It is useful with a terminal in raw mode (example).


SOCKET option group

These options are intended for all kinds of sockets, e.g. IP or UNIX domain. Most are applied with a setsockopt() call.

bind=<sockname>
Binds the socket to the given socket address using the bind() system call. The form of <sockname> is socket domain dependent: IP4 and IP6 allow the form [hostname|hostaddress][:(service|port)] (example), UNIX domain sockets require <filename>.

connect-timeout=<seconds>
Abort the connection attempt after <seconds> [timeval] with error status.

so-bindtodevice=<interface>
Binds the socket to the given <interface>. This option might require root privilege.

broadcast
For datagram sockets, allows sending to broadcast addresses and receiving packets addressed to broadcast addresses.

debug
Enables socket debugging.

dontroute
Only communicates with directly connected peers, does not use routers.

keepalive
Enables sending keepalives on the socket.

linger=<seconds>
Blocks shutdown() or close() until data transfers have finished or the given timeout [int] expired.

oobinline
Places out-of-band data in the input data stream.

priority=<priority>
Sets the protocol defined <priority> [<int>] for outgoing packets.

rcvbuf=<bytes>
Sets the size of the receive buffer after the socket() call to <bytes> [int]. With TCP sockets, this value corresponds to the socket's maximal window size.

rcvbuf-late=<bytes>
Sets the size of the receive buffer when the socket is already connected to <bytes> [int]. With TCP sockets, this value corresponds to the socket's maximal window size.

rcvlowat=<bytes>
Specifies the minimum number of received bytes [int] until the socket layer will pass the buffered data to socat.

rcvtimeo=<seconds>
Sets the receive timeout [timeval].

reuseaddr
Allows other sockets to bind to an address even if parts of it (e.g. the local port) are already in use by socat (example).

sndbuf=<bytes>
Sets the size of the send buffer after the socket() call to <bytes> [int].

sndbuf-late=<bytes>
Sets the size of the send buffer when the socket is connected to <bytes> [int].

sndlowat=<bytes>
Specifies the minimum number of bytes in the send buffer until the socket layer will send the data to <bytes> [int].

sndtimeo=<seconds>
Sets the send timeout to seconds [timeval].

pf=<string>
Forces the use of the specified IP version or protocol. <string> can be something like "ip4" or "ip6". The resulting value is used as first argument to the socket() or socketpair() calls. This option affects address resolution and the required syntax of bind and range options.

type=<type>
Sets the type of the socket, specified as second argument to the socket() or socketpair() calls, to <type> [int]. Address resolution is not affected by this option. Under Linux, 1 means stream oriented socket, 2 means datagram socket, and 3 means raw socket.

prototype
Sets the protocol of the socket, specified as third argument to the socket() or socketpair() calls, to <prototype> [int]. Address resolution is not affected by this option. 6 means TCP, 17 means UDP.

so-timestamp
Sets the SO_TIMESTAMP socket option. This enables receiving and logging of timestamp ancillary messages.

setsockopt-int=<level>:<optname>:<optval>
Invokes setsockopt() for the socket with the given parameters. level [int] is used as second argument to setsockopt() and specifies the layer, e.g. SOL_TCP for TCP (6 on Linux), or SOL_SOCKET for the socket layer (1 on Linux). optname [int] is the third argument to setsockopt() and tells which socket option is to be set. For the actual numbers you might have to look up the appropriate include files of your system. The 4th setsockopt() parameter, value [int], is passed to the function per pointer, and for the length parameter sizeof\(int) is taken implicitely.

setsockopt-bin=<level>:<optname>:<optval>
Like setsockopt-int, but <optval> must be provided in dalan format and specifies an arbitrary sequence of bytes; the length parameter is automatically derived from the data.

setsockopt-string=<level>:<optname>:<optval>
Like setsockopt-int, but <optval> must be a string. This string is passed to the function with trailing null character, and the length parameter is automatically derived from the data.


UNIX option group

These options apply to UNIX domain based addresses.

unix-tightsocklen=[0|1]
On socket operations, pass a socket address length that does not include the whole struct sockaddr_un record but (besides other components) only the relevant part of the filename or abstract string. Default is 1.

IP4 and IP6 option groups

These options can be used with IPv4 and IPv6 based sockets.

tos=<tos>
Sets the TOS (type of service) field of outgoing packets to <tos> [byte] (see RFC 791).

ttl=<ttl>
Sets the TTL (time to live) field of outgoing packets to <ttl> [byte].

ip-options=<data>
Sets IP options like source routing. Must be given in binary form, recommended format is a leading "x" followed by an even number of hex digits. This option may be used multiple times, data are appended. E.g., to connect to host 10.0.0.1 via some gateway using a loose source route, use the gateway as address parameter and set a loose source route using the option ip-options=x8307040a000001 .
IP options are defined in RFC 791.

mtudiscover=<0|1|2>
Takes 0, 1, 2 to never, want, or always use path MTU discover on this socket.

ip-pktinfo
Sets the IP_PKTINFO socket option. This enables receiving and logging of ancillary messages containing destination address and interface (Linux) (example).

ip-recverr
Sets the IP_RECVERR socket option. This enables receiving and logging of ancillary messages containing detailled error information.

ip-recvopts
Sets the IP_RECVOPTS socket option. This enables receiving and logging of IP options ancillary messages (Linux, *BSD).

ip-recvtos
Sets the IP_RECVTOS socket option. This enables receiving and logging of TOS (type of service) ancillary messages (Linux).

ip-recvttl
Sets the IP_RECVTTL socket option. This enables receiving and logging of TTL (time to live) ancillary messages (Linux, *BSD).

ip-recvdstaddr
Sets the IP_RECVDSTADDR socket option. This enables receiving and logging of ancillary messages containing destination address (*BSD) (example).

ip-recvif
Sets the IP_RECVIF socket option. This enables receiving and logging of interface ancillary messages (*BSD) (example).

ip-add-membership=<multicast-address:interface-address>

ip-add-membership=<multicast-address:interface-name>

ip-add-membership=<multicast-address:interface-index>

ip-add-membership=<multicast-address:interface-address:interface-name>

ip-add-membership=<multicast-address:interface-address:interface-index>
Makes the socket member of the specified multicast group. This is currently only implemented for IPv4. The option takes the IP address of the multicast group and info about the desired network interface. The most common syntax is the first one, while the others are only available on systems that provide struct mreqn (Linux).
The indices of active network interfaces can be shown using the utility procan.

ip-multicast-if=<hostname>
Specifies hostname or address of the network interface to be used for multicast traffic.

ip-multicast-loop=<bool>
Specifies if outgoing multicast traffic should loop back to the interface.

ip-multicast-ttl=<byte>
Sets the TTL used for outgoing multicast traffic. Default is 1.

res-debug

res-aaonly

res-usevc

res-primary

res-igntc

res-recurse

res-defnames

res-stayopen

res-dnsrch
These options set the corresponding resolver (name resolution) option flags. Append "=0" to clear a default option. See man resolver\(5) for more information on these options. Note: these options are valid only for the address they are applied to.


IP6 option group

These options can only be used on IPv6 based sockets. See IP options for options that can be applied to both IPv4 and IPv6 sockets.

ipv6only=<bool>
Sets the IPV6_V6ONLY socket option. If 0, the TCP stack will also accept connections using IPv4 protocol on the same port. The default is system dependent.

ipv6-recvdstopts
Sets the IPV6_RECVDSTOPTS socket option. This enables receiving and logging of ancillary messages containing the destination options.

ipv6-recvhoplimit
Sets the IPV6_RECVHOPLIMIT socket option. This enables receiving and logging of ancillary messages containing the hoplimit.

ipv6-recvhopopts
Sets the IPV6_RECVHOPOPTS socket option. This enables receiving and logging of ancillary messages containing the hop options.

ipv6-recvpktinfo
Sets the IPV6_RECVPKTINFO socket option. This enables receiving and logging of ancillary messages containing destination address and interface.

ipv6-unicast-hops=link(TYPE_INT)(<int>)
Sets the IPV6_UNICAST_HOPS socket option. This sets the hop count limit (TTL) for outgoing unicast packets.

ipv6-recvrthdr
Sets the IPV6_RECVRTHDR socket option. This enables receiving and logging of ancillary messages containing routing information.

ipv6-tclass
Sets the IPV6_TCLASS socket option. This sets the transfer class of outgoing packets.

ipv6-recvtclass
Sets the IPV6_RECVTCLASS socket option. This enables receiving and logging of ancillary messages containing the transfer class.


TCP option group

These options may be applied to TCP sockets. They work by invoking setsockopt() with the appropriate parameters.

cork
Doesn't send packets smaller than MSS (maximal segment size).

defer-accept
While listening, accepts connections only when data from the peer arrived.

keepcnt=<count>
Sets the number of keepalives before shutting down the socket to <count> [int].

keepidle=<seconds>
Sets the idle time before sending the first keepalive to <seconds> [int].

keepintvl=<seconds>
Sets the interval between two keepalives to <seconds> [int].

linger2=<seconds>
Sets the time to keep the socket in FIN-WAIT-2 state to <seconds> [int].

mss=<bytes>
Sets the MSS (maximum segment size) after the socket() call to <bytes> [int]. This value is then proposed to the peer with the SYN or SYN/ACK packet (example).

mss-late=<bytes>
Sets the MSS of the socket after connection has been established to <bytes> [int].

nodelay
Turns off the Nagle algorithm for measuring the RTT (round trip time).

rfc1323
Enables RFC1323 TCP options: TCP window scale, round-trip time measurement (RTTM), and protect against wrapped sequence numbers (PAWS) (AIX).

stdurg
Enables RFC1122 compliant urgent pointer handling (AIX).

syncnt=<count>
Sets the maximal number of SYN retransmits during connect to <count> [int].

md5sig
Enables generation of MD5 digests on the packets (FreeBSD).

noopt
Disables use of TCP options (FreeBSD, MacOSX).

nopush
sets the TCP_NOPUSH socket option (FreeBSD, MacOSX).

sack-disable
Disables use the selective acknowledge feature (OpenBSD).

signature-enable
Enables generation of MD5 digests on the packets (OpenBSD).

abort-threshold=<milliseconds>
Sets the time to wait for an answer of the peer on an established connection (HP-UX).

conn-abort-threshold=<milliseconds>
Sets the time to wait for an answer of the server during the initial connect (HP-UX).

keepinit
Sets the time to wait for an answer of the server during connect\() before giving up. Value in half seconds, default is 150 (75s) (Tru64).

paws
Enables the "protect against wrapped sequence numbers" feature (Tru64).

sackena
Enables selective acknowledge (Tru64).

tsoptena
Enables the time stamp option that allows RTT recalculation on existing connections (Tru64).


SCTP option group

These options may be applied to SCTP stream sockets.

sctp-nodelay
Sets the SCTP_NODELAY socket option that disables the Nagle algorithm.

sctp-maxseg=<bytes>
Sets the SCTP_MAXSEG socket option to <bytes> [int]. This value is then proposed to the peer with the SYN or SYN/ACK packet.


UDP, TCP, and SCTP option groups

Here we find options that are related to the network port mechanism and thus can be used with UDP, TCP, and SCTP client and server addresses.

sourceport=<port>
For outgoing (client) TCP and UDP connections, it sets the source <port> using an extra bind() call. With TCP or UDP listen addresses, socat immediately shuts down the connection if the client does not use this sourceport (example).

lowport
Outgoing (client) TCP and UDP connections with this option use an unused random source port between 640 and 1023 incl. On UNIX class operating systems, this requires root privilege, and thus indicates that the client process is authorized by local root. TCP and UDP listen addresses with this option immediately shut down the connection if the client does not use a sourceport <= 1023. This mechanism can provide limited authorization under some circumstances.


SOCKS option group

When using SOCKS type addresses, some socks specific options can be set.

socksport=<tcp service>
Overrides the default "socks" service or port 1080 for the socks server port with <TCP service>.

socksuser=<user>
Sends the <user> [string] in the username field to the socks server. Default is the actual user name ($LOGNAME or $USER) (example).


HTTP option group

Options that can be provided with HTTP type addresses. The only HTTP address currently implemented is proxy-connect.

proxyport=<TCP service>
Overrides the default HTTP proxy port 8080 with <TCP service>.

ignorecr
The HTTP protocol requires the use of CR+NL as line terminator. When a proxy server violates this standard, socat might not understand its answer. This option directs socat to interprete NL as line terminator and to ignore CR in the answer. Nevertheless, socat sends CR+NL to the proxy.

proxyauth=<username>:<password>
Provide "basic" authentication to the proxy server. The argument to the option is used with a "Proxy-Authorization: Base" header in base64 encoded form.
Note: username and password are visible for every user on the local machine in the process list; username and password are transferred to the proxy server unencrypted (base64 encoded) and might be sniffed.

resolve
Per default, socat sends to the proxy a CONNECT request containing the target hostname. With this option, socat resolves the hostname locally and sends the IP address. Please note that, according to RFC 2396, only name resolution to IPv4 addresses is implemented.


RANGE option group

These options check if a connecting client should be granted access. They can be applied to listening and receiving network sockets. tcp-wrappers options fall into this group.

range=<address-range>
After accepting a connection, tests if the peer is within range. For IPv4 addresses, address-range takes the form address/bits, e.g. 10.0.0.0/8, or address:mask, e.g. 10.0.0.0:255.0.0.0 (example); for IPv6, it is [ip6-address/bits], e.g. [::1/128]. If the client address does not match, socat issues a warning and keeps listening/receiving.

tcpwrap[=<name>]
Uses Wietse Venema's libwrap (tcpd) library to determine if the client is allowed to connect. The configuration files are /etc/hosts.allow and /etc/hosts.deny per default, see "man 5 hosts_access" for more information. The optional <name> (type string) is passed to the wrapper functions as daemon process name (example). If omitted, the basename of socats invocation (argv[0]) is passed. If both tcpwrap and range options are applied to an address, both conditions must be fulfilled to allow the connection.

allow-table=<filename>
Takes the specified file instead of /etc/hosts.allow.

deny-table=<filename>
Takes the specified file instead of /etc/hosts.deny.

tcpwrap-etc=<directoryname>
Looks for hosts.allow and hosts.deny in the specified directory. Is overridden by options hosts-allow and hosts-deny.


LISTEN option group

Options specific to listening sockets.

backlog=<count>
Sets the backlog value passed with the listen() system call to <count> [int]. Default is 5.

max-children=<count>
Limits the number of concurrent child processes [int]. Default is no limit.

CHILD option group

Options for addresses with multiple connections via child processes.

fork
After establishing a connection, handles its channel in a child process and keeps the parent process attempting to produce more connections, either by listening or by connecting in a loop (example).
SSL-CONNECT and SSL-LISTEN differ in when they actually fork off the child: SSL-LISTEN forks before the SSL handshake, while SSL-CONNECT forks afterwards. RETRY and FOREVER options are not inherited by the child process.
On some operating systems (e.g. FreeBSD) this option does not work for UDP-LISTEN addresses.


EXEC option group

Options for addresses that invoke a program.

path=<string>
Overrides the PATH environment variable for searching the program with <string>. This $PATH value is effective in the child process too.

login
Prefixes argv[0] for the execvp() call with '-', thus making a shell behave as login shell.


FORK option group

EXEC or SYSTEM addresses invoke a program using a child process and transfer data between socat and the program. The interprocess communication mechanism can be influenced with the following options. Per default, a socketpair() is created and assigned to stdin and stdout of the child process, while stderr is inherited from the socat process, and the child process uses file descriptors 0 and 1 for communicating with the main socat process.

nofork
Does not fork a subprocess for executing the program, instead calls execvp\() or system\() directly from the actual socat instance. This avoids the overhead of another process between the program and its peer, but introduces a lot of restrictions:
  • this option can only be applied to the second socat address.
  • it cannot be applied to a part of a dual address.
  • the first socat address cannot be OPENSSL or READLINE
  • socat options -b, -t, -D, -l, -v, -x become useless
  • for both addresses, options ignoreeof, cr, and crnl become useless
  • for the second address (the one with option nofork), options append, cloexec, flock, user, group, mode, nonblock, perm-late, setlk, and setpgid cannot be applied. Some of these could be used on the first address though.

pipes
Creates a pair of unnamed pipes for interprocess communication instead of a socket pair.

openpty
Establishes communication with the sub process using a pseudo terminal created with openpty() instead of the default (socketpair or ptmx).

ptmx
Establishes communication with the sub process using a pseudo terminal created by opening /dev/ptmx or /dev/ptc instead of the default (socketpair).

pty
Establishes communication with the sub process using a pseudo terminal instead of a socket pair. Creates the pty with an available mechanism. If openpty and ptmx are both available, it uses ptmx because this is POSIX compliant (example).

ctty
Makes the pty the controlling tty of the sub process (example).

stderr
Directs stderr of the sub process to its output channel by making stderr a dup() of stdout (example).

fdin=<fdnum>
Assigns the sub processes input channel to its file descriptor <fdnum> instead of stdin (0). The program started from the subprocess has to use this fd for reading data from socat (example).

fdout=<fdnum>
Assigns the sub processes output channel to its file descriptor <fdnum> instead of stdout (1). The program started from the subprocess has to use this fd for writing data to socat (example).

sighup, sigint, sigquit
Has socat pass signals of this type to the sub process. If no address has this option, socat terminates on these signals.


TERMIOS option group

For addresses that work on a tty (e.g., stdio, file:/dev/tty, exec:...,pty), the terminal parameters defined in the UN*X termios mechanism are made available as address option parameters. Please note that changes of the parameters of your interactive terminal remain effective after socat's termination, so you might have to enter "reset" or "stty sane" in your shell afterwards. For EXEC and SYSTEM addresses with option PTY, these options apply to the pty by the child processes.

b0
Disconnects the terminal.

b19200
Sets the serial line speed to 19200 baud. Some other rates are possible; use something like socat -hh |grep ' b[1-9]' to find all speeds supported by your implementation.
Note: On some operating systems, these options may not be available. Use ispeed or ospeed instead.

echo=<bool>
Enables or disables local echo.

icanon=<bool>
Sets or clears canonical mode, enabling line buffering and some special characters.

raw
Sets raw mode, thus passing input and output almost unprocessed. This option is obsolete, use option rawer or cfmakeraw instead.

rawer
Makes terminal rawer than raw option. This option implicitly turns off echo. (example).

cfmakeraw
Sets raw mode by invoking cfmakeraw() or by simulating this call. This option implicitly turns off echo.

ignbrk=<bool>
Ignores or interpretes the BREAK character (e.g., ^C)

brkint=<bool>

bs0

bs1

bsdly=<0|1>

clocal=<bool>

cr0
cr1
cr2
cr3
Sets the carriage return delay to 0, 1, 2, or 3, respectively. 0 means no delay, the other values are terminal dependent.

crdly=<0|1|2|3>

cread=<bool>

crtscts=<bool>

cs5
cs6
cs7
cs8
Sets the character size to 5, 6, 7, or 8 bits, respectively.

csize=<0|1|2|3>

cstopb=<bool>
Sets two stop bits, rather than one.

dsusp=<byte>
Sets the value for the VDSUSP character that suspends the current foreground process and reactivates the shell (all except Linux).

echoctl=<bool>
Echos control characters in hat notation (e.g. ^A)

echoe=<bool>

echok=<bool>

echoke=<bool>

echonl=<bool>

echoprt=<bool>

eof=<byte>

eol=<byte>

eol2=<byte>

erase=<byte>

discard=<byte>

ff0

ff1

ffdly=<bool>

flusho=<bool>

hupcl=<bool>

icrnl=<bool>

iexten=<bool>

igncr=<bool>

ignpar=<bool>

imaxbel=<bool>

inlcr=<bool>

inpck=<bool>

intr=<byte>

isig=<bool>

ispeed=<unsigned-int>
Set the baud rate for incoming data on this line.
See also: ospeed, b19200

istrip=<bool>

iuclc=<bool>

ixany=<bool>

ixoff=<bool>

ixon=<bool>

kill=<byte>

lnext=<byte>

min=<byte>

nl0
Sets the newline delay to 0.

nl1

nldly=<bool>

noflsh=<bool>

ocrnl=<bool>

ofdel=<bool>

ofill=<bool>

olcuc=<bool>

onlcr=<bool>

onlret=<bool>

onocr=<bool>

opost=<bool>
Enables or disables output processing; e.g., converts NL to CR-NL.

ospeed=<unsigned-int>
Set the baud rate for outgoing data on this line.
See also: ispeed, b19200

parenb=<bool>
Enable parity generation on output and parity checking for input.

parmrk=<bool>

parodd=<bool>

pendin=<bool>

quit=<byte>

reprint=<byte>

sane
Brings the terminal to something like a useful default state.

start=<byte>

stop=<byte>

susp=<byte>

swtc=<byte>

tab0

tab1

tab2

tab3

tabdly=<unsigned-int>

time=<byte>

tostop=<bool>

vt0

vt1

vtdly=<bool>

werase=<byte>

xcase=<bool>

xtabs

i-pop-all
With UNIX System V STREAMS, removes all drivers from the stack.

i-push=<string>
With UNIX System V STREAMS, pushes the driver (module) with the given name (string) onto the stack. For example, to make sure that a character device on Solaris supports termios etc, use the following options: i-pop-all,i-push=ptem,i-push=ldterm,i-push=ttcompat


PTY option group

These options are intended for use with the pty address type.

link=<filename>
Generates a symbolic link that points to the actual pseudo terminal (pty). This might help to solve the problem that ptys are generated with more or less unpredictable names, making it difficult to directly access the socat generated pty automatically. With this option, the user can specify a "fix" point in the file hierarchy that helps him to access the actual pty (example). Beginning with socat version 1.4.3, the symbolic link is removed when the address is closed (but see option unlink-close).

wait-slave
Blocks the open phase until a process opens the slave side of the pty. Usually, socat continues after generating the pty with opening the next address or with entering the transfer loop. With the wait-slave option, socat waits until some process opens the slave side of the pty before continuing. This option only works if the operating system provides the poll() system call. And it depends on an undocumented behaviour of pty's, so it does not work on all operating systems. It has successfully been tested on Linux, FreeBSD, NetBSD, and on Tru64 with openpty.

pty-interval=<seconds>
When the wait-slave option is set, socat periodically checks the HUP condition using poll() to find if the pty's slave side has been opened. The default polling interval is 1s. Use the pty-interval option [timeval] to change this value.


OPENSSL option group

These options apply to the openssl and openssl-listen address types.

cipher=<cipherlist>
Selects the list of ciphers that may be used for the connection. See the man page of ciphers , section CIPHER LIST FORMAT, for detailed information about syntax, values, and default of <cipherlist>.
Several cipher strings may be given, separated by ':'. Some simple cipher strings:

3DES
Uses a cipher suite with triple DES.

MD5
Uses a cipher suite with MD5.

aNULL
Uses a cipher suite without authentication.

NULL
Does not use encryption.

HIGH
Uses a cipher suite with "high" encryption.
Note that the peer must support the selected property, or the negotiation will fail.

method=<ssl-method>
Sets the protocol version to be used. Valid strings (not case sensitive) are:

SSL2
Select SSL protocol version 2.

SSL3
Select SSL protocol version 3.

SSL23
Select the best available SSL or TLS protocol. This is the default when this option is not provided.

TLS1
Select TLS protocol version 1.

TLS1.1
Select TLS protocol version 1.1.

TLS1.2
Select TLS protocol version 1.2.

DTLS1
Select DTLS protocol version 1.

verify=<bool>
Controls check of the peer's certificate. Default is 1 (true). Disabling verify might open your socket for everyone, making the encryption useless!

cert=<filename>
Specifies the file with the certificate and private key for authentication. The certificate must be in OpenSSL format (*.pem). With openssl-listen, use of this option is strongly recommended. Except with cipher aNULL, "no shared ciphers" error will occur when no certificate is given.

key=<filename>
Specifies the file with the private key. The private key may be in this file or in the file given with the cert option. The party that has to proof that it is the owner of a certificate needs the private key.

dhparams=<filename>
Specifies the file with the Diffie Hellman parameters. These parameters may also be in the file given with the cert option in which case the dhparams option is not needed.

cafile=<filename>
Specifies the file with the trusted (root) authority certificates. The file must be in PEM format and should contain one or more certificates. The party that checks the authentication of its peer trusts only certificates that are in this file.

capath=<dirname>
Specifies the directory with the trusted (root) certificates. The directory must contain certificates in PEM format and their hashes (see OpenSSL documentation)

egd=<filename>
On some systems, openssl requires an explicit source of random data. Specify the socket name where an entropy gathering daemon like egd provides random data, e.g. /dev/egd-pool.

pseudo
On systems where openssl cannot find an entropy source and where no entropy gathering daemon can be utilized, this option activates a mechanism for providing pseudo entropy. This is archieved by taking the current time in microseconds for feeding the libc pseudo random number generator with an initial value. openssl is then feeded with output from random\() calls.
NOTE:This mechanism is not sufficient for generation of secure keys!

compress
Enable or disable the use of compression for a connection. Setting this to "none" disables compression, setting it to "auto" lets OpenSSL choose the best available algorithm supported by both parties. The default is to not touch any compression-related settings. NOTE: Requires OpenSSL 0.9.8 or higher and disabling compression with OpenSSL 0.9.8 affects all new connections in the process.

commonname=<string>
Specify the commonname that the peer certificate must match. With OPENSSL-CONNECT address this overrides the given hostname or IP target address; with OPENSSL-LISTEN this turns on check of peer certificates commonname. This option has only meaning when option verify is not disabled and the choosen cipher provides a peer certificate.

fips
Enables FIPS mode if compiled in. For info about the FIPS encryption implementation standard see http://oss-institute.org/fips-faq.html. This mode might require that the involved certificates are generated with a FIPS enabled version of openssl. Setting or clearing this option on one socat address affects all OpenSSL addresses of this process.


RETRY option group

Options that control retry of some system calls, especially connection attempts.

retry=<num>
Number of retries before the connection or listen attempt is aborted. Default is 0, which means just one attempt.

interval=<timespec>
Time between consecutive attempts (seconds, [timespec]). Default is 1 second.

forever
Performs an unlimited number of retry attempts.


TUN option group

Options that control Linux TUN/TAP interface device addresses.

tun-device=<device-file>
Instructs socat to take another path for the TUN clone device. Default is /dev/net/tun.

tun-name=<if-name>
Gives the resulting network interface a specific name instead of the system generated (tun0, tun1, etc.)

tun-type=[tun|tap]
Sets the type of the TUN device; use this option to generate a TAP device. See the Linux docu for the difference between these types. When you try to establish a tunnel between two TUN devices, their types should be the same.

iff-no-pi
Sets the IFF_NO_PI flag which controls if the device includes additional packet information in the tunnel. When you try to establish a tunnel between two TUN devices, these flags should have the same values.

iff-up
Sets the TUN network interface status UP. Strongly recommended.

iff-broadcast
Sets the BROADCAST flag of the TUN network interface.

iff-debug
Sets the DEBUG flag of the TUN network interface.

iff-loopback
Sets the LOOPBACK flag of the TUN network interface.

iff-pointopoint
Sets the POINTOPOINT flag of the TUN device.

iff-notrailers
Sets the NOTRAILERS flag of the TUN device.

iff-running
Sets the RUNNING flag of the TUN device.

iff-noarp
Sets the NOARP flag of the TUN device.

iff-promisc
Sets the PROMISC flag of the TUN device.

iff-allmulti
Sets the ALLMULTI flag of the TUN device.

iff-master
Sets the MASTER flag of the TUN device.

iff-slave
Sets the SLAVE flag of the TUN device.

iff-multicast
Sets the MULTICAST flag of the TUN device.

iff-portsel
Sets the PORTSEL flag of the TUN device.

iff-automedia
Sets the AUTOMEDIA flag of the TUN device.

iff-dynamic
Sets the DYNAMIC flag of the TUN device.


DATA VALUES

This section explains the different data types that address parameters and address options can take.

address-range
Is currently only implemented for IPv4 and IPv6. See address-option `range'

bool
"0" or "1"; if value is omitted, "1" is taken.

byte
An unsigned int number, read with strtoul() , lower or equal to UCHAR_MAX .

command-line
A string specifying a program name and its arguments, separated by single spaces.

data
A raw data specification following dalan syntax. Currently the only valid form is a string starting with 'x' followed by an even number of hex digits, specifying a sequence of bytes.

directory
A string with usual UN*X directory name semantics.

facility
The name of a syslog facility in lower case characters.

fdnum
An unsigned int type, read with strtoul() , specifying a UN*X file descriptor.

filename
A string with usual UN*X filename semantics.

group
If the first character is a decimal digit, the value is read with strtoul() as unsigned integer specifying a group id. Otherwise, it must be an existing group name.

int
A number following the rules of the strtol() function with base "0", i.e. decimal number, octal number with leading "0", or hexadecimal number with leading "0x". The value must fit into a C int.

interface
A string specifying the device name of a network interface as shown by ifconfig or procan, e.g. "eth0".

IP address
An IPv4 address in numbers-and-dots notation, an IPv6 address in hex notation enclosed in brackets, or a hostname that resolves to an IPv4 or an IPv6 address.
Examples: 127.0.0.1, [::1], www.dest-unreach.org, dns1

IPv4 address
An IPv4 address in numbers-and-dots notation or a hostname that resolves to an IPv4 address.
Examples: 127.0.0.1, www.dest-unreach.org, dns2

IPv6 address
An iPv6 address in hexnumbers-and-colons notation enclosed in brackets, or a hostname that resolves to an IPv6 address.
Examples: [::1], [1234:5678:9abc:def0:1234:5678:9abc:def0], ip6name.domain.org

long
A number read with strtol() . The value must fit into a C long.

long long
A number read with strtoll() . The value must fit into a C long long.

off_t
An implementation dependend signed number, usually 32 bits, read with strtol or strtoll.

off64_t
An implementation dependend signed number, usually 64 bits, read with strtol or strtoll.

mode_t
An unsigned integer, read with strtoul() , specifying mode (permission) bits.

pid_t
A number, read with strtol() , specifying a process id.

port
A uint16_t (16 bit unsigned number) specifying a TCP or UDP port, read with strtoul() .

protocol
An unsigned 8 bit number, read with strtoul() .

size_t
An unsigned number with size_t limitations, read with strtoul .

sockname
A socket address. See address-option `bind'

string
A sequence of characters, not containing '\0' and, depending on the position within the command line, ':', ',', or "!!". Note that you might have to escape shell meta characters in the command line.

TCP service
A service name, not starting with a digit, that is resolved by getservbyname() , or an unsigned int 16 bit number read with strtoul() .

timeval
A double float specifying seconds; the number is mapped into a struct timeval, consisting of seconds and microseconds.

timespec
A double float specifying seconds; the number is mapped into a struct timespec, consisting of seconds and nanoseconds.

UDP service
A service name, not starting with a digit, that is resolved by getservbyname() , or an unsigned int 16 bit number read with strtoul() .

unsigned int
A number read with strtoul() . The value must fit into a C unsigned int.

user
If the first character is a decimal digit, the value is read with strtoul() as unsigned integer specifying a user id. Otherwise, it must be an existing user name.

EXAMPLES

socat - TCP4:www.domain.org:80

transfers data between STDIO (-) and a TCP4 connection to port 80 of host www.domain.org. This example results in an interactive connection similar to telnet or netcat. The stdin terminal parameters are not changed, so you may close the relay with ^D or abort it with ^C.

socat -d -d READLINE,history=$HOME/.http_history \
TCP4:www.domain.org:www,crnl

this is similar to the previous example, but you can edit the current line in a bash like manner (READLINE) and use the history file .http_history; socat prints messages about progress (-d -d). The port is specified by service name (www), and correct network line termination characters (crnl) instead of NL are used.

socat TCP4-LISTEN:www TCP4:www.domain.org:www

installs a simple TCP port forwarder. With TCP4-LISTEN it listens on local port "www" until a connection comes in, accepts it, then connects to the remote host (TCP4) and starts data transfer. It will not accept a econd connection.

socat -d -d -lmlocal2 \
TCP4-LISTEN:80,bind=myaddr1,su=nobody,fork,range=10.0.0.0/8,reuseaddr \
TCP4:www.domain.org:80,bind=myaddr2

TCP port forwarder, each side bound to another local IP address (bind). This example handles an almost arbitrary number of parallel or consecutive connections by fork'ing a new process after each accept() . It provides a little security by su'ing to user nobody after forking; it only permits connections from the private 10 network (range); due to reuseaddr, it allows immediate restart after master process's termination, even if some child sockets are not completely shut down. With -lmlocal2, socat logs to stderr until successfully reaching the accept loop. Further logging is directed to syslog with facility local2.

socat TCP4-LISTEN:5555,fork,tcpwrap=script \
EXEC:/bin/myscript,chroot=/home/sandbox,su-d=sandbox,pty,stderr

a simple server that accepts connections (TCP4-LISTEN) and fork's a new child process for each connection; every child acts as single relay. The client must match the rules for daemon process name "script" in /etc/hosts.allow and /etc/hosts.deny, otherwise it is refused access (see "man 5 hosts_access"). For EXEC'uting the program, the child process chroot's to /home/sandbox, su's to user sandbox, and then starts the program /home/sandbox/bin/myscript. Socat and myscript communicate via a pseudo tty (pty); myscript's stderr is redirected to stdout, so its error messages are transferred via socat to the connected client.

socat EXEC:"mail.sh target@domain.com",fdin=3,fdout=4 \
TCP4:mail.relay.org:25,crnl,bind=alias1.server.org,mss=512

mail.sh is a shell script, distributed with socat, that implements a simple SMTP client. It is programmed to "speak" SMTP on its FDs 3 (in) and 4 (out). The fdin and fdout options tell socat to use these FDs for communication with the program. Because mail.sh inherits stdin and stdout while socat does not use them, the script can read a mail body from stdin. Socat makes alias1 your local source address (bind), cares for correct network line termination (crnl) and sends at most 512 data bytes per packet (mss).

socat -,escape=0x0f /dev/ttyS0,rawer,crnl

opens an interactive connection via the serial line, e.g. for talking with a modem. rawer sets the console's and ttyS0's terminal parameters to practicable values, crnl converts to correct newline characters. escape allows to terminate the socat process with character control-O. Consider using READLINE instead of the first address.

socat UNIX-LISTEN:/tmp/.X11-unix/X1,fork \
SOCKS4:host.victim.org:127.0.0.1:6000,socksuser=nobody,sourceport=20

with UNIX-LISTEN, socat opens a listening UNIX domain socket /tmp/.X11-unix/X1. This path corresponds to local XWindow display :1 on your machine, so XWindow client connections to DISPLAY=:1 are accepted. Socat then speaks with the SOCKS4 server host.victim.org that might permit sourceport 20 based connections due to an FTP related weakness in its static IP filters. Socat pretends to be invoked by socksuser nobody, and requests to be connected to loopback port 6000 (only weak sockd configurations will allow this). So we get a connection to the victims XWindow server and, if it does not require MIT cookies or Kerberos authentication, we can start work. Please note that there can only be one connection at a time, because TCP can establish only one session with a given set of addresses and ports.

socat -u /tmp/readdata,seek-end=0,ignoreeof -

this is an example for unidirectional data transfer (-u). Socat transfers data from file /tmp/readdata (implicit address GOPEN), starting at its current end (seek-end=0 lets socat start reading at current end of file; use seek=0 or no seek option to first read the existing data) in a "tail -f" like mode (ignoreeof). The "file" might also be a listening UNIX domain socket (do not use a seek option then).

(sleep 5; echo PASSWORD; sleep 5; echo ls; sleep 1) |
socat - EXEC:'ssh -l user server',pty,setsid,ctty

EXEC'utes an ssh session to server. Uses a pty for communication between socat and ssh, makes it ssh's controlling tty (ctty), and makes this pty the owner of a new process group (setsid), so ssh accepts the password from socat.

socat -u TCP4-LISTEN:3334,reuseaddr,fork \
OPEN:/tmp/in.log,creat,append

implements a simple network based message collector. For each client connecting to port 3334, a new child process is generated (option fork). All data sent by the clients are append'ed to the file /tmp/in.log. If the file does not exist, socat creat's it. Option reuseaddr allows immediate restart of the server process.

socat READLINE,noecho='[Pp]assword:' EXEC:'ftp ftp.server.com',pty,setsid,ctty

wraps a command line history (READLINE) around the EXEC'uted ftp client utility. This allows editing and reuse of FTP commands for relatively comfortable browsing through the ftp directory hierarchy. The password is echoed! pty is required to have ftp issue a prompt. Nevertheless, there may occur some confusion with the password and FTP prompts.

socat PTY,link=$HOME/dev/vmodem0,rawer,wait-slave \
EXEC:'"ssh modemserver.us.org socat - /dev/ttyS0,nonblock,rawer"'

generates a pseudo terminal device (PTY) on the client that can be reached under the symbolic link $HOME/dev/vmodem0. An application that expects a serial line or modem can be configured to use $HOME/dev/vmodem0; its traffic will be directed to a modemserver via ssh where another socat instance links it to /dev/ttyS0.

socat TCP4-LISTEN:2022,reuseaddr,fork \
PROXY:proxy:www.domain.org:22,proxyport=3128,proxyauth=user:pass

starts a forwarder that accepts connections on port 2022, and directs them through the proxy daemon listening on port 3128 (proxyport) on host proxy, using the CONNECT method, where they are authenticated as "user" with "pass" (proxyauth). The proxy should establish connections to host www.domain.org on port 22 then.

socat - SSL:server:4443,cafile=server.crt,cert=client.pem

is an OpenSSL client that tries to establish a secure connection to an SSL server. Option cafile specifies a file that contains trust certificates: we trust the server only when it presents one of these certificates and proofs that it owns the related private key. Otherwise the connection is terminated. With cert a file containing the client certificate and the associated private key is specified. This is required in case the server wishes a client authentication; many Internet servers do not.
The first address ('-') can be replaced by almost any other socat address.

socat SSL-LISTEN:4443,reuseaddr,pf=ip4,fork,cert=server.pem,cafile=client.crt PIPE

is an OpenSSL server that accepts TCP connections, presents the certificate from the file server.pem and forces the client to present a certificate that is verified against cafile.crt.
The second address ('PIPE') can be replaced by almost any other socat address.
For instructions on generating and distributing OpenSSL keys and certificates see the additional socat docu socat-openssl.txt.

echo |socat -u - file:/tmp/bigfile,create,largefile,seek=100000000000

creates a 100GB sparse file; this requires a file system type that supports this (ext2, ext3, reiserfs, jfs; not minix, vfat). The operation of writing 1 byte might take long (reiserfs: some minutes; ext2: "no" time), and the resulting file can consume some disk space with just its inodes (reiserfs: 2MB; ext2: 16KB).

socat tcp-l:7777,reuseaddr,fork system:'filan -i 0 -s >&2',nofork

listens for incoming TCP connections on port 7777. For each accepted connection, invokes a shell. This shell has its stdin and stdout directly connected to the TCP socket (nofork). The shell starts filan and lets it print the socket addresses to stderr (your terminal window).

echo -e "\0\14\0\0\c" |socat -u - file:/usr/bin/squid.exe,seek=0x00074420

functions as primitive binary editor: it writes the 4 bytes 000 014 000 000 to the executable /usr/bin/squid at offset 0x00074420 (this is a real world patch to make the squid executable from Cygwin run under Windows, actual per May 2004).

socat - tcp:www.blackhat.org:31337,readbytes=1000

connects to an unknown service and prevents being flooded.

socat -U TCP:target:9999,end-close TCP-L:8888,reuseaddr,fork

merges data arriving from different TCP streams on port 8888 to just one stream to target:9999. The end-close option prevents the child processes forked off by the second address from terminating the shared connection to 9999 (close\(2) just unlinks the inode which stays active as long as the parent process lives; shutdown\(2) would actively terminate the connection).

socat - UDP4-DATAGRAM:192.168.1.0:123,sp=123,broadcast,range=192.168.1.0/24

sends a broadcast to the network 192.168.1.0/24 and receives the replies of the timeservers there. Ignores NTP packets from hosts outside this network.

socat - SOCKET-DATAGRAM:2:2:17:x007bxc0a80100x0000000000000000,bind=x007bx00000000x0000000000000000,setsockopt-int=1:6:1,range=x0000xc0a80100x0000000000000000:x0000xffffff00x0000000000000000

is semantically equivalent to the previous example, but all parameters are specified in generic form. the value 6 of setsockopt-int is the Linux value for SO_BROADCAST.

socat - IP4-DATAGRAM:255.255.255.255:44,broadcast,range=10.0.0.0/8

sends a broadcast to the local network\(s) using protocol 44. Accepts replies from the private address range only.

socat - UDP4-DATAGRAM:224.255.0.1:6666,bind=:6666,ip-add-membership=224.255.0.1:eth0

transfers data from stdin to the specified multicast address using UDP. Both local and remote ports are 6666. Tells the interface eth0 to also accept multicast packets of the given group. Multiple hosts on the local network can run this command, so all data sent by any of the hosts will be received by all the other ones. Note that there are many possible reasons for failure, including IP-filters, routing issues, wrong interface selection by the operating system, bridges, or a badly configured switch.

socat TCP:host2:4443 TUN:192.168.255.1/24,up

establishes one side of a virtual (but not private!) network with host2 where a similar process might run, with UDP-L and tun address 192.168.255.2. They can reach each other using the addresses 192.168.255.1 and 192.168.255.2. Note that streaming eg. via TCP or SSL does not guarantee to retain packet boundaries and may thus cause packet loss.

socat PTY,link=/var/run/ppp,rawer INTERFACE:hdlc0

circumvents the problem that pppd requires a serial device and thus might not be able to work on a synchronous line that is represented by a network device. socat creates a PTY to make pppd happy, binds to the network interface hdlc0, and can transfer data between both devices. Use pppd on device /var/run/ppp then.

socat -T 1 -d -d TCP-L:10081,reuseaddr,fork,crlf SYSTEM:"echo -e \"\\\"HTTP/1.0 200 OK\\\nDocumentType: text/plain\\\n\\\ndate: \$\(date\)\\\nserver:\$SOCAT_SOCKADDR:\$SOCAT_SOCKPORT\\\nclient: \$SOCAT_PEERADDR:\$SOCAT_PEERPORT\\\n\\\"\"; cat; echo -e \"\\\"\\\n\\\"\""

creates a simple HTTP echo server: each HTTP client that connects gets a valid HTTP reply that contains information about the client address and port as it is seen by the server host, the host address (which might vary on multihomed servers), and the original client request.

socat -d -d UDP4-RECVFROM:9999,so-broadcast,so-timestamp,ip-pktinfo,ip-recverr,ip-recvopts,ip-recvtos,ip-recvttl!!- SYSTEM:'export; sleep 1' |grep SOCAT

waits for an incoming UDP packet on port 9999 and prints the environment variables provided by socat. On BSD based systems you have to replace ip-pktinfo with ip-recvdstaddr,ip-recvif. Especially interesting is SOCAT_IP_DSTADDR: it contains the target address of the packet which may be a unicast, multicast, or broadcast address.

DIAGNOSTICS

Socat uses a logging mechanism that allows to filter messages by severity. The severities provided are more or less compatible to the appropriate syslog priority. With one or up to four occurrences of the -d command line option, the lowest priority of messages that are issued can be selected. Each message contains a single uppercase character specifying the messages severity (one of F, E, W, N, I, or D)

FATAL:
Conditions that require unconditional and immediate program termination.

ERROR:
Conditions that prevent proper program processing. Usually the program is terminated (see option -s).

WARNING:
Something did not function correctly or is in a state where correct further processing cannot be guaranteed, but might be possible.

NOTICE:
Interesting actions of the program, e.g. for supervising socat in some kind of server mode.

INFO:
Description of what the program does, and maybe why it happens. Allows to monitor the lifecycles of file descriptors.

DEBUG:
Description of how the program works, all system or library calls and their results.

Log messages can be written to stderr, to a file, or to syslog.

On exit, socat gives status 0 if it terminated due to EOF or inactivity timeout, with a positive value on error, and with a negative value on fatal error.

FILES

/usr/bin/socat
/usr/bin/filan
/usr/bin/procan

ENVIRONMENT VARIABLES

Input variables carry information from the environment to socat, output variables are set by socat for use in executed scripts and programs.

In the output variables beginning with "SOCAT" this prefix is actually replaced by the upper case name of the executable or the value of option -lp.

SOCAT_DEFAULT_LISTEN_IP (input)
(Values 4 or 6) Sets the IP version to be used for listen, recv, and recvfrom addresses if no pf (protocol-family) option is given. Is overridden by socat options -4 or -6.

SOCAT_PREFERRED_RESOLVE_IP (input)
(Values 0, 4, or 6) Sets the IP version to be used when resolving target host names when version is not specified by address type, option pf (protocol-family), or address format. If name resolution does not return a matching entry, the first result (with differing IP version) is taken. With value 0, socat always selects the first record and its IP version.

SOCAT_FORK_WAIT (input)
Specifies the time (seconds) to sleep the parent and child processes after successful fork\(). Useful for debugging.

SOCAT_VERSION (output)
Socat sets this variable to its version string, e.g. "1.7.0.0" for released versions or e.g. "1.6.0.1+envvar" for temporary versions; can be used in scripts invoked by socat.

SOCAT_PID (output)
Socat sets this variable to its process id. In case of fork address option, SOCAT_PID gets the child processes id. Forking for exec and system does not change SOCAT_PID.

SOCAT_PPID (output)
Socat sets this variable to its process id. In case of fork, SOCAT_PPID keeps the pid of the master process.

SOCAT_PEERADDR (output)
With passive socket addresses (all LISTEN and RECVFROM addresses), this variable is set to a string describing the peers socket address. Port information is not included.

SOCAT_PEERPORT (output)
With appropriate passive socket addresses (TCP, UDP, and SCTP - LISTEN and RECVFROM), this variable is set to a string containing the number of the peer port.

SOCAT_SOCKADDR (output)
With all LISTEN addresses, this variable is set to a string describing the local socket address. Port information is not included example

SOCAT_SOCKPORT (output)
With TCP-LISTEN, UDP-LISTEN, and SCTP-LISTEN addresses, this variable is set to the local port.

SOCAT_TIMESTAMP (output)
With all RECVFROM addresses where address option so-timestamp is applied, socat sets this variable to the resulting timestamp.

SOCAT_IP_OPTIONS (output)
With all IPv4 based RECVFROM addresses where address option ip-recvopts is applied, socat fills this variable with the IP options of the received packet.

SOCAT_IP_DSTADDR (output)
With all IPv4 based RECVFROM addresses where address option ip-recvdstaddr (BSD) or ip-pktinfo (other platforms) is applied, socat sets this variable to the destination address of the received packet. This is particularly useful to identify broadcast and multicast addressed packets.

SOCAT_IP_IF (output)
With all IPv4 based RECVFROM addresses where address option ip-recvif (BSD) or ip-pktinfo (other platforms) is applied, socat sets this variable to the name of the interface where the packet was received.

SOCAT_IP_LOCADDR (output)
With all IPv4 based RECVFROM addresses where address option ip-pktinfo is applied, socat sets this variable to the address of the interface where the packet was received.

SOCAT_IP_TOS (output)
With all IPv4 based RECVFROM addresses where address option ip-recvtos is applied, socat sets this variable to the TOS (type of service) of the received packet.

SOCAT_IP_TTL (output)
With all IPv4 based RECVFROM addresses where address option ip-recvttl is applied, socat sets this variable to the TTL (time to live) of the received packet.

SOCAT_IPV6_HOPLIMIT (output)
With all IPv6 based RECVFROM addresses where address option ipv6-recvhoplimit is applied, socat sets this variable to the hoplimit value of the received packet.

SOCAT_IPV6_DSTADDR (output)
With all IPv6 based RECVFROM addresses where address option ipv6-recvpktinfo is applied, socat sets this variable to the destination address of the received packet.

SOCAT_IPV6_TCLASS (output)
With all IPv6 based RECVFROM addresses where address option ipv6-recvtclass is applied, socat sets this variable to the transfer class of the received packet.

SOCAT_OPENSSL_X509_ISSUER (output)
Issuer field from peer certificate

SOCAT_OPENSSL_X509_SUBJECT (output)
Subject field from peer certificate

SOCAT_OPENSSL_X509_COMMONNAME (output)
commonName entries from peer certificates subject. Multiple values are separated by " // ".

SOCAT_OPENSSL_X509_* (output)
all other entries from peer certificates subject

SOCAT_OPENSSL_X509V3_DNS (output)
DNS entries from peer certificates extensions - subjectAltName field. Multiple values are separated by " // ".

HOSTNAME (input)
Is used to determine the hostname for logging (see -lh).

LOGNAME (input)
Is used as name for the socks client user name if no socksuser is given.
With options su and su-d, LOGNAME is set to the given user name.

USER (input)
Is used as name for the socks client user name if no socksuser is given and LOGNAME is empty.
With options su and su-d, USER is set to the given user name.

SHELL (output)
With options su and su-d, SHELL is set to the login shell of the given user.

PATH (output)
Can be set with option path for exec and system addresses.

HOME (output)
With options su and su-d, HOME is set to the home directory of the given user.

CREDITS

The work of the following groups and organizations was invaluable for this project:

The FSF (GNU, http://www.fsf.org/ project with their free and portable development software and lots of other useful tools and libraries.

The Linux developers community (http://www.linux.org/) for providing a free, open source operating system.

The Open Group (http://www.unix-systems.org/) for making their standard specifications available on the Internet for free.

VERSION

This man page describes version 1.7.3 of socat.

BUGS

Addresses cannot be nested, so a single socat process cannot, e.g., drive ssl over socks.

Address option ftruncate without value uses default 1 instead of 0.

Verbose modes (-x and/or -v) display line termination characters inconsistently when address options cr or crnl are used: They show the data after conversion in either direction.

The data transfer blocksize setting (-b) is ignored with address readline.

Send bug reports to <socat@dest-unreach.org>

SEE ALSO

nc\(1), netcat6\(1), sock\(1), rinetd\(8), cage\(1), socks.conf\(5), openssl\(1), stunnel\(8), pty\(1), rlwrap\(1), setsid\(1)

Socat home page http://www.dest-unreach.org/socat/

AUTHOR

Gerhard Rieger <rieger@dest-unreach.org> socat-1.7.3.1/doc/dest-unreach.css0000644000201000020100000000045211453022152016415 0ustar gerhardgerhardtable { empty-cells:show; } .frame { border-style:solid; border-width:4px; border-color:black; } .shell { font-family:Courier; padding:2px; padding-left:6px; padding-right:6px; border-style:solid; border-width:1px; border-color:gray; color:lightgreen; background-color:black; } socat-1.7.3.1/doc/socat.10000644000201000020100000040065312460744274014542 0ustar gerhardgerhard.TH "socat" "1" "" "" "" .PP .SH "NAME" socat \- Multipurpose relay (SOcket CAT) .PP .SH "SYNOPSIS" \f(CWsocat [options]

\fP .br \f(CWsocat \-V\fP .br \f(CWsocat \-h[h[h]] | \-?[?[?]]\fP .br \f(CWfilan\fP .br \f(CWprocan\fP .PP .SH "DESCRIPTION" .PP \fBSocat\fP is a command line based utility that establishes two bidirectional byte streams and transfers data between them\&. Because the streams can be constructed from a large set of different types of data sinks and sources (see address types), and because lots of address options may be applied to the streams, socat can be used for many different purposes\&. .PP \fBFilan\fP is a utility that prints information about its active file descriptors to stdout\&. It has been written for debugging \fBsocat\fP, but might be useful for other purposes too\&. Use the \-h option to find more infos\&. .PP \fBProcan\fP is a utility that prints information about process parameters to stdout\&. It has been written to better understand some UNIX process properties and for debugging \fBsocat\fP, but might be useful for other purposes too\&. .PP The life cycle of a \fBsocat\fP instance typically consists of four phases\&. .PP In the \fIinit\fP phase, the command line options are parsed and logging is initialized\&. .PP During the \fIopen\fP phase, \fBsocat\fP opens the first address and afterwards the second address\&. These steps are usually blocking; thus, especially for complex address types like socks, connection requests or authentication dialogs must be completed before the next step is started\&. .PP In the \fItransfer\fP phase, \fBsocat\fP watches both streams\(cq\& read and write file descriptors via \f(CWselect()\fP , and, when data is available on one side \fIand\fP can be written to the other side, socat reads it, performs newline character conversions if required, and writes the data to the write file descriptor of the other stream, then continues waiting for more data in both directions\&. .PP When one of the streams effectively reaches EOF, the \fIclosing\fP phase begins\&. \fBSocat\fP transfers the EOF condition to the other stream, i\&.e\&. tries to shutdown only its write stream, giving it a chance to terminate gracefully\&. For a defined time \fBsocat\fP continues to transfer data in the other direction, but then closes all remaining channels and terminates\&. .PP .SH "OPTIONS" .PP \fBSocat\fP provides some command line options that modify the behaviour of the program\&. They have nothing to do with so called address options that are used as parts of address specifications\&. .PP .IP "\fB\f(CW\-V\fP\fP" Print version and available feature information to stdout, and exit\&. .IP "\fB\f(CW\-h | \-?\fP\fP" Print a help text to stdout describing command line options and available address types, and exit\&. .IP "\fB\f(CW\-hh | \-??\fP\fP" Like \-h, plus a list of the short names of all available address options\&. Some options are platform dependend, so this output is helpful for checking the particular implementation\&. .IP "\fB\f(CW\-hhh | \-???\fP\fP" Like \-hh, plus a list of all available address option names\&. .IP "\fB\f(CW\-d\fP\fP" Without this option, only fatal and error messages are generated; applying this option also prints warning messages\&. See DIAGNOSTICS for more information\&. .IP "\fB\f(CW\-d \-d\fP\fP" Prints fatal, error, warning, and notice messages\&. .IP "\fB\f(CW\-d \-d \-d\fP\fP" Prints fatal, error, warning, notice, and info messages\&. .IP "\fB\f(CW\-d \-d \-d \-d\fP\fP" Prints fatal, error, warning, notice, info, and debug messages\&. .IP "\fB\f(CW\-D\fP\fP" Logs information about file descriptors before starting the transfer phase\&. .IP "\fB\f(CW\-ly[]\fP\fP" Writes messages to syslog instead of stderr; severity as defined with \-d option\&. With optional , the syslog type can be selected, default is \(dq\&daemon\(dq\&\&. Third party libraries might not obey this option\&. .IP "\fB\f(CW\-lf\fP\fP\f(CW \fP" Writes messages to [filename] instead of stderr\&. Some third party libraries, in particular libwrap, might not obey this option\&. .IP "\fB\f(CW\-ls\fP\fP" Writes messages to stderr (this is the default)\&. Some third party libraries might not obey this option, in particular libwrap appears to only log to syslog\&. .IP "\fB\f(CW\-lp\fP\fP\f(CW\fP" Overrides the program name printed in error messages and used for constructing environment variable names\&. .IP "\fB\f(CW\-lu\fP\fP" Extends the timestamp of error messages to microsecond resolution\&. Does not work when logging to syslog\&. .IP "\fB\f(CW\-lm[]\fP\fP" Mixed log mode\&. During startup messages are printed to stderr; when \fBsocat\fP starts the transfer phase loop or daemon mode (i\&.e\&. after opening all streams and before starting data transfer, or, with listening sockets with fork option, before the first accept call), it switches logging to syslog\&. With optional , the syslog type can be selected, default is \(dq\&daemon\(dq\&\&. .IP "\fB\f(CW\-lh\fP\fP" Adds hostname to log messages\&. Uses the value from environment variable HOSTNAME or the value retrieved with \f(CWuname()\fP if HOSTNAME is not set\&. .IP "\fB\f(CW\-v\fP\fP" Writes the transferred data not only to their target streams, but also to stderr\&. The output format is text with some conversions for readability, and prefixed with \(dq\&> \(dq\& or \(dq\&< \(dq\& indicating flow directions\&. .IP "\fB\f(CW\-x\fP\fP" Writes the transferred data not only to their target streams, but also to stderr\&. The output format is hexadecimal, prefixed with \(dq\&> \(dq\& or \(dq\&< \(dq\& indicating flow directions\&. Can be combined with \f(CW\-v\fP \&. .IP "\fB\f(CW\-b\fP\fP\f(CW\fP" Sets the data transfer block [size_t]\&. At most bytes are transferred per step\&. Default is 8192 bytes\&. .IP "\fB\f(CW\-s\fP\fP" By default, \fBsocat\fP terminates when an error occurred to prevent the process from running when some option could not be applied\&. With this option, \fBsocat\fP is sloppy with errors and tries to continue\&. Even with this option, socat will exit on fatals, and will abort connection attempts when security checks failed\&. .IP "\fB\f(CW\-t\fP\fP\f(CW\fP" When one channel has reached EOF, the write part of the other channel is shut down\&. Then, \fBsocat\fP waits [timeval] seconds before terminating\&. Default is 0\&.5 seconds\&. This timeout only applies to addresses where write and read part can be closed independently\&. When during the timeout interval the read part gives EOF, socat terminates without awaiting the timeout\&. .IP "\fB\f(CW\-T\fP\fP\f(CW\fP" Total inactivity timeout: when socat is already in the transfer loop and nothing has happened for [timeval] seconds (no data arrived, no interrupt occurred\&.\&.\&.) then it terminates\&. Useful with protocols like UDP that cannot transfer EOF\&. .IP "\fB\f(CW\-u\fP\fP" Uses unidirectional mode\&. The first address is only used for reading, and the second address is only used for writing (example)\&. .IP "\fB\f(CW\-U\fP\fP" Uses unidirectional mode in reverse direction\&. The first address is only used for writing, and the second address is only used for reading\&. .IP "\fB\f(CW\-g\fP\fP" During address option parsing, don\(cq\&t check if the option is considered useful in the given address environment\&. Use it if you want to force, e\&.g\&., appliance of a socket option to a serial device\&. .IP "\fB\f(CW\-L\fP\fP\f(CW\fP" If lockfile exists, exits with error\&. If lockfile does not exist, creates it and continues, unlinks lockfile on exit\&. .IP "\fB\f(CW\-W\fP\fP\f(CW\fP" If lockfile exists, waits until it disappears\&. When lockfile does not exist, creates it and continues, unlinks lockfile on exit\&. .IP "\fB\f(CW\-4\fP\fP" Use IP version 4 in case that the addresses do not implicitly or explicitly specify a version; this is the default\&. .IP "\fB\f(CW\-6\fP\fP" Use IP version 6 in case that the addresses do not implicitly or explicitly specify a version\&. .PP .SH "ADDRESS SPECIFICATIONS" .PP With the address command line arguments, the user gives \fBsocat\fP instructions and the necessary information for establishing the byte streams\&. .PP An address specification usually consists of an address type keyword, zero or more required address parameters separated by \(cq\&:\(cq\& from the keyword and from each other, and zero or more address options separated by \(cq\&,\(cq\&\&. .PP The keyword specifies the address type (e\&.g\&., TCP4, OPEN, EXEC)\&. For some keywords there exist synonyms (\(cq\&\-\(cq\& for STDIO, TCP for TCP4)\&. Keywords are case insensitive\&. For a few special address types, the keyword may be omitted: Address specifications starting with a number are assumed to be FD (raw file descriptor) addresses; if a \(cq\&/\(cq\& is found before the first \(cq\&:\(cq\& or \(cq\&,\(cq\&, GOPEN (generic file open) is assumed\&. .PP The required number and type of address parameters depend on the address type\&. E\&.g\&., TCP4 requires a server specification (name or address), and a port specification (number or service name)\&. .PP Zero or more address options may be given with each address\&. They influence the address in some ways\&. Options consist of an option keyword or an option keyword and a value, separated by \(cq\&=\(cq\&\&. Option keywords are case insensitive\&. For filtering the options that are useful with an address type, each option is member of one option group\&. For each address type there is a set of option groups allowed\&. Only options belonging to one of these address groups may be used (except with option \-g)\&. .PP Address specifications following the above schema are also called \fIsingle\fP address specifications\&. Two single addresses can be combined with \(dq\&!!\(dq\& to form a \fIdual\fP type address for one channel\&. Here, the first address is used by \fBsocat\fP for reading data, and the second address for writing data\&. There is no way to specify an option only once for being applied to both single addresses\&. .PP Usually, addresses are opened in read/write mode\&. When an address is part of a dual address specification, or when option \-u or \-U is used, an address might be used only for reading or for writing\&. Considering this is important with some address types\&. .PP With socat version 1\&.5\&.0 and higher, the lexical analysis tries to handle quotes and parenthesis meaningfully and allows escaping of special characters\&. If one of the characters ( { [ \(cq\& is found, the corresponding closing character \- ) } ] \(cq\& \- is looked for; they may also be nested\&. Within these constructs, socats special characters and strings : , !! are not handled specially\&. All those characters and strings can be escaped with \e or within \(dq\&\(dq\& .PP .SH "ADDRESS TYPES" .PP This section describes the available address types with their keywords, parameters, and semantics\&. .PP .IP "\fB\f(CWCREATE:\fP\fP" Opens with \f(CWcreat()\fP and uses the file descriptor for writing\&. This address type requires write\-only context, because a file opened with \f(CWcreat\fP cannot be read from\&. .br Flags like O_LARGEFILE cannot be applied\&. If you need them use OPEN with options create,create\&. .br must be a valid existing or not existing path\&. If is a named pipe, \f(CWcreat()\fP might block; if refers to a socket, this is an error\&. .br Option groups: FD,REG,NAMED .br Useful options: mode, user, group, unlink\-early, unlink\-late, append .br See also: OPEN, GOPEN .IP "\fB\f(CWEXEC:\fP\fP" Forks a sub process that establishes communication with its parent process and invokes the specified program with \f(CWexecvp()\fP \&. is a simple command with arguments separated by single spaces\&. If the program name contains a \(cq\&/\(cq\&, the part after the last \(cq\&/\(cq\& is taken as ARGV[0]\&. If the program name is a relative path, the \f(CWexecvp()\fP semantics for finding the program via \f(CW$PATH\fP apply\&. After successful program start, \fBsocat\fP writes data to stdin of the process and reads from its stdout using a UNIX domain socket generated by \f(CWsocketpair()\fP per default\&. (example) .br Option groups: FD,SOCKET,EXEC,FORK,TERMIOS .br Useful options: path, fdin, fdout, chroot, su, su\-d, nofork, pty, stderr, ctty, setsid, pipes, login, sigint, sigquit .br See also: SYSTEM .IP "\fB\f(CWFD:\fP\fP" Uses the file descriptor \&. It must already exist as valid UN*X file descriptor\&. .br Option groups: FD (TERMIOS,REG,SOCKET) .br See also: STDIO, STDIN, STDOUT, STDERR .IP "\fB\f(CWGOPEN:\fP\fP" (Generic open) This address type tries to handle any file system entry except directories usefully\&. may be a relative or absolute path\&. If it already exists, its type is checked\&. In case of a UNIX domain socket, \fBsocat\fP connects; if connecting fails, \fBsocat\fP assumes a datagram socket and uses \f(CWsendto()\fP calls\&. If the entry is not a socket, \fBsocat\fP opens it applying the \f(CWO_APPEND\fP flag\&. If it does not exist, it is opened with flag \f(CWO_CREAT\fP as a regular file (example)\&. .br Option groups: FD,REG,SOCKET,NAMED,OPEN .br See also: OPEN, CREATE, UNIX\-CONNECT .IP .IP "\fB\f(CWIP\-SENDTO::\fP\fP" Opens a raw IP socket\&. Depending on host specification or option pf, IP protocol version 4 or 6 is used\&. It uses to send packets to [IP address] and receives packets from host, ignores packets from other hosts\&. Protocol 255 uses the raw socket with the IP header being part of the data\&. .br Option groups: FD,SOCKET,IP4,IP6 .br Useful options: pf, ttl .br See also: IP4\-SENDTO, IP6\-SENDTO, IP\-RECVFROM, IP\-RECV, UDP\-SENDTO, UNIX\-SENDTO .IP "\fB\f(CWINTERFACE:\fP\fP" Communicates with a network connected on an interface using raw packets including link level data\&. is the name of the network interface\&. Currently only available on Linux\&. Option groups: FD,SOCKET .br Useful options: pf, type .br See also: ip\-recv .IP "\fB\f(CWIP4\-SENDTO::\fP\fP" Like IP\-SENDTO, but always uses IPv4\&. .br Option groups: FD,SOCKET,IP4 .br .IP "\fB\f(CWIP6\-SENDTO::\fP\fP" Like IP\-SENDTO, but always uses IPv6\&. .br Option groups: FD,SOCKET,IP6 .br .IP .IP "\fB\f(CWIP\-DATAGRAM:
:\fP\fP" Sends outgoing data to the specified address which may in particular be a broadcast or multicast address\&. Packets arriving on the local socket are checked if their source addresses match RANGE or TCPWRAP options\&. This address type can for example be used for implementing symmetric or asymmetric broadcast or multicast communications\&. .br Option groups: FD, SOCKET, IP4, IP6, RANGE .br Useful options: bind, range, tcpwrap, broadcast, ip\-multicast\-loop, ip\-multicast\-ttl, ip\-multicast\-if, ip\-add\-membership, ttl, tos, pf .br See also: IP4\-DATAGRAM, IP6\-DATAGRAM, IP\-SENDTO, IP\-RECVFROM, IP\-RECV, UDP\-DATAGRAM .IP "\fB\f(CWIP4\-DATAGRAM::\fP\fP" Like IP\-DATAGRAM, but always uses IPv4\&. (example) .br Option groups: FD,SOCKET,IP4,RANGE .br .IP "\fB\f(CWIP6\-DATAGRAM::\fP\fP" Like IP\-DATAGRAM, but always uses IPv6\&. Please note that IPv6 does not know broadcasts\&. .br Option groups: FD,SOCKET,IP6,RANGE .br .IP .IP "\fB\f(CWIP\-RECVFROM:\fP\fP" Opens a raw IP socket of \&. Depending on option pf, IP protocol version 4 or 6 is used\&. It receives one packet from an unspecified peer and may send one or more answer packets to that peer\&. This mode is particularly useful with fork option where each arriving packet \- from arbitrary peers \- is handled by its own sub process\&. This allows a behaviour similar to typical UDP based servers like ntpd or named\&. .br Please note that the reply packets might be fetched as incoming traffic when sender and receiver IP address are identical because there is no port number to distinguish the sockets\&. .br This address works well with IP\-SENDTO address peers (see above)\&. Protocol 255 uses the raw socket with the IP header being part of the data\&. .br Option groups: FD,SOCKET,IP4,IP6,CHILD,RANGE .br Useful options: pf, fork, range, ttl, broadcast .br See also: IP4\-RECVFROM, IP6\-RECVFROM, IP\-SENDTO, IP\-RECV, UDP\-RECVFROM, UNIX\-RECVFROM .IP "\fB\f(CWIP4\-RECVFROM:\fP\fP" Like IP\-RECVFROM, but always uses IPv4\&. .br Option groups: FD,SOCKET,IP4,CHILD,RANGE .br .IP "\fB\f(CWIP6\-RECVFROM:\fP\fP" Like IP\-RECVFROM, but always uses IPv6\&. .br Option groups: FD,SOCKET,IP6,CHILD,RANGE .br .IP .IP "\fB\f(CWIP\-RECV:\fP\fP" Opens a raw IP socket of \&. Depending on option pf, IP protocol version 4 or 6 is used\&. It receives packets from multiple unspecified peers and merges the data\&. No replies are possible\&. It can be, e\&.g\&., addressed by socat IP\-SENDTO address peers\&. Protocol 255 uses the raw socket with the IP header being part of the data\&. .br Option groups: FD,SOCKET,IP4,IP6,RANGE .br Useful options: pf, range .br See also: IP4\-RECV, IP6\-RECV, IP\-SENDTO, IP\-RECVFROM, UDP\-RECV, UNIX\-RECV .IP "\fB\f(CWIP4\-RECV:\fP\fP" Like IP\-RECV, but always uses IPv4\&. .br Option groups: FD,SOCKET,IP4,RANGE .br .IP "\fB\f(CWIP6\-RECV:\fP\fP" Like IP\-RECV, but always uses IPv6\&. .br Option groups: FD,SOCKET,IP6,RANGE .br .IP .IP "\fB\f(CWOPEN:\fP\fP" Opens using the \f(CWopen()\fP system call (example)\&. This operation fails on UNIX domain sockets\&. .br Note: This address type is rarly useful in bidirectional mode\&. .br Option groups: FD,REG,NAMED,OPEN .br Useful options: creat, excl, noatime, nofollow, append, rdonly, wronly, lock, readbytes, ignoreeof .br See also: CREATE, GOPEN, UNIX\-CONNECT .IP "\fB\f(CWOPENSSL::\fP\fP" Tries to establish a SSL connection to [TCP service] on [IP address] using TCP/IP version 4 or 6 depending on address specification, name resolution, or option pf\&. .br NOTE: Up to version 1\&.7\&.2\&.4 the server certificate was only checked for validity against the system certificate store or cafile or capath, but not for match with the server\(cq\&s name or its IP address\&. Since version 1\&.7\&.3\&.0 socat checks the peer certificate for match with the parameter or the value of the openssl\-commonname option\&. Socat tries to match it against the certificates subject commonName, and the certifications extension subjectAltName DNS names\&. Wildcards in the certificate are supported\&. .br Option groups: FD,SOCKET,IP4,IP6,TCP,OPENSSL,RETRY .br Useful options: cipher, method, verify, commonname cafile, capath, certificate, key, compress, bind, pf, connect\-timeout, sourceport, retry .br See also: OPENSSL\-LISTEN, TCP .IP "\fB\f(CWOPENSSL\-LISTEN:\fP\fP" Listens on tcp [TCP service]\&. The IP version is 4 or the one specified with pf\&. When a connection is accepted, this address behaves as SSL server\&. .br Note: You probably want to use the certificate option with this address\&. .br NOTE: The client certificate is only checked for validity against cafile or capath, but not for match with the client\(cq\&s name or its IP address! .br Option groups: FD,SOCKET,IP4,IP6,TCP,LISTEN,OPENSSL,CHILD,RANGE,RETRY .br Useful options: pf, cipher, method, verify, commonname cafile, capath, certificate, key, compress, fork, bind, range, tcpwrap, su, reuseaddr, retry .br See also: OPENSSL, TCP\-LISTEN .IP "\fB\f(CWPIPE:\fP\fP" If already exists, it is opened\&. If it does not exist, a named pipe is created and opened\&. Beginning with socat version 1\&.4\&.3, the named pipe is removed when the address is closed (but see option unlink\-close .br Note: When a pipe is used for both reading and writing, it works as echo service\&. .br Note: When a pipe is used for both reading and writing, and socat tries to write more bytes than the pipe can buffer (Linux 2\&.4: 2048 bytes), socat might block\&. Consider using socat option, e\&.g\&., \f(CW\-b 2048\fP .br Option groups: FD,NAMED,OPEN .br Useful options: rdonly, nonblock, group, user, mode, unlink\-early .br See also: unnamed pipe .IP "\fB\f(CWPIPE\fP\fP" Creates an unnamed pipe and uses it for reading and writing\&. It works as an echo, because everything written to it appeares immediately as read data\&. .br Note: When socat tries to write more bytes than the pipe can queue (Linux 2\&.4: 2048 bytes), socat might block\&. Consider, e\&.g\&., using option \f(CW\-b 2048\fP .br Option groups: FD .br See also: named pipe .IP "\fB\f(CWPROXY:::\fP\fP" Connects to an HTTP proxy server on port 8080 using TCP/IP version 4 or 6 depending on address specification, name resolution, or option pf, and sends a CONNECT request for hostname:port\&. If the proxy grants access and succeeds to connect to the target, data transfer between socat and the target can start\&. Note that the traffic need not be HTTP but can be an arbitrary protocol\&. .br Option groups: FD,SOCKET,IP4,IP6,TCP,HTTP,RETRY .br Useful options: proxyport, ignorecr, proxyauth, resolve, crnl, bind, connect\-timeout, mss, sourceport, retry .br See also: SOCKS, TCP .IP "\fB\f(CWPTY\fP\fP" Generates a pseudo terminal (pty) and uses its master side\&. Another process may open the pty\(cq\&s slave side using it like a serial line or terminal\&. (example)\&. If both the ptmx and the openpty mechanisms are available, ptmx is used (POSIX)\&. .br Option groups: FD,NAMED,PTY,TERMIOS .br Useful options: link, openpty, wait\-slave, mode, user, group .br See also: UNIX\-LISTEN, PIPE, EXEC, SYSTEM .IP "\fB\f(CWREADLINE\fP\fP" Uses GNU readline and history on stdio to allow editing and reusing input lines (example)\&. This requires the GNU readline and history libraries\&. Note that stdio should be a (pseudo) terminal device, otherwise readline does not seem to work\&. .br Option groups: FD,READLINE,TERMIOS .br Useful options: history, noecho .br See also: STDIO .IP "\fB\f(CWSCTP\-CONNECT::\fP\fP" Establishes an SCTP stream connection to the specified [IP address] and [TCP service] using TCP/IP version 4 or 6 depending on address specification, name resolution, or option pf\&. .br Option groups: FD,SOCKET,IP4,IP6,SCTP,CHILD,RETRY .br Useful options: bind, pf, connect\-timeout, tos, mtudiscover, sctp\-maxseg, sctp\-nodelay, nonblock, sourceport, retry, readbytes .br See also: SCTP4\-CONNECT, SCTP6\-CONNECT, SCTP\-LISTEN, TCP\-CONNECT .IP "\fB\f(CWSCTP4\-CONNECT::\fP\fP" Like SCTP\-CONNECT, but only supports IPv4 protocol\&. .br Option groups: FD,SOCKET,IP4,SCTP,CHILD,RETRY .br .IP "\fB\f(CWSCTP6\-CONNECT::\fP\fP" Like SCTP\-CONNECT, but only supports IPv6 protocol\&. .br Option groups: FD,SOCKET,IP6,SCTP,CHILD,RETRY .br .IP "\fB\f(CWSCTP\-LISTEN:\fP\fP" Listens on [TCP service] and accepts a TCP/IP connection\&. The IP version is 4 or the one specified with address option pf, socat option (\-4, \-6), or environment variable SOCAT_DEFAULT_LISTEN_IP\&. Note that opening this address usually blocks until a client connects\&. .br Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP4,IP6,SCTP,RETRY .br Useful options: crnl, fork, bind, range, tcpwrap, pf, max\-children, backlog, sctp\-maxseg, sctp\-nodelay, su, reuseaddr, retry, cool\-write .br See also: SCTP4\-LISTEN, SCTP6\-LISTEN, TCP\-LISTEN, SCTP\-CONNECT .IP "\fB\f(CWSCTP4\-LISTEN:\fP\fP" Like SCTP\-LISTEN, but only supports IPv4 protocol\&. .br Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP4,SCTP,RETRY .br .IP "\fB\f(CWSCTP6\-LISTEN:\fP\fP" Like SCTP\-LISTEN, but only supports IPv6 protocol\&. .br Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP6,SCTP,RETRY .br .IP "\fB\f(CWSOCKET\-CONNECT:::\fP\fP" Creates a stream socket using the first and second given socket parameters and \f(CWSOCK_STREAM\fP (see man socket\e(2)) and connects to the remote\-address\&. The two socket parameters have to be specified by int numbers\&. Consult your OS documentation and include files to find the appropriate values\&. The remote\-address must be the data representation of a sockaddr structure without sa_family and (BSD) sa_len components\&. .br Please note that you can \- beyond the options of the specified groups \- also use options of higher level protocols when you apply socat option \-g\&. .br Option groups: FD,SOCKET,CHILD,RETRY .br Useful options: bind, setsockopt\-int, setsockopt\-bin, setsockopt\-string .br See also: TCP, UDP\-CONNECT, UNIX\-CONNECT, SOCKET\-LISTEN, SOCKET\-SENDTO .IP "\fB\f(CWSOCKET\-DATAGRAM::::\fP\fP" Creates a datagram socket using the first three given socket parameters (see man socket\e(2)) and sends outgoing data to the remote\-address\&. The three socket parameters have to be specified by int numbers\&. Consult your OS documentation and include files to find the appropriate values\&. The remote\-address must be the data representation of a sockaddr structure without sa_family and (BSD) sa_len components\&. .br Please note that you can \- beyond the options of the specified groups \- also use options of higher level protocols when you apply socat option \-g\&. .br Option groups: FD,SOCKET,RANGE .br Useful options: bind, range, setsockopt\-int, setsockopt\-bin, setsockopt\-string .br See also: UDP\-DATAGRAM, IP\-DATAGRAM, SOCKET\-SENDTO, SOCKET\-RECV, SOCKET\-RECVFROM .IP "\fB\f(CWSOCKET\-LISTEN:::\fP\fP" Creates a stream socket using the first and second given socket parameters and \f(CWSOCK_STREAM\fP (see man socket\e(2)) and waits for incoming connections on local\-address\&. The two socket parameters have to be specified by int numbers\&. Consult your OS documentation and include files to find the appropriate values\&. The local\-address must be the data representation of a sockaddr structure without sa_family and (BSD) sa_len components\&. .br Please note that you can \- beyond the options of the specified groups \- also use options of higher level protocols when you apply socat option \-g\&. .br Option groups: FD,SOCKET,LISTEN,RANGE,CHILD,RETRY .br Useful options: setsockopt\-int, setsockopt\-bin, setsockopt\-string .br See also: TCP, UDP\-CONNECT, UNIX\-CONNECT, SOCKET\-LISTEN, SOCKET\-SENDTO, SOCKET\-SENDTO .IP "\fB\f(CWSOCKET\-RECV::::\fP\fP" Creates a socket using the three given socket parameters (see man socket\e(2)) and binds it to \&. Receives arriving data\&. The three parameters have to be specified by int numbers\&. Consult your OS documentation and include files to find the appropriate values\&. The local\-address must be the data representation of a sockaddr structure without sa_family and (BSD) sa_len components\&. .br Option groups: FD,SOCKET,RANGE .br Useful options: range, setsockopt\-int, setsockopt\-bin, setsockopt\-string .br See also: UDP\-RECV, IP\-RECV, UNIX\-RECV, SOCKET\-DATAGRAM, SOCKET\-SENDTO, SOCKET\-RECVFROM .IP "\fB\f(CWSOCKET\-RECVFROM::::\fP\fP" Creates a socket using the three given socket parameters (see man socket\e(2)) and binds it to \&. Receives arriving data and sends replies back to the sender\&. The first three parameters have to be specified as int numbers\&. Consult your OS documentation and include files to find the appropriate values\&. The local\-address must be the data representation of a sockaddr structure without sa_family and (BSD) sa_len components\&. .br Option groups: FD,SOCKET,CHILD,RANGE .br Useful options: fork, range, setsockopt\-int, setsockopt\-bin, setsockopt\-string .br See also: UDP\-RECVFROM, IP\-RECVFROM, UNIX\-RECVFROM, SOCKET\-DATAGRAM, SOCKET\-SENDTO, SOCKET\-RECV .IP "\fB\f(CWSOCKET\-SENDTO::::\fP\fP" Creates a socket using the three given socket parameters (see man socket\e(2))\&. Sends outgoing data to the given address and receives replies\&. The three parameters have to be specified as int numbers\&. Consult your OS documentation and include files to find the appropriate values\&. The remote\-address must be the data representation of a sockaddr structure without sa_family and (BSD) sa_len components\&. .br Option groups: FD,SOCKET .br Useful options: bind, setsockopt\-int, setsockopt\-bin, setsockopt\-string .br See also: UDP\-SENDTO, IP\-SENDTO, UNIX\-SENDTO, SOCKET\-DATAGRAM, SOCKET\-RECV SOCKET\-RECVFROM .IP "\fB\f(CWSOCKS4:::\fP\fP" Connects via [IP address] to [IPv4 address] on [TCP service], using socks version 4 protocol over IP version 4 or 6 depending on address specification, name resolution, or option pf (example)\&. .br Option groups: FD,SOCKET,IP4,IP6,TCP,SOCKS4,RETRY .br Useful options: socksuser, socksport, sourceport, pf, retry .br See also: SOCKS4A, PROXY, TCP .IP "\fB\f(CWSOCKS4A:::\fP\fP" like SOCKS4, but uses socks protocol version 4a, thus leaving host name resolution to the socks server\&. .br Option groups: FD,SOCKET,IP4,IP6,TCP,SOCKS4,RETRY .br .IP "\fB\f(CWSTDERR\fP\fP" Uses file descriptor 2\&. .br Option groups: FD (TERMIOS,REG,SOCKET) .br See also: FD .IP "\fB\f(CWSTDIN\fP\fP" Uses file descriptor 0\&. .br Option groups: FD (TERMIOS,REG,SOCKET) .br Useful options: readbytes .br See also: FD .IP "\fB\f(CWSTDIO\fP\fP" Uses file descriptor 0 for reading, and 1 for writing\&. .br Option groups: FD (TERMIOS,REG,SOCKET) .br Useful options: readbytes .br See also: FD .IP "\fB\f(CWSTDOUT\fP\fP" Uses file descriptor 1\&. .br Option groups: FD (TERMIOS,REG,SOCKET) .br See also: FD .IP "\fB\f(CWSYSTEM:\fP\fP" Forks a sub process that establishes communication with its parent process and invokes the specified program with \f(CWsystem()\fP \&. Please note that [string] must not contain \(cq\&,\(cq\& or \(dq\&!!\(dq\&, and that shell meta characters may have to be protected\&. After successful program start, \fBsocat\fP writes data to stdin of the process and reads from its stdout\&. .br Option groups: FD,SOCKET,EXEC,FORK,TERMIOS .br Useful options: path, fdin, fdout, chroot, su, su\-d, nofork, pty, stderr, ctty, setsid, pipes, sigint, sigquit .br See also: EXEC .IP "\fB\f(CWTCP::\fP\fP" Connects to [TCP service] on [IP address] using TCP/IP version 4 or 6 depending on address specification, name resolution, or option pf\&. .br Option groups: FD,SOCKET,IP4,IP6,TCP,RETRY .br Useful options: crnl, bind, pf, connect\-timeout, tos, mtudiscover, mss, nodelay, nonblock, sourceport, retry, readbytes .br See also: TCP4, TCP6, TCP\-LISTEN, UDP, SCTP\-CONNECT, UNIX\-CONNECT .IP "\fB\f(CWTCP4::\fP\fP" Like TCP, but only supports IPv4 protocol (example)\&. .br Option groups: FD,SOCKET,IP4,TCP,RETRY .br .IP "\fB\f(CWTCP6::\fP\fP" Like TCP, but only supports IPv6 protocol\&. .br Option groups: FD,SOCKET,IP6,TCP,RETRY .br .IP "\fB\f(CWTCP\-LISTEN:\fP\fP" Listens on [TCP service] and accepts a TCP/IP connection\&. The IP version is 4 or the one specified with address option pf, socat option (\-4, \-6), or environment variable SOCAT_DEFAULT_LISTEN_IP\&. Note that opening this address usually blocks until a client connects\&. .br Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP4,IP6,TCP,RETRY .br Useful options: crnl, fork, bind, range, tcpwrap, pf, max\-children, backlog, mss, su, reuseaddr, retry, cool\-write .br See also: TCP4\-LISTEN, TCP6\-LISTEN, UDP\-LISTEN, SCTP\-LISTEN, UNIX\-LISTEN, OPENSSL\-LISTEN, TCP\-CONNECT .IP "\fB\f(CWTCP4\-LISTEN:\fP\fP" Like TCP\-LISTEN, but only supports IPv4 protocol (example)\&. .br Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP4,TCP,RETRY .br .IP "\fB\f(CWTCP6\-LISTEN:\fP\fP" Like TCP\-LISTEN, but only supports IPv6 protocol\&. .br Additional useful option: ipv6only .br Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP6,TCP,RETRY .br .IP "\fB\f(CWTUN[:/]\fP\fP" Creates a Linux TUN/TAP device and optionally assignes it the address and netmask given by the parameters\&. The resulting network interface is almost ready for use by other processes; socat serves its \(dq\&wire side\(dq\&\&. This address requires read and write access to the tunnel cloning device, usually \f(CW/dev/net/tun\fP , as well as permission to set some \f(CWioctl()s\fP\&. \fBOption iff\-up is required to immediately activate the interface!\fP .br Option groups: FD,NAMED,OPEN,TUN .br Useful options: iff\-up, tun\-device, tun\-name, tun\-type, iff\-no\-pi .br See also: ip\-recv .IP "\fB\f(CWUDP::\fP\fP" Connects to [UDP service] on [IP address] using UDP/IP version 4 or 6 depending on address specification, name resolution, or option pf\&. .br Please note that, due to UDP protocol properties, no real connection is established; data has to be sent for `connecting\(cq\& to the server, and no end\-of\-file condition can be transported\&. .br Option groups: FD,SOCKET,IP4,IP6 .br Useful options: ttl, tos, bind, sourceport, pf .br See also: UDP4, UDP6, UDP\-LISTEN, TCP, IP .IP "\fB\f(CWUDP4::\fP\fP" Like UDP, but only supports IPv4 protocol\&. .br Option groups: FD,SOCKET,IP4 .br .IP "\fB\f(CWUDP6::\fP\fP" Like UDP, but only supports IPv6 protocol\&. .br Option groups: FD,SOCKET,IP6 .br .IP "\fB\f(CWUDP\-DATAGRAM:
:\fP\fP" Sends outgoing data to the specified address which may in particular be a broadcast or multicast address\&. Packets arriving on the local socket are checked for the correct remote port and if their source addresses match RANGE or TCPWRAP options\&. This address type can for example be used for implementing symmetric or asymmetric broadcast or multicast communications\&. .br Option groups: FD,SOCKET,IP4,IP6,RANGE .br Useful options: bind, range, tcpwrap, broadcast, ip\-multicast\-loop, ip\-multicast\-ttl, ip\-multicast\-if, ip\-add\-membership, ttl, tos, sourceport, pf .br See also: UDP4\-DATAGRAM, UDP6\-DATAGRAM, UDP\-SENDTO, UDP\-RECVFROM, UDP\-RECV, UDP\-CONNECT, UDP\-LISTEN, IP\-DATAGRAM .IP "\fB\f(CWUDP4\-DATAGRAM:
:\fP\fP" Like UDP\-DATAGRAM, but only supports IPv4 protocol (example1, example2)\&. .br Option groups: FD,SOCKET,IP4, RANGE .IP "\fB\f(CWUDP6\-DATAGRAM:
:\fP\fP" Like UDP\-DATAGRAM, but only supports IPv6 protocol\&. .br Option groups: FD,SOCKET,IP6,RANGE .IP "\fB\f(CWUDP\-LISTEN:\fP\fP" Waits for a UDP/IP packet arriving on [UDP service] and `connects\(cq\& back to sender\&. The accepted IP version is 4 or the one specified with option pf\&. Please note that, due to UDP protocol properties, no real connection is established; data has to arrive from the peer first, and no end\-of\-file condition can be transported\&. Note that opening this address usually blocks until a client connects\&. .br Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP4,IP6 .br Useful options: fork, bind, range, pf .br See also: UDP, UDP4\-LISTEN, UDP6\-LISTEN, TCP\-LISTEN .IP "\fB\f(CWUDP4\-LISTEN:\fP\fP" Like UDP\-LISTEN, but only support IPv4 protocol\&. .br Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP4 .br .IP "\fB\f(CWUDP6\-LISTEN:\fP\fP" Like UDP\-LISTEN, but only support IPv6 protocol\&. .br Option groups: FD,SOCKET,LISTEN,CHILD,RANGE,IP6 .br .IP "\fB\f(CWUDP\-SENDTO::\fP\fP" Communicates with the specified peer socket, defined by [UDP service] on [IP address], using UDP/IP version 4 or 6 depending on address specification, name resolution, or option pf\&. It sends packets to and receives packets from that peer socket only\&. This address effectively implements a datagram client\&. It works well with socat UDP\-RECVFROM and UDP\-RECV address peers\&. .br Option groups: FD,SOCKET,IP4,IP6 .br Useful options: ttl, tos, bind, sourceport, pf .br See also: UDP4\-SENDTO, UDP6\-SENDTO, UDP\-RECVFROM, UDP\-RECV, UDP\-CONNECT, UDP\-LISTEN, IP\-SENDTO .IP "\fB\f(CWUDP4\-SENDTO::\fP\fP" Like UDP\-SENDTO, but only supports IPv4 protocol\&. .br Option groups: FD,SOCKET,IP4 .IP "\fB\f(CWUDP6\-SENDTO::\fP\fP" Like UDP\-SENDTO, but only supports IPv6 protocol\&. .br Option groups: FD,SOCKET,IP6 .IP .IP "\fB\f(CWUDP\-RECVFROM:\fP\fP" Creates a UDP socket on [UDP service] using UDP/IP version 4 or 6 depending on option pf\&. It receives one packet from an unspecified peer and may send one or more answer packets to that peer\&. This mode is particularly useful with fork option where each arriving packet \- from arbitrary peers \- is handled by its own sub process\&. This allows a behaviour similar to typical UDP based servers like ntpd or named\&. This address works well with socat UDP\-SENDTO address peers\&. .br Option groups: FD,SOCKET,IP4,IP6,CHILD,RANGE .br Useful options: fork, ttl, tos, bind, sourceport, pf .br See also: UDP4\-RECVFROM, UDP6\-RECVFROM, UDP\-SENDTO, UDP\-RECV, UDP\-CONNECT, UDP\-LISTEN, IP\-RECVFROM, UNIX\-RECVFROM .IP "\fB\f(CWUDP4\-RECVFROM:\fP\fP" Like UDP\-RECVFROM, but only supports IPv4 protocol\&. .br Option groups: FD,SOCKET,IP4,CHILD,RANGE .IP "\fB\f(CWUDP6\-RECVFROM:\fP\fP" Like UDP\-RECVFROM, but only supports IPv6 protocol\&. .br Option groups: FD,SOCKET,IP6,CHILD,RANGE .IP .IP "\fB\f(CWUDP\-RECV:\fP\fP" Creates a UDP socket on [UDP service] using UDP/IP version 4 or 6 depending on option pf\&. It receives packets from multiple unspecified peers and merges the data\&. No replies are possible\&. It works well with, e\&.g\&., socat UDP\-SENDTO address peers; it behaves similar to a syslog server\&. .br Option groups: FD,SOCKET,IP4,IP6,RANGE .br Useful options: fork, pf, bind, sourceport, ttl, tos .br See also: UDP4\-RECV, UDP6\-RECV, UDP\-SENDTO, UDP\-RECVFROM, UDP\-CONNECT, UDP\-LISTEN, IP\-RECV, UNIX\-RECV .IP "\fB\f(CWUDP4\-RECV:\fP\fP" Like UDP\-RECV, but only supports IPv4 protocol\&. .br Option groups: FD,SOCKET,IP4,RANGE .IP "\fB\f(CWUDP6\-RECV:\fP\fP" Like UDP\-RECV, but only supports IPv6 protocol\&. .br Option groups: FD,SOCKET,IP6,RANGE .IP .IP "\fB\f(CWUNIX\-CONNECT:\fP\fP" Connects to assuming it is a UNIX domain socket\&. If does not exist, this is an error; if is not a UNIX domain socket, this is an error; if is a UNIX domain socket, but no process is listening, this is an error\&. .br Option groups: FD,SOCKET,NAMED,RETRY,UNIX .br ) Useful options: bind .br See also: UNIX\-LISTEN, UNIX\-SENDTO, TCP .IP .IP "\fB\f(CWUNIX\-LISTEN:\fP\fP" Listens on using a UNIX domain stream socket and accepts a connection\&. If exists and is not a socket, this is an error\&. If exists and is a UNIX domain socket, binding to the address fails (use option unlink\-early!)\&. Note that opening this address usually blocks until a client connects\&. Beginning with socat version 1\&.4\&.3, the file system entry is removed when this address is closed (but see option unlink\-close) (example)\&. .br Option groups: FD,SOCKET,NAMED,LISTEN,CHILD,RETRY,UNIX .br Useful options: fork, umask, mode, user, group, unlink\-early .br See also: UNIX\-CONNECT, UNIX\-RECVFROM, UNIX\-RECV, TCP\-LISTEN .IP .IP "\fB\f(CWUNIX\-SENDTO:\fP\fP" Communicates with the specified peer socket, defined by [] assuming it is a UNIX domain datagram socket\&. It sends packets to and receives packets from that peer socket only\&. Please note that it might be neccessary to bind the local socket to an address (e\&.g\&. \f(CW/tmp/sock1\fP, which must not exist before)\&. This address type works well with socat UNIX\-RECVFROM and UNIX\-RECV address peers\&. .br Option groups: FD,SOCKET,NAMED,UNIX .br Useful options: bind .br See also: UNIX\-RECVFROM, UNIX\-RECV, UNIX\-CONNECT, UDP\-SENDTO, IP\-SENDTO .IP .IP "\fB\f(CWUNIX\-RECVFROM:\fP\fP" Creates a UNIX domain datagram socket []\&. Receives one packet and may send one or more answer packets to that peer\&. This mode is particularly useful with fork option where each arriving packet \- from arbitrary peers \- is handled by its own sub process\&. This address works well with socat UNIX\-SENDTO address peers\&. .br Option groups: FD,SOCKET,NAMED,CHILD,UNIX .br Useful options: fork .br See also: UNIX\-SENDTO, UNIX\-RECV, UNIX\-LISTEN, UDP\-RECVFROM, IP\-RECVFROM .IP .IP "\fB\f(CWUNIX\-RECV:\fP\fP" Creates a UNIX domain datagram socket []\&. Receives packets from multiple unspecified peers and merges the data\&. No replies are possible\&. It can be, e\&.g\&., addressed by socat UNIX\-SENDTO address peers\&. It behaves similar to a syslog server\&. Option groups: FD,SOCKET,NAMED,UNIX .br See also: UNIX\-SENDTO, UNIX\-RECVFROM, UNIX\-LISTEN, UDP\-RECV, IP\-RECV .IP .IP "\fB\f(CWUNIX\-CLIENT:\fP\fP" Communicates with the specified peer socket, defined by [] assuming it is a UNIX domain socket\&. It first tries to connect and, if that fails, assumes it is a datagram socket, thus supporting both types\&. .br Option groups: FD,SOCKET,NAMED,UNIX .br Useful options: bind .br See also: UNIX\-CONNECT, UNIX\-SENDTO, GOPEN .IP .IP "\fB\f(CWABSTRACT\-CONNECT:\fP\fP" .IP "\fB\f(CWABSTRACT\-LISTEN:\fP\fP" .IP "\fB\f(CWABSTRACT\-SENDTO:\fP\fP" .IP "\fB\f(CWABSTRACT\-RECVFROM:\fP\fP" .IP "\fB\f(CWABSTRACT\-RECV:\fP\fP" .IP "\fB\f(CWABSTRACT\-CLIENT:\fP\fP" The ABSTRACT addresses are almost identical to the related UNIX addresses except that they do not address file system based sockets but an alternate UNIX domain address space\&. To archieve this the socket address strings are prefixed with \(dq\&\e0\(dq\& internally\&. This feature is available (only?) on Linux\&. Option groups are the same as with the related UNIX addresses, except that the ABSTRACT addresses are not member of the NAMED group\&. .PP .SH "ADDRESS OPTIONS" .PP Address options can be applied to address specifications to influence the process of opening the addresses and the properties of the resulting data channels\&. .PP For technical reasons not every option can be applied to every address type; e\&.g\&., applying a socket option to a regular file will fail\&. To catch most useless combinations as early as in the open phase, the concept of \fIoption groups\fP was introduced\&. Each option belongs to one or more option groups\&. Options can be used only with address types that support at least one of their option groups (but see option \-g)\&. .PP Address options have data types that their values must conform to\&. Every address option consists of just a keyword or a keyword followed by \(dq\&=value\(dq\&, where value must conform to the options type\&. Some address options manipulate parameters of system calls; e\&.g\&., option sync sets the \f(CWO_SYNC\fP flag with the \f(CWopen()\fP call\&. Other options cause a system or library call; e\&.g\&., with option `ttl=value\(cq\& the \f(CWsetsockopt(fd, SOL_IP, IP_TTL, value, sizeof(int))\fP call is applied\&. Other options set internal \fBsocat\fP variables that are used during data transfer; e\&.g\&., `crnl\(cq\& causes explicit character conversions\&. A few options have more complex implementations; e\&.g\&., su\-d (substuser\-delayed) inquires some user and group infos, stores them, and applies them later after a possible \f(CWchroot()\fP call\&. .PP If multiple options are given to an address, their sequence in the address specification has (almost) no effect on the sequence of their execution/application\&. Instead, \fBsocat\fP has built in an \fIoption phase\fP model that tries to bring the options in a useful order\&. Some options exist in different forms (e\&.g\&., unlink, unlink\-early, unlink\-late) to control the time of their execution\&. .PP If the same option is specified more than once within one address specification, with equal or different values, the effect depends on the kind of option\&. Options resulting in function calls like \f(CWsetsockopt()\fP cause multiple invocations\&. With options that set parameters for a required call like \f(CWopen()\fP or set internal flags, the value of the last option occurrence is effective\&. .PP The existence or semantics of many options are system dependent\&. \fBSocat\fP usually does NOT try to emulate missing libc or kernel features, it just provides an interface to the underlying system\&. So, if an operating system lacks a feature, the related option is simply not available on this platform\&. .PP The following paragraphs introduce just the more common address options\&. For a more comprehensive reference and to find information about canonical option names, alias names, option phases, and platforms see file \fBxio\&.help\fP\&. .br .br .PP .br .PP \fI\fBFD option group\fP\fP .PP This option group contains options that are applied to a UN*X style file descriptor, no matter how it was generated\&. Because all current \fBsocat\fP address types are file descriptor based, these options may be applied to any address\&. .br Note: Some of these options are also member of another option group, that provides an other, non\-fd based mechanism\&. For these options, it depends on the actual address type and its option groups which mechanism is used\&. The second, non\-fd based mechanism is prioritized\&. .IP "\fB\f(CWcloexec=\fP\fP" Sets the \f(CWFD_CLOEXEC\fP flag with the \f(CWfcntl()\fP system call to value \&. If set, the file descriptor is closed on \f(CWexec()\fP family function calls\&. \fBSocat\fP internally handles this flag for the fds it controls, so in most cases there will be no need to apply this option\&. .IP "\fB\f(CWsetlk\fP\fP" Tries to set a discretionary write lock to the whole file using the \f(CWfcntl(fd, F_SETLK, \&.\&.\&.)\fP system call\&. If the file is already locked, this call results in an error\&. On Linux, when the file permissions for group are \(dq\&S\(dq\& (g\-x,g+s), and the file system is locally mounted with the \(dq\&mand\(dq\& option, the lock is mandatory, i\&.e\&. prevents other processes from opening the file\&. .IP "\fB\f(CWsetlkw\fP\fP" Tries to set a discretionary waiting write lock to the whole file using the \f(CWfcntl(fd, F_SETLKW, \&.\&.\&.)\fP system call\&. If the file is already locked, this call blocks\&. See option setlk for information about making this lock mandatory\&. .IP "\fB\f(CWsetlk\-rd\fP\fP" Tries to set a discretionary read lock to the whole file using the \f(CWfcntl(fd, F_SETLK, \&.\&.\&.)\fP system call\&. If the file is already write locked, this call results in an error\&. See option setlk for information about making this lock mandatory\&. .IP "\fB\f(CWsetlkw\-rd\fP\fP" Tries to set a discretionary waiting read lock to the whole file using the \f(CWfcntl(fd, F_SETLKW, \&.\&.\&.)\fP system call\&. If the file is already write locked, this call blocks\&. See option setlk for information about making this lock mandatory\&. .IP "\fB\f(CWflock\-ex\fP\fP" Tries to set a blocking exclusive advisory lock to the file using the \f(CWflock(fd, LOCK_EX)\fP system call\&. \fBSocat\fP hangs in this call if the file is locked by another process\&. .IP "\fB\f(CWflock\-ex\-nb\fP\fP" Tries to set a nonblocking exclusive advisory lock to the file using the \f(CWflock(fd, LOCK_EX|LOCK_NB)\fP system call\&. If the file is already locked, this option results in an error\&. .IP "\fB\f(CWflock\-sh\fP\fP" Tries to set a blocking shared advisory lock to the file using the \f(CWflock(fd, LOCK_SH)\fP system call\&. \fBSocat\fP hangs in this call if the file is locked by another process\&. .IP "\fB\f(CWflock\-sh\-nb\fP\fP" Tries to set a nonblocking shared advisory lock to the file using the \f(CWflock(fd, LOCK_SH|LOCK_NB)\fP system call\&. If the file is already locked, this option results in an error\&. .IP "\fB\f(CWlock\fP\fP" Sets a blocking lock on the file\&. Uses the setlk or flock mechanism depending on availability on the particular platform\&. If both are available, the POSIX variant (setlkw) is used\&. .IP "\fB\f(CWuser=\fP\fP" Sets the (owner) of the stream\&. If the address is member of the NAMED option group, \fBsocat\fP uses the \f(CWchown()\fP system call after opening the file or binding to the UNIX domain socket (race condition!)\&. Without filesystem entry, \fBsocat\fP sets the user of the stream using the \f(CWfchown()\fP system call\&. These calls might require root privilege\&. .IP "\fB\f(CWuser\-late=\fP\fP" Sets the owner of the fd to with the \f(CWfchown()\fP system call after opening or connecting the channel\&. This is useful only on file system entries\&. .IP "\fB\f(CWgroup=\fP\fP" Sets the of the stream\&. If the address is member of the NAMED option group, \fBsocat\fP uses the \f(CWchown()\fP system call after opening the file or binding to the UNIX domain socket (race condition!)\&. Without filesystem entry, \fBsocat\fP sets the group of the stream with the \f(CWfchown()\fP system call\&. These calls might require group membership or root privilege\&. .IP "\fB\f(CWgroup\-late=\fP\fP" Sets the group of the fd to with the \f(CWfchown()\fP system call after opening or connecting the channel\&. This is useful only on file system entries\&. .IP "\fB\f(CWmode=\fP\fP" Sets the [mode_t] (permissions) of the stream\&. If the address is member of the NAMED option group and uses the \f(CWopen()\fP or \f(CWcreat()\fP call, the mode is applied with these\&. If the address is member of the NAMED option group without using these system calls, \fBsocat\fP uses the \f(CWchmod()\fP system call after opening the filesystem entry or binding to the UNIX domain socket (race condition!)\&. Otherwise, \fBsocat\fP sets the mode of the stream using \f(CWfchmod()\fP \&. These calls might require ownership or root privilege\&. .IP "\fB\f(CWperm\-late=\fP\fP" Sets the permissions of the fd to value [mode_t] using the \f(CWfchmod()\fP system call after opening or connecting the channel\&. This is useful only on file system entries\&. .IP "\fB\f(CWappend=\fP\fP" Always writes data to the actual end of file\&. If the address is member of the OPEN option group, \fBsocat\fP uses the \f(CWO_APPEND\fP flag with the \f(CWopen()\fP system call (example)\&. Otherwise, \fBsocat\fP applies the \f(CWfcntl(fd, F_SETFL, O_APPEND)\fP call\&. .IP "\fB\f(CWnonblock=\fP\fP" Tries to open or use file in nonblocking mode\&. Its only effects are that the \f(CWconnect()\fP call of TCP addresses does not block, and that opening a named pipe for reading does not block\&. If the address is member of the OPEN option group, \fBsocat\fP uses the \f(CWO_NONBLOCK\fP flag with the \f(CWopen()\fP system call\&. Otherwise, \fBsocat\fP applies the \f(CWfcntl(fd, F_SETFL, O_NONBLOCK)\fP call\&. .IP "\fB\f(CWbinary\fP\fP" Opens the file in binary mode to avoid implicit line terminator conversions (Cygwin)\&. .IP "\fB\f(CWtext\fP\fP" Opens the file in text mode to force implicit line terminator conversions (Cygwin)\&. .IP "\fB\f(CWnoinherit\fP\fP" Does not keep this file open in a spawned process (Cygwin)\&. .IP "\fB\f(CWcool\-write\fP\fP" Takes it easy when write fails with EPIPE or ECONNRESET and logs the message with \fInotice\fP level instead of \fIerror\fP\&. This prevents the log file from being filled with useless error messages when socat is used as a high volume server or proxy where clients often abort the connection\&. .br This option is experimental\&. .IP "\fB\f(CWend\-close\fP\fP" Changes the (address dependent) method of ending a connection to just close the file descriptors\&. This is useful when the connection is to be reused by or shared with other processes (example)\&. .br Normally, socket connections will be ended with \f(CWshutdown(2)\fP which terminates the socket even if it is shared by multiple processes\&. \f(CWclose(2)\fP \(dq\&unlinks\(dq\& the socket from the process but keeps it active as long as there are still links from other processes\&. .br Similarly, when an address of type EXEC or SYSTEM is ended, socat usually will explicitely kill the sub process\&. With this option, it will just close the file descriptors\&. .IP "\fB\f(CWshut\-none\fP\fP" Changes the (address dependent) method of shutting down the write part of a connection to not do anything\&. .IP "\fB\f(CWshut\-down\fP\fP" Changes the (address dependent) method of shutting down the write part of a connection to \f(CWshutdown\e(fd, SHUT_WR)\fP\&. Is only useful with sockets\&. .IP "\fB\f(CWshut\-close\fP\fP" Changes the (address dependent) method of shutting down the write part of a connection to \f(CWclose\e(fd)\fP\&. .IP "\fB\f(CWshut\-null\fP\fP" When one address indicates EOF, \fBsocat\fP will send a zero sized packet to the write channel of the other address to transfer the EOF condition\&. This is useful with UDP and other datagram protocols\&. Has been tested against netcat and socat with option null\-eof\&. .IP "\fB\f(CWnull\-eof\fP\fP" Normally \fBsocat\fP will ignore empty (zero size payload) packets arriving on datagram sockets, so it survives port scans\&. With this option \fBsocat\fP interprets empty datagram packets as EOF indicator (see shut\-null)\&. .IP "\fB\f(CWioctl\-void=\fP\fP" Calls \f(CWioctl()\fP with the request value as second argument and NULL as third argument\&. This option allows to utilize ioctls that are not explicitely implemented in socat\&. .IP "\fB\f(CWioctl\-int=:\fP\fP" Calls \f(CWioctl()\fP with the request value as second argument and the integer value as third argument\&. .IP "\fB\f(CWioctl\-intp=:\fP\fP" Calls \f(CWioctl()\fP with the request value as second argument and a pointer to the integer value as third argument\&. .IP "\fB\f(CWioctl\-bin=:\fP\fP" Calls \f(CWioctl()\fP with the request value as second argument and a pointer to the given data value as third argument\&. This data must be specified in form\&. .IP "\fB\f(CWioctl\-string=:\fP\fP" Calls \f(CWioctl()\fP with the request value as second argument and a pointer to the given string as third argument\&. form\&. .PP .br .PP \fI\fBNAMED option group\fP\fP .PP These options work on file system entries\&. .br See also options user, group, and mode\&. .PP .IP "\fB\f(CWuser\-early=\fP\fP" Changes the (owner) of the file system entry before accessing it, using the \f(CWchown()\fP system call\&. This call might require root privilege\&. .IP "\fB\f(CWgroup\-early=\fP\fP" Changes the of the file system entry before accessing it, using the \f(CWchown()\fP system call\&. This call might require group membership or root privilege\&. .IP "\fB\f(CWperm\-early=\fP\fP" Changes the [mode_t] of the file system entry before accessing it, using the \f(CWchmod()\fP system call\&. This call might require ownership or root privilege\&. .IP "\fB\f(CWumask=\fP\fP" Sets the umask of the process to [mode_t] before accessing the file system entry (useful with UNIX domain sockets!)\&. This call might affect all further operations of the \fBsocat\fP process! .IP "\fB\f(CWunlink\-early\fP\fP" Unlinks (removes) the file before opening it and even before applying user\-early etc\&. .IP "\fB\f(CWunlink\fP\fP" Unlinks (removes) the file before accessing it, but after user\-early etc\&. .IP "\fB\f(CWunlink\-late\fP\fP" Unlinks (removes) the file after opening it to make it inaccessible for other processes after a short race condition\&. .IP "\fB\f(CWunlink\-close\fP\fP" Removes the addresses file system entry when closing the address\&. For named pipes, listening unix domain sockets, and the symbolic links of pty addresses, the default is 1; for created files, opened files, generic opened files, and client unix domain sockets the default is 0\&. .PP .br .PP \fI\fBOPEN option group\fP\fP .PP The OPEN group options allow to set flags with the \f(CWopen()\fP system call\&. E\&.g\&., option `creat\(cq\& sets the \f(CWO_CREAT\fP flag\&. .br See also options append and nonblock\&. .IP "\fB\f(CWcreat=\fP\fP" Creates the file if it does not exist (example)\&. .IP "\fB\f(CWdsync=\fP\fP" Blocks \f(CWwrite()\fP calls until metainfo is physically written to media\&. .IP "\fB\f(CWexcl=\fP\fP" With option creat, if file exists this is an error\&. .IP "\fB\f(CWlargefile=\fP\fP" On 32 bit systems, allows a file larger than 2^31 bytes\&. .IP "\fB\f(CWnoatime\fP\fP" Sets the O_NOATIME options, so reads do not change the access timestamp\&. .IP "\fB\f(CWnoctty=\fP\fP" Does not make this file the controlling terminal\&. .IP "\fB\f(CWnofollow=\fP\fP" Does not follow symbolic links\&. .IP "\fB\f(CWnshare=\fP\fP" Does not allow to share this file with other processes\&. .IP "\fB\f(CWrshare=\fP\fP" Does not allow other processes to open this file for writing\&. .IP "\fB\f(CWrsync=\fP\fP" Blocks \f(CWwrite()\fP until metainfo is physically written to media\&. .IP "\fB\f(CWsync=\fP\fP" Blocks \f(CWwrite()\fP until data is physically written to media\&. .IP "\fB\f(CWrdonly=\fP\fP" Opens the file for reading only\&. .IP "\fB\f(CWwronly=\fP\fP" Opens the file for writing only\&. .IP "\fB\f(CWtrunc\fP\fP" Truncates the file to size 0 during opening it\&. .PP .br .PP \fI\fBREG and BLK option group\fP\fP .PP These options are usually applied to a UN*X file descriptor, but their semantics make sense only on a file supporting random access\&. .IP "\fB\f(CWseek=\fP\fP" Applies the \f(CWlseek(fd, , SEEK_SET)\fP (or \f(CWlseek64\fP ) system call, thus positioning the file pointer absolutely to [off_t or off64_t]\&. Please note that a missing value defaults to 1, not 0\&. .IP "\fB\f(CWseek\-cur=\fP\fP" Applies the \f(CWlseek(fd, , SEEK_CUR)\fP (or \f(CWlseek64\fP ) system call, thus positioning the file pointer [off_t or off64_t] bytes relatively to its current position (which is usually 0)\&. Please note that a missing value defaults to 1, not 0\&. .IP "\fB\f(CWseek\-end=\fP\fP" Applies the \f(CWlseek(fd, , SEEK_END)\fP (or \f(CWlseek64\fP ) system call, thus positioning the file pointer [off_t or off64_t] bytes relatively to the files current end\&. Please note that a missing value defaults to 1, not 0\&. .IP "\fB\f(CWftruncate=\fP\fP" Applies the \f(CWftruncate(fd, )\fP (or \f(CWftruncate64\fP if available) system call, thus truncating the file at the position [off_t or off64_t]\&. Please note that a missing value defaults to 1, not 0\&. .IP .IP "\fB\f(CWsecrm=\fP\fP" .IP "\fB\f(CWunrm=\fP\fP" .IP "\fB\f(CWcompr=\fP\fP" .IP "\fB\f(CWext2\-sync=\fP\fP" .IP "\fB\f(CWimmutable=\fP\fP" .IP "\fB\f(CWext2\-append=\fP\fP" .IP "\fB\f(CWnodump=\fP\fP" .IP "\fB\f(CWext2\-noatime=\fP\fP" .IP "\fB\f(CWjournal\-data=\fP\fP" .IP "\fB\f(CWnotail=\fP\fP" .IP "\fB\f(CWdirsync=\fP\fP" These options change non standard file attributes on operating systems and file systems that support these features, like Linux with ext2fs, ext3fs, or reiserfs\&. See man 1 chattr for information on these options\&. Please note that there might be a race condition between creating the file and applying these options\&. .PP .br .PP \fI\fBPROCESS option group\fP\fP .PP Options of this group change the process properties instead of just affecting one data channel\&. For EXEC and SYSTEM addresses and for LISTEN and CONNECT type addresses with option FORK, these options apply to the child processes instead of the main socat process\&. .IP "\fB\f(CWchroot=\fP\fP" Performs a \f(CWchroot()\fP operation to after processing the address (example)\&. This call might require root privilege\&. .IP "\fB\f(CWchroot\-early=\fP\fP" Performs a \f(CWchroot()\fP operation to before opening the address\&. This call might require root privilege\&. .IP "\fB\f(CWsetgid=\fP\fP" Changes the primary of the process after processing the address\&. This call might require root privilege\&. Please note that this option does not drop other group related privileges\&. .IP "\fB\f(CWsetgid\-early=\fP\fP" Like setgit but is performed before opening the address\&. .IP "\fB\f(CWsetuid=\fP\fP" Changes the (owner) of the process after processing the address\&. This call might require root privilege\&. Please note that this option does not drop group related privileges\&. Check if option su better fits your needs\&. .IP "\fB\f(CWsetuid\-early=\fP\fP" Like setuid but is performed before opening the address\&. .IP "\fB\f(CWsu=\fP\fP" Changes the (owner) and groups of the process after processing the address (example)\&. This call might require root privilege\&. .IP "\fB\f(CWsu\-d=\fP\fP" Short name for \f(CWsubstuser\-delayed\fP\&. Changes the (owner) and groups of the process after processing the address (example)\&. The user and his groups are retrieved \fIbefore\fP a possible \f(CWchroot()\fP \&. This call might require root privilege\&. .IP "\fB\f(CWsetpgid=\fP\fP" Makes the process a member of the specified process group \&. If no value is given, or if the value is 0 or 1, the process becomes leader of a new process group\&. .IP "\fB\f(CWsetsid\fP\fP" Makes the process the leader of a new session (example)\&. .PP .br .PP \fI\fBREADLINE option group\fP\fP .PP These options apply to the readline address type\&. .IP "\fB\f(CWhistory=\fP\fP" Reads and writes history from/to (example)\&. .IP "\fB\f(CWnoprompt\fP\fP" Since version 1\&.4\&.0, socat per default tries to determine a prompt \- that is then passed to the readline call \- by remembering the last incomplete line of the output\&. With this option, socat does not pass a prompt to readline, so it begins line editing in the first column of the terminal\&. .IP "\fB\f(CWnoecho=\fP\fP" Specifies a regular pattern for a prompt that prevents the following input line from being displayed on the screen and from being added to the history\&. The prompt is defined as the text that was output to the readline address after the lastest newline character and before an input character was typed\&. The pattern is a regular expression, e\&.g\&. \(dq\&^[Pp]assword:\&.*$\(dq\& or \(dq\&([Uu]ser:|[Pp]assword:)\(dq\&\&. See regex\e(7) for details\&. (example) .IP "\fB\f(CWprompt=\fP\fP" Passes the string as prompt to the readline function\&. readline prints this prompt when stepping through the history\&. If this string matches a constant prompt issued by an interactive program on the other socat address, consistent look and feel can be archieved\&. .PP .br .PP \fI\fBAPPLICATION option group\fP\fP .PP This group contains options that work at data level\&. Note that these options only apply to the \(dq\&raw\(dq\& data transferred by socat, but not to protocol data used by addresses like PROXY\&. .IP "\fB\f(CWcr\fP\fP" Converts the default line termination character NL (\(cq\&\en\(cq\&, 0x0a) to/from CR (\(cq\&\er\(cq\&, 0x0d) when writing/reading on this channel\&. .IP "\fB\f(CWcrnl\fP\fP" Converts the default line termination character NL (\(cq\&\en\(cq\&, 0x0a) to/from CRNL (\(dq\&\er\en\(dq\&, 0x0d0a) when writing/reading on this channel (example)\&. Note: socat simply strips all CR characters\&. .IP "\fB\f(CWignoreeof\fP\fP" When EOF occurs on this channel, \fBsocat\fP ignores it and tries to read more data (like \(dq\&tail \-f\(dq\&) (example)\&. .IP "\fB\f(CWreadbytes=\fP\fP" \fBsocat\fP reads only so many bytes from this address (the address provides only so many bytes for transfer and pretends to be at EOF afterwards)\&. Must be greater than 0\&. .IP "\fB\f(CWlockfile=\fP\fP" If lockfile exists, exits with error\&. If lockfile does not exist, creates it and continues, unlinks lockfile on exit\&. .IP "\fB\f(CWwaitlock=\fP\fP" If lockfile exists, waits until it disappears\&. When lockfile does not exist, creates it and continues, unlinks lockfile on exit\&. .IP "\fB\f(CWescape=\fP\fP" Specifies the numeric code of a character that triggers EOF on the input stream\&. It is useful with a terminal in raw mode (example)\&. .PP .br .PP \fI\fBSOCKET option group\fP\fP .PP These options are intended for all kinds of sockets, e\&.g\&. IP or UNIX domain\&. Most are applied with a \f(CWsetsockopt()\fP call\&. .IP "\fB\f(CWbind=\fP\fP" Binds the socket to the given socket address using the \f(CWbind()\fP system call\&. The form of is socket domain dependent: IP4 and IP6 allow the form [hostname|hostaddress][:(service|port)] (example), UNIX domain sockets require \&. .IP "\fB\f(CWconnect\-timeout=\fP\fP" Abort the connection attempt after [timeval] with error status\&. .IP "\fB\f(CWso\-bindtodevice=\fP\fP" Binds the socket to the given \&. This option might require root privilege\&. .IP "\fB\f(CWbroadcast\fP\fP" For datagram sockets, allows sending to broadcast addresses and receiving packets addressed to broadcast addresses\&. .IP "\fB\f(CWdebug\fP\fP" Enables socket debugging\&. .IP "\fB\f(CWdontroute\fP\fP" Only communicates with directly connected peers, does not use routers\&. .IP "\fB\f(CWkeepalive\fP\fP" Enables sending keepalives on the socket\&. .IP "\fB\f(CWlinger=\fP\fP" Blocks \f(CWshutdown()\fP or \f(CWclose()\fP until data transfers have finished or the given timeout [int] expired\&. .IP "\fB\f(CWoobinline\fP\fP" Places out\-of\-band data in the input data stream\&. .IP "\fB\f(CWpriority=\fP\fP" Sets the protocol defined [] for outgoing packets\&. .IP "\fB\f(CWrcvbuf=\fP\fP" Sets the size of the receive buffer after the \f(CWsocket()\fP call to [int]\&. With TCP sockets, this value corresponds to the socket\(cq\&s maximal window size\&. .IP "\fB\f(CWrcvbuf\-late=\fP\fP" Sets the size of the receive buffer when the socket is already connected to [int]\&. With TCP sockets, this value corresponds to the socket\(cq\&s maximal window size\&. .IP "\fB\f(CWrcvlowat=\fP\fP" Specifies the minimum number of received bytes [int] until the socket layer will pass the buffered data to \fBsocat\fP\&. .IP "\fB\f(CWrcvtimeo=\fP\fP" Sets the receive timeout [timeval]\&. .IP "\fB\f(CWreuseaddr\fP\fP" Allows other sockets to bind to an address even if parts of it (e\&.g\&. the local port) are already in use by \fBsocat\fP (example)\&. .IP "\fB\f(CWsndbuf=\fP\fP" Sets the size of the send buffer after the \f(CWsocket()\fP call to [int]\&. .IP "\fB\f(CWsndbuf\-late=\fP\fP" Sets the size of the send buffer when the socket is connected to [int]\&. .IP "\fB\f(CWsndlowat=\fP\fP" Specifies the minimum number of bytes in the send buffer until the socket layer will send the data to [int]\&. .IP "\fB\f(CWsndtimeo=\fP\fP" Sets the send timeout to seconds [timeval]\&. .IP "\fB\f(CWpf=\fP\fP" Forces the use of the specified IP version or protocol\&. can be something like \(dq\&ip4\(dq\& or \(dq\&ip6\(dq\&\&. The resulting value is used as first argument to the \f(CWsocket()\fP or \f(CWsocketpair()\fP calls\&. This option affects address resolution and the required syntax of bind and range options\&. .IP "\fB\f(CWtype=\fP\fP" Sets the type of the socket, specified as second argument to the \f(CWsocket()\fP or \f(CWsocketpair()\fP calls, to [int]\&. Address resolution is not affected by this option\&. Under Linux, 1 means stream oriented socket, 2 means datagram socket, and 3 means raw socket\&. .IP "\fB\f(CWprototype\fP\fP" Sets the protocol of the socket, specified as third argument to the \f(CWsocket()\fP or \f(CWsocketpair()\fP calls, to [int]\&. Address resolution is not affected by this option\&. 6 means TCP, 17 means UDP\&. .IP "\fB\f(CWso\-timestamp\fP\fP" Sets the SO_TIMESTAMP socket option\&. This enables receiving and logging of timestamp ancillary messages\&. .IP "\fB\f(CWsetsockopt\-int=::\fP\fP" Invokes \f(CWsetsockopt()\fP for the socket with the given parameters\&. \f(CWlevel\fP [int] is used as second argument to \f(CWsetsockopt()\fP and specifies the layer, e\&.g\&. SOL_TCP for TCP (6 on Linux), or SOL_SOCKET for the socket layer (1 on Linux)\&. \f(CWoptname\fP [int] is the third argument to \f(CWsetsockopt()\fP and tells which socket option is to be set\&. For the actual numbers you might have to look up the appropriate include files of your system\&. The 4th \f(CWsetsockopt()\fP parameter, \f(CWvalue\fP [int], is passed to the function per pointer, and for the length parameter sizeof\e(int) is taken implicitely\&. .IP "\fB\f(CWsetsockopt\-bin=::\fP\fP" Like \f(CWsetsockopt\-int\fP, but must be provided in dalan format and specifies an arbitrary sequence of bytes; the length parameter is automatically derived from the data\&. .IP "\fB\f(CWsetsockopt\-string=::\fP\fP" Like \f(CWsetsockopt\-int\fP, but must be a string\&. This string is passed to the function with trailing null character, and the length parameter is automatically derived from the data\&. .PP .br .PP \fI\fBUNIX option group\fP\fP .PP These options apply to UNIX domain based addresses\&. .IP "\fB\f(CWunix\-tightsocklen=[0|1]\fP\fP" On socket operations, pass a socket address length that does not include the whole \f(CWstruct sockaddr_un\fP record but (besides other components) only the relevant part of the filename or abstract string\&. Default is 1\&. .PP \fI\fBIP4 and IP6 option groups\fP\fP .PP These options can be used with IPv4 and IPv6 based sockets\&. .IP "\fB\f(CWtos=\fP\fP" Sets the TOS (type of service) field of outgoing packets to [byte] (see RFC 791)\&. .IP "\fB\f(CWttl=\fP\fP" Sets the TTL (time to live) field of outgoing packets to [byte]\&. .IP "\fB\f(CWip\-options=\fP\fP" Sets IP options like source routing\&. Must be given in binary form, recommended format is a leading \(dq\&x\(dq\& followed by an even number of hex digits\&. This option may be used multiple times, data are appended\&. E\&.g\&., to connect to host 10\&.0\&.0\&.1 via some gateway using a loose source route, use the gateway as address parameter and set a loose source route using the option \f(CWip\-options=x8307040a000001\fP \&. .br IP options are defined in RFC 791\&. .br .IP "\fB\f(CWmtudiscover=<0|1|2>\fP\fP" Takes 0, 1, 2 to never, want, or always use path MTU discover on this socket\&. .IP "\fB\f(CWip\-pktinfo\fP\fP" Sets the IP_PKTINFO socket option\&. This enables receiving and logging of ancillary messages containing destination address and interface (Linux) (example)\&. .IP "\fB\f(CWip\-recverr\fP\fP" Sets the IP_RECVERR socket option\&. This enables receiving and logging of ancillary messages containing detailled error information\&. .IP "\fB\f(CWip\-recvopts\fP\fP" Sets the IP_RECVOPTS socket option\&. This enables receiving and logging of IP options ancillary messages (Linux, *BSD)\&. .IP "\fB\f(CWip\-recvtos\fP\fP" Sets the IP_RECVTOS socket option\&. This enables receiving and logging of TOS (type of service) ancillary messages (Linux)\&. .IP "\fB\f(CWip\-recvttl\fP\fP" Sets the IP_RECVTTL socket option\&. This enables receiving and logging of TTL (time to live) ancillary messages (Linux, *BSD)\&. .IP "\fB\f(CWip\-recvdstaddr\fP\fP" Sets the IP_RECVDSTADDR socket option\&. This enables receiving and logging of ancillary messages containing destination address (*BSD) (example)\&. .IP "\fB\f(CWip\-recvif\fP\fP" Sets the IP_RECVIF socket option\&. This enables receiving and logging of interface ancillary messages (*BSD) (example)\&. .IP "\fB\f(CWip\-add\-membership=\fP\fP" .IP "\fB\f(CWip\-add\-membership=\fP\fP" .IP "\fB\f(CWip\-add\-membership=\fP\fP" .IP "\fB\f(CWip\-add\-membership=\fP\fP" .IP "\fB\f(CWip\-add\-membership=\fP\fP" Makes the socket member of the specified multicast group\&. This is currently only implemented for IPv4\&. The option takes the IP address of the multicast group and info about the desired network interface\&. The most common syntax is the first one, while the others are only available on systems that provide \f(CWstruct mreqn\fP (Linux)\&. .br The indices of active network interfaces can be shown using the utility \fBprocan\fP\&. .IP "\fB\f(CWip\-multicast\-if=\fP\fP" Specifies hostname or address of the network interface to be used for multicast traffic\&. .IP "\fB\f(CWip\-multicast\-loop=\fP\fP" Specifies if outgoing multicast traffic should loop back to the interface\&. .IP "\fB\f(CWip\-multicast\-ttl=\fP\fP" Sets the TTL used for outgoing multicast traffic\&. Default is 1\&. .IP "\fB\f(CWres\-debug\fP\fP" .IP "\fB\f(CWres\-aaonly\fP\fP" .IP "\fB\f(CWres\-usevc\fP\fP" .IP "\fB\f(CWres\-primary\fP\fP" .IP "\fB\f(CWres\-igntc\fP\fP" .IP "\fB\f(CWres\-recurse\fP\fP" .IP "\fB\f(CWres\-defnames\fP\fP" .IP "\fB\f(CWres\-stayopen\fP\fP" .IP "\fB\f(CWres\-dnsrch\fP\fP" These options set the corresponding resolver (name resolution) option flags\&. Append \(dq\&=0\(dq\& to clear a default option\&. See man resolver\e(5) for more information on these options\&. Note: these options are valid only for the address they are applied to\&. .IP .br .PP \fI\fBIP6 option group\fP\fP .PP These options can only be used on IPv6 based sockets\&. See IP options for options that can be applied to both IPv4 and IPv6 sockets\&. .IP "\fB\f(CWipv6only=\fP\fP" Sets the IPV6_V6ONLY socket option\&. If 0, the TCP stack will also accept connections using IPv4 protocol on the same port\&. The default is system dependent\&. .IP "\fB\f(CWipv6\-recvdstopts\fP\fP" Sets the IPV6_RECVDSTOPTS socket option\&. This enables receiving and logging of ancillary messages containing the destination options\&. .IP "\fB\f(CWipv6\-recvhoplimit\fP\fP" Sets the IPV6_RECVHOPLIMIT socket option\&. This enables receiving and logging of ancillary messages containing the hoplimit\&. .IP "\fB\f(CWipv6\-recvhopopts\fP\fP" Sets the IPV6_RECVHOPOPTS socket option\&. This enables receiving and logging of ancillary messages containing the hop options\&. .IP "\fB\f(CWipv6\-recvpktinfo\fP\fP" Sets the IPV6_RECVPKTINFO socket option\&. This enables receiving and logging of ancillary messages containing destination address and interface\&. .IP "\fB\f(CWipv6\-unicast\-hops=link(TYPE_INT)()\fP\fP" Sets the IPV6_UNICAST_HOPS socket option\&. This sets the hop count limit (TTL) for outgoing unicast packets\&. .IP "\fB\f(CWipv6\-recvrthdr\fP\fP" Sets the IPV6_RECVRTHDR socket option\&. This enables receiving and logging of ancillary messages containing routing information\&. .IP "\fB\f(CWipv6\-tclass\fP\fP" Sets the IPV6_TCLASS socket option\&. This sets the transfer class of outgoing packets\&. .IP "\fB\f(CWipv6\-recvtclass\fP\fP" Sets the IPV6_RECVTCLASS socket option\&. This enables receiving and logging of ancillary messages containing the transfer class\&. .PP .br .PP \fI\fBTCP option group\fP\fP .PP These options may be applied to TCP sockets\&. They work by invoking \f(CWsetsockopt()\fP with the appropriate parameters\&. .IP "\fB\f(CWcork\fP\fP" Doesn\(cq\&t send packets smaller than MSS (maximal segment size)\&. .IP "\fB\f(CWdefer\-accept\fP\fP" While listening, accepts connections only when data from the peer arrived\&. .IP "\fB\f(CWkeepcnt=\fP\fP" Sets the number of keepalives before shutting down the socket to [int]\&. .IP "\fB\f(CWkeepidle=\fP\fP" Sets the idle time before sending the first keepalive to [int]\&. .IP "\fB\f(CWkeepintvl=\fP\fP" Sets the interval between two keepalives to [int]\&. .IP "\fB\f(CWlinger2=\fP\fP" Sets the time to keep the socket in FIN\-WAIT\-2 state to [int]\&. .IP "\fB\f(CWmss=\fP\fP" Sets the MSS (maximum segment size) after the \f(CWsocket()\fP call to [int]\&. This value is then proposed to the peer with the SYN or SYN/ACK packet (example)\&. .IP "\fB\f(CWmss\-late=\fP\fP" Sets the MSS of the socket after connection has been established to [int]\&. .IP "\fB\f(CWnodelay\fP\fP" Turns off the Nagle algorithm for measuring the RTT (round trip time)\&. .IP "\fB\f(CWrfc1323\fP\fP" Enables RFC1323 TCP options: TCP window scale, round\-trip time measurement (RTTM), and protect against wrapped sequence numbers (PAWS) (AIX)\&. .IP "\fB\f(CWstdurg\fP\fP" Enables RFC1122 compliant urgent pointer handling (AIX)\&. .IP "\fB\f(CWsyncnt=\fP\fP" Sets the maximal number of SYN retransmits during connect to [int]\&. .IP "\fB\f(CWmd5sig\fP\fP" Enables generation of MD5 digests on the packets (FreeBSD)\&. .IP "\fB\f(CWnoopt\fP\fP" Disables use of TCP options (FreeBSD, MacOSX)\&. .IP "\fB\f(CWnopush\fP\fP" sets the TCP_NOPUSH socket option (FreeBSD, MacOSX)\&. .IP "\fB\f(CWsack\-disable\fP\fP" Disables use the selective acknowledge feature (OpenBSD)\&. .IP "\fB\f(CWsignature\-enable\fP\fP" Enables generation of MD5 digests on the packets (OpenBSD)\&. .IP "\fB\f(CWabort\-threshold=\fP\fP" Sets the time to wait for an answer of the peer on an established connection (HP\-UX)\&. .IP "\fB\f(CWconn\-abort\-threshold=\fP\fP" Sets the time to wait for an answer of the server during the initial connect (HP\-UX)\&. .IP "\fB\f(CWkeepinit\fP\fP" Sets the time to wait for an answer of the server during connect\e() before giving up\&. Value in half seconds, default is 150 (75s) (Tru64)\&. .IP "\fB\f(CWpaws\fP\fP" Enables the \(dq\&protect against wrapped sequence numbers\(dq\& feature (Tru64)\&. .IP "\fB\f(CWsackena\fP\fP" Enables selective acknowledge (Tru64)\&. .IP "\fB\f(CWtsoptena\fP\fP" Enables the time stamp option that allows RTT recalculation on existing connections (Tru64)\&. .PP .br .PP \fI\fBSCTP option group\fP\fP .PP These options may be applied to SCTP stream sockets\&. .IP "\fB\f(CWsctp\-nodelay\fP\fP" Sets the SCTP_NODELAY socket option that disables the Nagle algorithm\&. .IP "\fB\f(CWsctp\-maxseg=\fP\fP" Sets the SCTP_MAXSEG socket option to [int]\&. This value is then proposed to the peer with the SYN or SYN/ACK packet\&. .PP .br .PP \fI\fBUDP, TCP, and SCTP option groups\fP\fP .PP Here we find options that are related to the network port mechanism and thus can be used with UDP, TCP, and SCTP client and server addresses\&. .IP "\fB\f(CWsourceport=\fP\fP" For outgoing (client) TCP and UDP connections, it sets the source using an extra \f(CWbind()\fP call\&. With TCP or UDP listen addresses, socat immediately shuts down the connection if the client does not use this sourceport (example)\&. .IP "\fB\f(CWlowport\fP\fP" Outgoing (client) TCP and UDP connections with this option use an unused random source port between 640 and 1023 incl\&. On UNIX class operating systems, this requires root privilege, and thus indicates that the client process is authorized by local root\&. TCP and UDP listen addresses with this option immediately shut down the connection if the client does not use a sourceport <= 1023\&. This mechanism can provide limited authorization under some circumstances\&. .PP .br .PP \fI\fBSOCKS option group\fP\fP .PP When using SOCKS type addresses, some socks specific options can be set\&. .IP "\fB\f(CWsocksport=\fP\fP" Overrides the default \(dq\&socks\(dq\& service or port 1080 for the socks server port with \&. .IP "\fB\f(CWsocksuser=\fP\fP" Sends the [string] in the username field to the socks server\&. Default is the actual user name ($LOGNAME or $USER) (example)\&. .PP .br .PP \fI\fBHTTP option group\fP\fP .PP Options that can be provided with HTTP type addresses\&. The only HTTP address currently implemented is proxy\-connect\&. .PP .IP "\fB\f(CWproxyport=\fP\fP" Overrides the default HTTP proxy port 8080 with \&. .IP "\fB\f(CWignorecr\fP\fP" The HTTP protocol requires the use of CR+NL as line terminator\&. When a proxy server violates this standard, socat might not understand its answer\&. This option directs socat to interprete NL as line terminator and to ignore CR in the answer\&. Nevertheless, socat sends CR+NL to the proxy\&. .IP "\fB\f(CWproxyauth=:\fP\fP" Provide \(dq\&basic\(dq\& authentication to the proxy server\&. The argument to the option is used with a \(dq\&Proxy\-Authorization: Base\(dq\& header in base64 encoded form\&. .br Note: username and password are visible for every user on the local machine in the process list; username and password are transferred to the proxy server unencrypted (base64 encoded) and might be sniffed\&. .IP "\fB\f(CWresolve\fP\fP" Per default, socat sends to the proxy a CONNECT request containing the target hostname\&. With this option, socat resolves the hostname locally and sends the IP address\&. Please note that, according to RFC 2396, only name resolution to IPv4 addresses is implemented\&. .PP .br .PP \fI\fBRANGE option group\fP\fP .PP These options check if a connecting client should be granted access\&. They can be applied to listening and receiving network sockets\&. tcp\-wrappers options fall into this group\&. .IP "\fB\f(CWrange=\fP\fP" After accepting a connection, tests if the peer is within \fIrange\fP\&. For IPv4 addresses, address\-range takes the form address/bits, e\&.g\&. 10\&.0\&.0\&.0/8, or address:mask, e\&.g\&. 10\&.0\&.0\&.0:255\&.0\&.0\&.0 (example); for IPv6, it is [ip6\-address/bits], e\&.g\&. [::1/128]\&. If the client address does not match, \fBsocat\fP issues a warning and keeps listening/receiving\&. .IP "\fB\f(CWtcpwrap[=]\fP\fP" Uses Wietse Venema\(cq\&s libwrap (tcpd) library to determine if the client is allowed to connect\&. The configuration files are /etc/hosts\&.allow and /etc/hosts\&.deny per default, see \(dq\&man 5 hosts_access\(dq\& for more information\&. The optional (type string) is passed to the wrapper functions as daemon process name (example)\&. If omitted, the basename of socats invocation (argv[0]) is passed\&. If both tcpwrap and range options are applied to an address, both conditions must be fulfilled to allow the connection\&. .IP "\fB\f(CWallow\-table=\fP\fP" Takes the specified file instead of /etc/hosts\&.allow\&. .IP "\fB\f(CWdeny\-table=\fP\fP" Takes the specified file instead of /etc/hosts\&.deny\&. .IP "\fB\f(CWtcpwrap\-etc=\fP\fP" Looks for hosts\&.allow and hosts\&.deny in the specified directory\&. Is overridden by options hosts\-allow and hosts\-deny\&. .PP .br .PP \fI\fBLISTEN option group\fP\fP .PP Options specific to listening sockets\&. .IP "\fB\f(CWbacklog=\fP\fP" Sets the backlog value passed with the \f(CWlisten()\fP system call to [int]\&. Default is 5\&. .IP "\fB\f(CWmax\-children=\fP\fP" Limits the number of concurrent child processes [int]\&. Default is no limit\&. .br .PP \fI\fBCHILD option group\fP\fP .PP Options for addresses with multiple connections via child processes\&. .IP "\fB\f(CWfork\fP\fP" After establishing a connection, handles its channel in a child process and keeps the parent process attempting to produce more connections, either by listening or by connecting in a loop (example)\&. .br SSL\-CONNECT and SSL\-LISTEN differ in when they actually fork off the child: SSL\-LISTEN forks \fIbefore\fP the SSL handshake, while SSL\-CONNECT forks \fIafterwards\fP\&. RETRY and FOREVER options are not inherited by the child process\&. .br On some operating systems (e\&.g\&. FreeBSD) this option does not work for UDP\-LISTEN addresses\&. .br .PP .br .PP \fI\fBEXEC option group\fP\fP .PP Options for addresses that invoke a program\&. .IP "\fB\f(CWpath=\fP\fP" Overrides the PATH environment variable for searching the program with \&. This \f(CW$PATH\fP value is effective in the child process too\&. .IP "\fB\f(CWlogin\fP\fP" Prefixes \f(CWargv[0]\fP for the \f(CWexecvp()\fP call with \(cq\&\-\(cq\&, thus making a shell behave as login shell\&. .PP .br .PP \fI\fBFORK option group\fP\fP .PP EXEC or SYSTEM addresses invoke a program using a child process and transfer data between \fBsocat\fP and the program\&. The interprocess communication mechanism can be influenced with the following options\&. Per default, a \f(CWsocketpair()\fP is created and assigned to stdin and stdout of the child process, while stderr is inherited from the \fBsocat\fP process, and the child process uses file descriptors 0 and 1 for communicating with the main socat process\&. .IP "\fB\f(CWnofork\fP\fP" Does not fork a subprocess for executing the program, instead calls execvp\e() or system\e() directly from the actual socat instance\&. This avoids the overhead of another process between the program and its peer, but introduces a lot of restrictions: .IP o this option can only be applied to the second \fBsocat\fP address\&. .IP o it cannot be applied to a part of a dual address\&. .IP o the first socat address cannot be OPENSSL or READLINE .IP o socat options \-b, \-t, \-D, \-l, \-v, \-x become useless .IP o for both addresses, options ignoreeof, cr, and crnl become useless .IP o for the second address (the one with option nofork), options append, cloexec, flock, user, group, mode, nonblock, perm\-late, setlk, and setpgid cannot be applied\&. Some of these could be used on the first address though\&. .IP "\fB\f(CWpipes\fP\fP" Creates a pair of unnamed pipes for interprocess communication instead of a socket pair\&. .IP "\fB\f(CWopenpty\fP\fP" Establishes communication with the sub process using a pseudo terminal created with \f(CWopenpty()\fP instead of the default (socketpair or ptmx)\&. .IP "\fB\f(CWptmx\fP\fP" Establishes communication with the sub process using a pseudo terminal created by opening \fB/dev/ptmx\fP or \fB/dev/ptc\fP instead of the default (socketpair)\&. .IP "\fB\f(CWpty\fP\fP" Establishes communication with the sub process using a pseudo terminal instead of a socket pair\&. Creates the pty with an available mechanism\&. If openpty and ptmx are both available, it uses ptmx because this is POSIX compliant (example)\&. .IP "\fB\f(CWctty\fP\fP" Makes the pty the controlling tty of the sub process (example)\&. .IP "\fB\f(CWstderr\fP\fP" Directs stderr of the sub process to its output channel by making stderr a \f(CWdup()\fP of stdout (example)\&. .IP "\fB\f(CWfdin=\fP\fP" Assigns the sub processes input channel to its file descriptor instead of stdin (0)\&. The program started from the subprocess has to use this fd for reading data from \fBsocat\fP (example)\&. .IP "\fB\f(CWfdout=\fP\fP" Assigns the sub processes output channel to its file descriptor instead of stdout (1)\&. The program started from the subprocess has to use this fd for writing data to \fBsocat\fP (example)\&. .IP "\fB\f(CWsighup\fP\fP, \fB\f(CWsigint\fP\fP, \fB\f(CWsigquit\fP\fP" Has \fBsocat\fP pass signals of this type to the sub process\&. If no address has this option, socat terminates on these signals\&. .PP .br .PP \fI\fBTERMIOS option group\fP\fP .PP For addresses that work on a tty (e\&.g\&., stdio, file:/dev/tty, exec:\&.\&.\&.,pty), the terminal parameters defined in the UN*X termios mechanism are made available as address option parameters\&. Please note that changes of the parameters of your interactive terminal remain effective after \fBsocat\fP\(cq\&s termination, so you might have to enter \(dq\&reset\(dq\& or \(dq\&stty sane\(dq\& in your shell afterwards\&. For EXEC and SYSTEM addresses with option PTY, these options apply to the pty by the child processes\&. .PP .IP "\fB\f(CWb0\fP\fP" Disconnects the terminal\&. .IP "\fB\f(CWb19200\fP\fP" Sets the serial line speed to 19200 baud\&. Some other rates are possible; use something like \f(CWsocat \-hh |grep \(cq\& b[1\-9]\(cq\&\fP to find all speeds supported by your implementation\&. .br Note: On some operating systems, these options may not be available\&. Use ispeed or ospeed instead\&. .IP "\fB\f(CWecho=\fP\fP" Enables or disables local echo\&. .IP "\fB\f(CWicanon=\fP\fP" Sets or clears canonical mode, enabling line buffering and some special characters\&. .IP "\fB\f(CWraw\fP\fP" Sets raw mode, thus passing input and output almost unprocessed\&. This option is obsolete, use option rawer or cfmakeraw instead\&. .IP "\fB\f(CWrawer\fP\fP" Makes terminal rawer than raw option\&. This option implicitly turns off echo\&. (example)\&. .IP "\fB\f(CWcfmakeraw\fP\fP" Sets raw mode by invoking \f(CWcfmakeraw()\fP or by simulating this call\&. This option implicitly turns off echo\&. .IP "\fB\f(CWignbrk=\fP\fP" Ignores or interpretes the BREAK character (e\&.g\&., ^C) .IP "\fB\f(CWbrkint=\fP\fP" .IP "\fB\f(CWbs0\fP\fP" .IP "\fB\f(CWbs1\fP\fP" .IP "\fB\f(CWbsdly=<0|1>\fP\fP" .IP "\fB\f(CWclocal=\fP\fP" .IP \.LP \.nf \fBcr0 cr1 cr2 cr3\fP \.fi \.IP Sets the carriage return delay to 0, 1, 2, or 3, respectively\&. 0 means no delay, the other values are terminal dependent\&. .IP .IP "\fB\f(CWcrdly=<0|1|2|3>\fP\fP" .IP "\fB\f(CWcread=\fP\fP" .IP "\fB\f(CWcrtscts=\fP\fP" .IP \.LP \.nf \fBcs5 cs6 cs7 cs8\fP \.fi \.IP Sets the character size to 5, 6, 7, or 8 bits, respectively\&. .IP .IP "\fB\f(CWcsize=<0|1|2|3>\fP\fP" .IP "\fB\f(CWcstopb=\fP\fP" Sets two stop bits, rather than one\&. .IP "\fB\f(CWdsusp=\fP\fP" Sets the value for the VDSUSP character that suspends the current foreground process and reactivates the shell (all except Linux)\&. .IP "\fB\f(CWechoctl=\fP\fP" Echos control characters in hat notation (e\&.g\&. ^A) .IP "\fB\f(CWechoe=\fP\fP" .IP "\fB\f(CWechok=\fP\fP" .IP "\fB\f(CWechoke=\fP\fP" .IP "\fB\f(CWechonl=\fP\fP" .IP "\fB\f(CWechoprt=\fP\fP" .IP "\fB\f(CWeof=\fP\fP" .IP "\fB\f(CWeol=\fP\fP" .IP "\fB\f(CWeol2=\fP\fP" .IP "\fB\f(CWerase=\fP\fP" .IP "\fB\f(CWdiscard=\fP\fP" .IP "\fB\f(CWff0\fP\fP" .IP "\fB\f(CWff1\fP\fP" .IP "\fB\f(CWffdly=\fP\fP" .IP "\fB\f(CWflusho=\fP\fP" .IP "\fB\f(CWhupcl=\fP\fP" .IP "\fB\f(CWicrnl=\fP\fP" .IP "\fB\f(CWiexten=\fP\fP" .IP "\fB\f(CWigncr=\fP\fP" .IP "\fB\f(CWignpar=\fP\fP" .IP "\fB\f(CWimaxbel=\fP\fP" .IP "\fB\f(CWinlcr=\fP\fP" .IP "\fB\f(CWinpck=\fP\fP" .IP "\fB\f(CWintr=\fP\fP" .IP "\fB\f(CWisig=\fP\fP" .IP "\fB\f(CWispeed=\fP\fP" Set the baud rate for incoming data on this line\&. .br See also: ospeed, b19200 .IP "\fB\f(CWistrip=\fP\fP" .IP "\fB\f(CWiuclc=\fP\fP" .IP "\fB\f(CWixany=\fP\fP" .IP "\fB\f(CWixoff=\fP\fP" .IP "\fB\f(CWixon=\fP\fP" .IP "\fB\f(CWkill=\fP\fP" .IP "\fB\f(CWlnext=\fP\fP" .IP "\fB\f(CWmin=\fP\fP" .IP "\fB\f(CWnl0\fP\fP" Sets the newline delay to 0\&. .IP "\fB\f(CWnl1\fP\fP" .IP "\fB\f(CWnldly=\fP\fP" .IP "\fB\f(CWnoflsh=\fP\fP" .IP "\fB\f(CWocrnl=\fP\fP" .IP "\fB\f(CWofdel=\fP\fP" .IP "\fB\f(CWofill=\fP\fP" .IP "\fB\f(CWolcuc=\fP\fP" .IP "\fB\f(CWonlcr=\fP\fP" .IP "\fB\f(CWonlret=\fP\fP" .IP "\fB\f(CWonocr=\fP\fP" .IP "\fB\f(CWopost=\fP\fP" Enables or disables output processing; e\&.g\&., converts NL to CR\-NL\&. .IP "\fB\f(CWospeed=\fP\fP" Set the baud rate for outgoing data on this line\&. .br See also: ispeed, b19200 .IP "\fB\f(CWparenb=\fP\fP" Enable parity generation on output and parity checking for input\&. .IP "\fB\f(CWparmrk=\fP\fP" .IP "\fB\f(CWparodd=\fP\fP" .IP "\fB\f(CWpendin=\fP\fP" .IP "\fB\f(CWquit=\fP\fP" .IP "\fB\f(CWreprint=\fP\fP" .IP "\fB\f(CWsane\fP\fP" Brings the terminal to something like a useful default state\&. .IP "\fB\f(CWstart=\fP\fP" .IP "\fB\f(CWstop=\fP\fP" .IP "\fB\f(CWsusp=\fP\fP" .IP "\fB\f(CWswtc=\fP\fP" .IP "\fB\f(CWtab0\fP\fP" .IP "\fB\f(CWtab1\fP\fP" .IP "\fB\f(CWtab2\fP\fP" .IP "\fB\f(CWtab3\fP\fP" .IP "\fB\f(CWtabdly=\fP\fP" .IP "\fB\f(CWtime=\fP\fP" .IP "\fB\f(CWtostop=\fP\fP" .IP "\fB\f(CWvt0\fP\fP" .IP "\fB\f(CWvt1\fP\fP" .IP "\fB\f(CWvtdly=\fP\fP" .IP "\fB\f(CWwerase=\fP\fP" .IP "\fB\f(CWxcase=\fP\fP" .IP "\fB\f(CWxtabs\fP\fP" .IP "\fB\f(CWi\-pop\-all\fP\fP" With UNIX System V STREAMS, removes all drivers from the stack\&. .IP "\fB\f(CWi\-push=\fP\fP" With UNIX System V STREAMS, pushes the driver (module) with the given name (string) onto the stack\&. For example, to make sure that a character device on Solaris supports termios etc, use the following options: \f(CWi\-pop\-all,i\-push=ptem,i\-push=ldterm,i\-push=ttcompat\fP .PP .br .PP \fI\fBPTY option group\fP\fP .PP These options are intended for use with the pty address type\&. .PP .IP "\fB\f(CWlink=\fP\fP" Generates a symbolic link that points to the actual pseudo terminal (pty)\&. This might help to solve the problem that ptys are generated with more or less unpredictable names, making it difficult to directly access the socat generated pty automatically\&. With this option, the user can specify a \(dq\&fix\(dq\& point in the file hierarchy that helps him to access the actual pty (example)\&. Beginning with \fBsocat\fP version 1\&.4\&.3, the symbolic link is removed when the address is closed (but see option unlink\-close)\&. .IP "\fB\f(CWwait\-slave\fP\fP" Blocks the open phase until a process opens the slave side of the pty\&. Usually, socat continues after generating the pty with opening the next address or with entering the transfer loop\&. With the wait\-slave option, socat waits until some process opens the slave side of the pty before continuing\&. This option only works if the operating system provides the \f(CWpoll()\fP system call\&. And it depends on an undocumented behaviour of pty\(cq\&s, so it does not work on all operating systems\&. It has successfully been tested on Linux, FreeBSD, NetBSD, and on Tru64 with openpty\&. .IP "\fB\f(CWpty\-interval=\fP\fP" When the wait\-slave option is set, socat periodically checks the HUP condition using \f(CWpoll()\fP to find if the pty\(cq\&s slave side has been opened\&. The default polling interval is 1s\&. Use the pty\-interval option [timeval] to change this value\&. .PP .br .PP \fI\fBOPENSSL option group\fP\fP .PP These options apply to the openssl and openssl\-listen address types\&. .PP .IP "\fB\f(CWcipher=\fP\fP" Selects the list of ciphers that may be used for the connection\&. See the man page of \f(CWciphers\fP , section \fBCIPHER LIST FORMAT\fP, for detailed information about syntax, values, and default of \&. .br Several cipher strings may be given, separated by \(cq\&:\(cq\&\&. Some simple cipher strings: .IP "3DES" Uses a cipher suite with triple DES\&. .IP "MD5" Uses a cipher suite with MD5\&. .IP "aNULL" Uses a cipher suite without authentication\&. .IP "NULL" Does not use encryption\&. .IP "HIGH" Uses a cipher suite with \(dq\&high\(dq\& encryption\&. Note that the peer must support the selected property, or the negotiation will fail\&. .IP "\fB\f(CWmethod=\fP\fP" Sets the protocol version to be used\&. Valid strings (not case sensitive) are: .IP "\f(CWSSL2\fP" Select SSL protocol version 2\&. .IP "\f(CWSSL3\fP" Select SSL protocol version 3\&. .IP "\f(CWSSL23\fP" Select the best available SSL or TLS protocol\&. This is the default when this option is not provided\&. .IP "\f(CWTLS1\fP" Select TLS protocol version 1\&. .IP "\f(CWTLS1\&.1\fP" Select TLS protocol version 1\&.1\&. .IP "\f(CWTLS1\&.2\fP" Select TLS protocol version 1\&.2\&. .IP "\f(CWDTLS1\fP" Select DTLS protocol version 1\&. .IP "\fB\f(CWverify=\fP\fP" Controls check of the peer\(cq\&s certificate\&. Default is 1 (true)\&. Disabling verify might open your socket for everyone, making the encryption useless! .IP "\fB\f(CWcert=\fP\fP" Specifies the file with the certificate and private key for authentication\&. The certificate must be in OpenSSL format (*\&.pem)\&. With openssl\-listen, use of this option is strongly recommended\&. Except with cipher aNULL, \(dq\&no shared ciphers\(dq\& error will occur when no certificate is given\&. .IP "\fB\f(CWkey=\fP\fP" Specifies the file with the private key\&. The private key may be in this file or in the file given with the cert option\&. The party that has to proof that it is the owner of a certificate needs the private key\&. .IP "\fB\f(CWdhparams=\fP\fP" Specifies the file with the Diffie Hellman parameters\&. These parameters may also be in the file given with the cert option in which case the dhparams option is not needed\&. .IP "\fB\f(CWcafile=\fP\fP" Specifies the file with the trusted (root) authority certificates\&. The file must be in PEM format and should contain one or more certificates\&. The party that checks the authentication of its peer trusts only certificates that are in this file\&. .IP "\fB\f(CWcapath=\fP\fP" Specifies the directory with the trusted (root) certificates\&. The directory must contain certificates in PEM format and their hashes (see OpenSSL documentation) .IP "\fB\f(CWegd=\fP\fP" On some systems, openssl requires an explicit source of random data\&. Specify the socket name where an entropy gathering daemon like egd provides random data, e\&.g\&. /dev/egd\-pool\&. .IP "\fB\f(CWpseudo\fP\fP" On systems where openssl cannot find an entropy source and where no entropy gathering daemon can be utilized, this option activates a mechanism for providing pseudo entropy\&. This is archieved by taking the current time in microseconds for feeding the libc pseudo random number generator with an initial value\&. openssl is then feeded with output from random\e() calls\&. .br NOTE:This mechanism is not sufficient for generation of secure keys! .IP "\fB\f(CWcompress\fP\fP" Enable or disable the use of compression for a connection\&. Setting this to \(dq\&none\(dq\& disables compression, setting it to \(dq\&auto\(dq\& lets OpenSSL choose the best available algorithm supported by both parties\&. The default is to not touch any compression\-related settings\&. NOTE: Requires OpenSSL 0\&.9\&.8 or higher and disabling compression with OpenSSL 0\&.9\&.8 affects all new connections in the process\&. .IP "\fB\f(CWcommonname=\fP\fP" Specify the commonname that the peer certificate must match\&. With OPENSSL\-CONNECT address this overrides the given hostname or IP target address; with OPENSSL\-LISTEN this turns on check of peer certificates commonname\&. This option has only meaning when option verify is not disabled and the choosen cipher provides a peer certificate\&. .IP "\fB\f(CWfips\fP\fP" Enables FIPS mode if compiled in\&. For info about the FIPS encryption implementation standard see http://oss\-institute\&.org/fips\-faq\&.html\&. This mode might require that the involved certificates are generated with a FIPS enabled version of openssl\&. Setting or clearing this option on one socat address affects all OpenSSL addresses of this process\&. .PP .br .PP \fI\fBRETRY option group\fP\fP .PP Options that control retry of some system calls, especially connection attempts\&. .PP .IP "\fB\f(CWretry=\fP\fP" Number of retries before the connection or listen attempt is aborted\&. Default is 0, which means just one attempt\&. .IP "\fB\f(CWinterval=\fP\fP" Time between consecutive attempts (seconds, [timespec])\&. Default is 1 second\&. .IP "\fB\f(CWforever\fP\fP" Performs an unlimited number of retry attempts\&. .PP .br .PP \fI\fBTUN option group\fP\fP .PP Options that control Linux TUN/TAP interface device addresses\&. .PP .IP "\fB\f(CWtun\-device=\fP\fP" Instructs socat to take another path for the TUN clone device\&. Default is \f(CW/dev/net/tun\fP\&. .IP "\fB\f(CWtun\-name=\fP\fP" Gives the resulting network interface a specific name instead of the system generated (tun0, tun1, etc\&.) .IP "\fB\f(CWtun\-type=[tun|tap]\fP\fP" Sets the type of the TUN device; use this option to generate a TAP device\&. See the Linux docu for the difference between these types\&. When you try to establish a tunnel between two TUN devices, their types should be the same\&. .IP "\fB\f(CWiff\-no\-pi\fP\fP" Sets the IFF_NO_PI flag which controls if the device includes additional packet information in the tunnel\&. When you try to establish a tunnel between two TUN devices, these flags should have the same values\&. .IP "\fB\f(CWiff\-up\fP\fP" Sets the TUN network interface status UP\&. Strongly recommended\&. .IP "\fB\f(CWiff\-broadcast\fP\fP" Sets the BROADCAST flag of the TUN network interface\&. .IP "\fB\f(CWiff\-debug\fP\fP" Sets the DEBUG flag of the TUN network interface\&. .IP "\fB\f(CWiff\-loopback\fP\fP" Sets the LOOPBACK flag of the TUN network interface\&. .IP "\fB\f(CWiff\-pointopoint\fP\fP" Sets the POINTOPOINT flag of the TUN device\&. .IP "\fB\f(CWiff\-notrailers\fP\fP" Sets the NOTRAILERS flag of the TUN device\&. .IP "\fB\f(CWiff\-running\fP\fP" Sets the RUNNING flag of the TUN device\&. .IP "\fB\f(CWiff\-noarp\fP\fP" Sets the NOARP flag of the TUN device\&. .IP "\fB\f(CWiff\-promisc\fP\fP" Sets the PROMISC flag of the TUN device\&. .IP "\fB\f(CWiff\-allmulti\fP\fP" Sets the ALLMULTI flag of the TUN device\&. .IP "\fB\f(CWiff\-master\fP\fP" Sets the MASTER flag of the TUN device\&. .IP "\fB\f(CWiff\-slave\fP\fP" Sets the SLAVE flag of the TUN device\&. .IP "\fB\f(CWiff\-multicast\fP\fP" Sets the MULTICAST flag of the TUN device\&. .IP "\fB\f(CWiff\-portsel\fP\fP" Sets the PORTSEL flag of the TUN device\&. .IP "\fB\f(CWiff\-automedia\fP\fP" Sets the AUTOMEDIA flag of the TUN device\&. .IP "\fB\f(CWiff\-dynamic\fP\fP" Sets the DYNAMIC flag of the TUN device\&. .PP .br .PP .SH "DATA VALUES" .PP This section explains the different data types that address parameters and address options can take\&. .PP .IP "address\-range" Is currently only implemented for IPv4 and IPv6\&. See address\-option `range\(cq\& .IP "bool" \(dq\&0\(dq\& or \(dq\&1\(dq\&; if value is omitted, \(dq\&1\(dq\& is taken\&. .IP "byte" An unsigned int number, read with \f(CWstrtoul()\fP , lower or equal to \f(CWUCHAR_MAX\fP \&. .IP "command\-line" A string specifying a program name and its arguments, separated by single spaces\&. .IP "data" A raw data specification following \fIdalan\fP syntax\&. Currently the only valid form is a string starting with \(cq\&x\(cq\& followed by an even number of hex digits, specifying a sequence of bytes\&. .IP "directory" A string with usual UN*X directory name semantics\&. .IP "facility" The name of a syslog facility in lower case characters\&. .IP "fdnum" An unsigned int type, read with \f(CWstrtoul()\fP , specifying a UN*X file descriptor\&. .IP "filename" A string with usual UN*X filename semantics\&. .IP "group" If the first character is a decimal digit, the value is read with \f(CWstrtoul()\fP as unsigned integer specifying a group id\&. Otherwise, it must be an existing group name\&. .IP "int" A number following the rules of the \f(CWstrtol()\fP function with base \(dq\&0\(dq\&, i\&.e\&. decimal number, octal number with leading \(dq\&0\(dq\&, or hexadecimal number with leading \(dq\&0x\(dq\&\&. The value must fit into a C int\&. .IP "interface" A string specifying the device name of a network interface as shown by ifconfig or procan, e\&.g\&. \(dq\ð0\(dq\&\&. .IP "IP address" An IPv4 address in numbers\-and\-dots notation, an IPv6 address in hex notation enclosed in brackets, or a hostname that resolves to an IPv4 or an IPv6 address\&. .br Examples: 127\&.0\&.0\&.1, [::1], www\&.dest\-unreach\&.org, dns1 .IP "IPv4 address" An IPv4 address in numbers\-and\-dots notation or a hostname that resolves to an IPv4 address\&. .br Examples: 127\&.0\&.0\&.1, www\&.dest\-unreach\&.org, dns2 .IP "IPv6 address" An iPv6 address in hexnumbers\-and\-colons notation enclosed in brackets, or a hostname that resolves to an IPv6 address\&. .br Examples: [::1], [1234:5678:9abc:def0:1234:5678:9abc:def0], ip6name\&.domain\&.org .IP "long" A number read with \f(CWstrtol()\fP \&. The value must fit into a C long\&. .IP "long long" A number read with \f(CWstrtoll()\fP \&. The value must fit into a C long long\&. .IP "off_t" An implementation dependend signed number, usually 32 bits, read with strtol or strtoll\&. .IP "off64_t" An implementation dependend signed number, usually 64 bits, read with strtol or strtoll\&. .IP "mode_t" An unsigned integer, read with \f(CWstrtoul()\fP , specifying mode (permission) bits\&. .IP "pid_t" A number, read with \f(CWstrtol()\fP , specifying a process id\&. .IP "port" A uint16_t (16 bit unsigned number) specifying a TCP or UDP port, read with \f(CWstrtoul()\fP \&. .IP "protocol" An unsigned 8 bit number, read with \f(CWstrtoul()\fP \&. .IP "size_t" An unsigned number with size_t limitations, read with \f(CWstrtoul\fP \&. .IP "sockname" A socket address\&. See address\-option `bind\(cq\& .IP "string" A sequence of characters, not containing \(cq\&\e0\(cq\& and, depending on the position within the command line, \(cq\&:\(cq\&, \(cq\&,\(cq\&, or \(dq\&!!\(dq\&\&. Note that you might have to escape shell meta characters in the command line\&. .IP "TCP service" A service name, not starting with a digit, that is resolved by \f(CWgetservbyname()\fP , or an unsigned int 16 bit number read with \f(CWstrtoul()\fP \&. .IP "timeval" A double float specifying seconds; the number is mapped into a struct timeval, consisting of seconds and microseconds\&. .IP "timespec" A double float specifying seconds; the number is mapped into a struct timespec, consisting of seconds and nanoseconds\&. .IP "UDP service" A service name, not starting with a digit, that is resolved by \f(CWgetservbyname()\fP , or an unsigned int 16 bit number read with \f(CWstrtoul()\fP \&. .IP "unsigned int" A number read with \f(CWstrtoul()\fP \&. The value must fit into a C unsigned int\&. .IP "user" If the first character is a decimal digit, the value is read with \f(CWstrtoul()\fP as unsigned integer specifying a user id\&. Otherwise, it must be an existing user name\&. .PP .SH "EXAMPLES" .PP .IP "\fB\f(CWsocat \- TCP4:www\&.domain\&.org:80\fP\fP" .IP transfers data between STDIO (\-) and a TCP4 connection to port 80 of host www\&.domain\&.org\&. This example results in an interactive connection similar to telnet or netcat\&. The stdin terminal parameters are not changed, so you may close the relay with ^D or abort it with ^C\&. .IP \.LP \.nf \fBsocat -d -d READLINE,history=$HOME/.http_history \\ TCP4:www.domain.org:www,crnl\fP \.fi .IP this is similar to the previous example, but you can edit the current line in a bash like manner (READLINE) and use the history file \&.http_history; \fBsocat\fP prints messages about progress (\-d \-d)\&. The port is specified by service name (www), and correct network line termination characters (crnl) instead of NL are used\&. .IP .IP "\fB\f(CWsocat TCP4\-LISTEN:www TCP4:www\&.domain\&.org:www\fP\fP" .IP installs a simple TCP port forwarder\&. With TCP4\-LISTEN it listens on local port \(dq\&www\(dq\& until a connection comes in, accepts it, then connects to the remote host (TCP4) and starts data transfer\&. It will not accept a econd connection\&. .IP \.LP \.nf \fBsocat -d -d -lmlocal2 \\ TCP4-LISTEN:80,bind=myaddr1,reuseaddr,fork,su=nobody,range=10.0.0.0/8 \\ TCP4:www.domain.org:80,bind=myaddr2\fP \.fi .IP TCP port forwarder, each side bound to another local IP address (bind)\&. This example handles an almost arbitrary number of parallel or consecutive connections by fork\(cq\&ing a new process after each \f(CWaccept()\fP \&. It provides a little security by su\(cq\&ing to user nobody after forking; it only permits connections from the private 10 network (range); due to reuseaddr, it allows immediate restart after master process\(cq\&s termination, even if some child sockets are not completely shut down\&. With \-lmlocal2, socat logs to stderr until successfully reaching the accept loop\&. Further logging is directed to syslog with facility local2\&. .IP \.LP \.nf \fBsocat TCP4-LISTEN:5555,fork,tcpwrap=script \\ EXEC:/bin/myscript,chroot=/home/sandbox,su-d=sandbox,pty,stderr\fP \.fi .IP a simple server that accepts connections (TCP4\-LISTEN) and fork\(cq\&s a new child process for each connection; every child acts as single relay\&. The client must match the rules for daemon process name \(dq\&script\(dq\& in /etc/hosts\&.allow and /etc/hosts\&.deny, otherwise it is refused access (see \(dq\&man 5 hosts_access\(dq\&)\&. For EXEC\(cq\&uting the program, the child process chroot\(cq\&s to \fB/home/sandbox\fP, su\(cq\&s to user sandbox, and then starts the program \fB/home/sandbox/bin/myscript\fP\&. \fBSocat\fP and myscript communicate via a pseudo tty (pty); myscript\(cq\&s stderr is redirected to stdout, so its error messages are transferred via \fBsocat\fP to the connected client\&. .IP \.LP \.nf \fBsocat EXEC:"mail.sh target@domain.com",fdin=3,fdout=4 \\ TCP4:mail.relay.org:25,crnl,bind=alias1.server.org,mss=512\fP \.fi .IP \fBmail\&.sh\fP is a shell script, distributed with \fBsocat\fP, that implements a simple SMTP client\&. It is programmed to \(dq\&speak\(dq\& SMTP on its FDs 3 (in) and 4 (out)\&. The fdin and fdout options tell \fBsocat\fP to use these FDs for communication with the program\&. Because mail\&.sh inherits stdin and stdout while \fBsocat\fP does not use them, the script can read a mail body from stdin\&. \fBSocat\fP makes alias1 your local source address (bind), cares for correct network line termination (crnl) and sends at most 512 data bytes per packet (mss)\&. .IP .IP "\fB\f(CWsocat \-,escape=0x0f /dev/ttyS0,rawer,crnl\fP\fP" .IP opens an interactive connection via the serial line, e\&.g\&. for talking with a modem\&. rawer sets the console\(cq\&s and ttyS0\(cq\&s terminal parameters to practicable values, crnl converts to correct newline characters\&. escape allows to terminate the socat process with character control\-O\&. Consider using READLINE instead of the first address\&. .IP \.LP \.nf \fBsocat UNIX-LISTEN:/tmp/.X11-unix/X1,fork \\ SOCKS4:host.victim.org:127.0.0.1:6000,socksuser=nobody,sourceport=20\fP \.fi .IP with UNIX\-LISTEN, \fBsocat\fP opens a listening UNIX domain socket \fB/tmp/\&.X11\-unix/X1\fP\&. This path corresponds to local XWindow display :1 on your machine, so XWindow client connections to DISPLAY=:1 are accepted\&. \fBSocat\fP then speaks with the SOCKS4 server host\&.victim\&.org that might permit sourceport 20 based connections due to an FTP related weakness in its static IP filters\&. \fBSocat\fP pretends to be invoked by socksuser nobody, and requests to be connected to loopback port 6000 (only weak sockd configurations will allow this)\&. So we get a connection to the victims XWindow server and, if it does not require MIT cookies or Kerberos authentication, we can start work\&. Please note that there can only be one connection at a time, because TCP can establish only one session with a given set of addresses and ports\&. .IP .IP "\fB\f(CWsocat \-u /tmp/readdata,seek\-end=0,ignoreeof \-\fP\fP" .IP this is an example for unidirectional data transfer (\-u)\&. \fBSocat\fP transfers data from file /tmp/readdata (implicit address GOPEN), starting at its current end (seek\-end=0 lets \fBsocat\fP start reading at current end of file; use seek=0 or no seek option to first read the existing data) in a \(dq\&tail \-f\(dq\& like mode (ignoreeof)\&. The \(dq\&file\(dq\& might also be a listening UNIX domain socket (do not use a seek option then)\&. .IP \.LP \.nf \fB(sleep 5; echo PASSWORD; sleep 5; echo ls; sleep 1) | socat - EXEC:'ssh -l user server',pty,setsid,ctty\fP \.fi .IP EXEC\(cq\&utes an ssh session to server\&. Uses a pty for communication between \fBsocat\fP and ssh, makes it ssh\(cq\&s controlling tty (ctty), and makes this pty the owner of a new process group (setsid), so ssh accepts the password from \fBsocat\fP\&. .IP \.LP \.nf \fBsocat -u TCP4-LISTEN:3334,reuseaddr,fork \\ OPEN:/tmp/in.log,creat,append\fP \.fi .IP implements a simple network based message collector\&. For each client connecting to port 3334, a new child process is generated (option fork)\&. All data sent by the clients are append\(cq\&ed to the file /tmp/in\&.log\&. If the file does not exist, socat creat\(cq\&s it\&. Option reuseaddr allows immediate restart of the server process\&. .IP .IP "\fB\f(CWsocat READLINE,noecho=\(cq\&[Pp]assword:\(cq\& EXEC:\(cq\&ftp ftp\&.server\&.com\(cq\&,pty,setsid,ctty\fP\fP" .IP wraps a command line history (READLINE) around the EXEC\(cq\&uted ftp client utility\&. This allows editing and reuse of FTP commands for relatively comfortable browsing through the ftp directory hierarchy\&. The password is echoed! pty is required to have ftp issue a prompt\&. Nevertheless, there may occur some confusion with the password and FTP prompts\&. .IP \.LP \.nf \fBsocat PTY,link=$HOME/dev/vmodem0,rawer,wait-slave \\\bf \fBEXEC:"ssh modemserver.us.org socat - /dev/ttyS0,nonblock,rawer"\fP \.fi .IP generates a pseudo terminal device (PTY) on the client that can be reached under the symbolic link \fB$HOME/dev/vmodem0\fP\&. An application that expects a serial line or modem can be configured to use \fB$HOME/dev/vmodem0\fP; its traffic will be directed to a modemserver via ssh where another socat instance links it to \fB/dev/ttyS0\fP\&. .IP \.LP \.nf \fBsocat TCP4-LISTEN:2022,reuseaddr,fork \\ PROXY:proxy:www.domain.org:22,proxyport=3128,proxyauth=user:pass\fP \.fi .IP starts a forwarder that accepts connections on port 2022, and directs them through the proxy daemon listening on port 3128 (proxyport) on host proxy, using the CONNECT method, where they are authenticated as \(dq\&user\(dq\& with \(dq\&pass\(dq\& (proxyauth)\&. The proxy should establish connections to host www\&.domain\&.org on port 22 then\&. .IP .IP "\fB\f(CWsocat \- SSL:server:4443,cafile=server\&.crt,cert=client\&.pem\fP\fP" .IP is an OpenSSL client that tries to establish a secure connection to an SSL server\&. Option cafile specifies a file that contains trust certificates: we trust the server only when it presents one of these certificates and proofs that it owns the related private key\&. Otherwise the connection is terminated\&. With cert a file containing the client certificate and the associated private key is specified\&. This is required in case the server wishes a client authentication; many Internet servers do not\&. .br The first address (\(cq\&\-\(cq\&) can be replaced by almost any other socat address\&. .IP .IP "\fB\f(CWsocat SSL\-LISTEN:4443,reuseaddr,pf=ip4,fork,cert=server\&.pem,cafile=client\&.crt PIPE\fP\fP" .IP is an OpenSSL server that accepts TCP connections, presents the certificate from the file server\&.pem and forces the client to present a certificate that is verified against cafile\&.crt\&. .br The second address (\(cq\&PIPE\(cq\&) can be replaced by almost any other socat address\&. .br For instructions on generating and distributing OpenSSL keys and certificates see the additional socat docu \f(CWsocat\-openssl\&.txt\fP\&. .IP .IP "\fB\f(CWecho |socat \-u \- file:/tmp/bigfile,create,largefile,seek=100000000000\fP\fP" .IP creates a 100GB sparse file; this requires a file system type that supports this (ext2, ext3, reiserfs, jfs; not minix, vfat)\&. The operation of writing 1 byte might take long (reiserfs: some minutes; ext2: \(dq\&no\(dq\& time), and the resulting file can consume some disk space with just its inodes (reiserfs: 2MB; ext2: 16KB)\&. .IP .IP "\fB\f(CWsocat tcp\-l:7777,reuseaddr,fork system:\(cq\&filan \-i 0 \-s >&2\(cq\&,nofork\fP\fP" .IP listens for incoming TCP connections on port 7777\&. For each accepted connection, invokes a shell\&. This shell has its stdin and stdout directly connected to the TCP socket (nofork)\&. The shell starts filan and lets it print the socket addresses to stderr (your terminal window)\&. .IP .IP "\fB\f(CWecho \-e \(dq\&\e0\e14\e0\e0\ec\(dq\& |socat \-u \- file:/usr/bin/squid\&.exe,seek=0x00074420\fP\fP" .IP functions as primitive binary editor: it writes the 4 bytes 000 014 000 000 to the executable /usr/bin/squid at offset 0x00074420 (this is a real world patch to make the squid executable from Cygwin run under Windows, actual per May 2004)\&. .IP .IP "\fB\f(CWsocat \- tcp:www\&.blackhat\&.org:31337,readbytes=1000\fP\fP" .IP connects to an unknown service and prevents being flooded\&. .IP .IP "\fB\f(CWsocat \-U TCP:target:9999,end\-close TCP\-L:8888,reuseaddr,fork\fP\fP" .IP merges data arriving from different TCP streams on port 8888 to just one stream to target:9999\&. The end\-close option prevents the child processes forked off by the second address from terminating the shared connection to 9999 (close\e(2) just unlinks the inode which stays active as long as the parent process lives; shutdown\e(2) would actively terminate the connection)\&. .IP .IP "\fB\f(CWsocat \- UDP4\-DATAGRAM:192\&.168\&.1\&.0:123,sp=123,broadcast,range=192\&.168\&.1\&.0/24\fP\fP" .IP sends a broadcast to the network 192\&.168\&.1\&.0/24 and receives the replies of the timeservers there\&. Ignores NTP packets from hosts outside this network\&. .IP .IP "\fB\f(CWsocat \- SOCKET\-DATAGRAM:2:2:17:x007bxc0a80100x0000000000000000,bind=x007bx00000000x0000000000000000,setsockopt\-int=1:6:1,range=x0000xc0a80100x0000000000000000:x0000xffffff00x0000000000000000\fP\fP" .IP is semantically equivalent to the previous example, but all parameters are specified in generic form\&. the value 6 of setsockopt\-int is the Linux value for \f(CWSO_BROADCAST\fP\&. .IP .IP "\fB\f(CWsocat \- IP4\-DATAGRAM:255\&.255\&.255\&.255:44,broadcast,range=10\&.0\&.0\&.0/8\fP\fP" .IP sends a broadcast to the local network\e(s) using protocol 44\&. Accepts replies from the private address range only\&. .IP .IP "\fB\f(CWsocat \- UDP4\-DATAGRAM:224\&.255\&.0\&.1:6666,bind=:6666,ip\-add\-membership=224\&.255\&.0\&.1:eth0\fP\fP" .IP transfers data from stdin to the specified multicast address using UDP\&. Both local and remote ports are 6666\&. Tells the interface eth0 to also accept multicast packets of the given group\&. Multiple hosts on the local network can run this command, so all data sent by any of the hosts will be received by all the other ones\&. Note that there are many possible reasons for failure, including IP\-filters, routing issues, wrong interface selection by the operating system, bridges, or a badly configured switch\&. .IP .IP "\fB\f(CWsocat TCP:host2:4443 TUN:192\&.168\&.255\&.1/24,up\fP\fP" .IP establishes one side of a virtual (but not private!) network with host2 where a similar process might run, with UDP\-L and tun address 192\&.168\&.255\&.2\&. They can reach each other using the addresses 192\&.168\&.255\&.1 and 192\&.168\&.255\&.2\&. Note that streaming eg\&. via TCP or SSL does not guarantee to retain packet boundaries and may thus cause packet loss\&. .IP .IP "\fB\f(CWsocat PTY,link=/var/run/ppp,rawer INTERFACE:hdlc0\fP\fP" .IP circumvents the problem that pppd requires a serial device and thus might not be able to work on a synchronous line that is represented by a network device\&. socat creates a PTY to make pppd happy, binds to the network interface \f(CWhdlc0\fP, and can transfer data between both devices\&. Use pppd on device \f(CW/var/run/ppp\fP then\&. .IP .IP "\fB\f(CWsocat \-T 1 \-d \-d TCP\-L:10081,reuseaddr,fork,crlf SYSTEM:\(dq\&echo \-e \e\(dq\&\e\e\e\(dq\&HTTP/1\&.0 200 OK\e\e\enDocumentType: text/plain\e\e\en\e\e\endate: \e$\e(date\e)\e\e\enserver:\e$SOCAT_SOCKADDR:\e$SOCAT_SOCKPORT\e\e\enclient: \e$SOCAT_PEERADDR:\e$SOCAT_PEERPORT\e\e\en\e\e\e\(dq\&\e\(dq\&; cat; echo \-e \e\(dq\&\e\e\e\(dq\&\e\e\en\e\e\e\(dq\&\e\(dq\&\(dq\&\fP\fP" .IP creates a simple HTTP echo server: each HTTP client that connects gets a valid HTTP reply that contains information about the client address and port as it is seen by the server host, the host address (which might vary on multihomed servers), and the original client request\&. .IP .IP "\fB\f(CWsocat \-d \-d UDP4\-RECVFROM:9999,so\-broadcast,so\-timestamp,ip\-pktinfo,ip\-recverr,ip\-recvopts,ip\-recvtos,ip\-recvttl!!\- SYSTEM:\(cq\&export; sleep 1\(cq\& |grep SOCAT\fP\fP" .IP waits for an incoming UDP packet on port 9999 and prints the environment variables provided by socat\&. On BSD based systems you have to replace \f(CWip\-pktinfo\fP with \f(CWip\-recvdstaddr\fP,\f(CWip\-recvif\fP\&. Especially interesting is SOCAT_IP_DSTADDR: it contains the target address of the packet which may be a unicast, multicast, or broadcast address\&. .IP .IP "\fB\f(CW\fP\fP" .IP .SH "DIAGNOSTICS" .PP \fBSocat\fP uses a logging mechanism that allows to filter messages by severity\&. The severities provided are more or less compatible to the appropriate syslog priority\&. With one or up to four occurrences of the \-d command line option, the lowest priority of messages that are issued can be selected\&. Each message contains a single uppercase character specifying the messages severity (one of F, E, W, N, I, or D) .PP .IP "FATAL:" Conditions that require unconditional and immediate program termination\&. .IP "ERROR:" Conditions that prevent proper program processing\&. Usually the program is terminated (see option \-s)\&. .IP "WARNING:" Something did not function correctly or is in a state where correct further processing cannot be guaranteed, but might be possible\&. .IP "NOTICE:" Interesting actions of the program, e\&.g\&. for supervising \fBsocat\fP in some kind of server mode\&. .IP "INFO:" Description of what the program does, and maybe why it happens\&. Allows to monitor the lifecycles of file descriptors\&. .IP "DEBUG:" Description of how the program works, all system or library calls and their results\&. .PP Log messages can be written to stderr, to a file, or to syslog\&. .PP On exit, \fBsocat\fP gives status 0 if it terminated due to EOF or inactivity timeout, with a positive value on error, and with a negative value on fatal error\&. .PP .SH "FILES" .PP /usr/bin/socat .br /usr/bin/filan .br /usr/bin/procan .PP .SH "ENVIRONMENT VARIABLES" .PP Input variables carry information from the environment to socat, output variables are set by socat for use in executed scripts and programs\&. .PP In the output variables beginning with \(dq\&SOCAT\(dq\& this prefix is actually replaced by the upper case name of the executable or the value of option \-lp\&. .PP .IP "\fBSOCAT_DEFAULT_LISTEN_IP\fP (input)" (Values 4 or 6) Sets the IP version to be used for listen, recv, and recvfrom addresses if no pf (protocol\-family) option is given\&. Is overridden by socat options \-4 or \-6\&. .IP .IP "\fBSOCAT_PREFERRED_RESOLVE_IP\fP (input)" (Values 0, 4, or 6) Sets the IP version to be used when resolving target host names when version is not specified by address type, option pf (protocol\-family), or address format\&. If name resolution does not return a matching entry, the first result (with differing IP version) is taken\&. With value 0, socat always selects the first record and its IP version\&. .IP .IP "\fBSOCAT_FORK_WAIT\fP (input)" Specifies the time (seconds) to sleep the parent and child processes after successful fork\e()\&. Useful for debugging\&. .IP .IP "\fBSOCAT_VERSION\fP (output)" Socat sets this variable to its version string, e\&.g\&. \f(CW\(dq\&1\&.7\&.0\&.0\(dq\&\fP for released versions or e\&.g\&. \f(CW\(dq\&1\&.6\&.0\&.1+envvar\(dq\&\fP for temporary versions; can be used in scripts invoked by socat\&. .IP .IP "\fBSOCAT_PID\fP (output)" Socat sets this variable to its process id\&. In case of fork address option, SOCAT_PID gets the child processes id\&. Forking for exec and system does not change SOCAT_PID\&. .IP .IP "\fBSOCAT_PPID\fP (output)" Socat sets this variable to its process id\&. In case of fork, SOCAT_PPID keeps the pid of the master process\&. .IP .IP "\fBSOCAT_PEERADDR\fP (output)" With passive socket addresses (all LISTEN and RECVFROM addresses), this variable is set to a string describing the peers socket address\&. Port information is not included\&. .IP .IP "\fBSOCAT_PEERPORT\fP (output)" With appropriate passive socket addresses (TCP, UDP, and SCTP \- LISTEN and RECVFROM), this variable is set to a string containing the number of the peer port\&. .IP .IP "\fBSOCAT_SOCKADDR\fP (output)" With all LISTEN addresses, this variable is set to a string describing the local socket address\&. Port information is not included example .IP .IP "\fBSOCAT_SOCKPORT\fP (output)" With TCP\-LISTEN, UDP\-LISTEN, and SCTP\-LISTEN addresses, this variable is set to the local port\&. .IP .IP "\fBSOCAT_TIMESTAMP\fP (output)" With all RECVFROM addresses where address option so\-timestamp is applied, socat sets this variable to the resulting timestamp\&. .IP .IP "\fBSOCAT_IP_OPTIONS\fP (output)" With all IPv4 based RECVFROM addresses where address option ip\-recvopts is applied, socat fills this variable with the IP options of the received packet\&. .IP .IP "\fBSOCAT_IP_DSTADDR\fP (output)" With all IPv4 based RECVFROM addresses where address option ip\-recvdstaddr (BSD) or ip\-pktinfo (other platforms) is applied, socat sets this variable to the destination address of the received packet\&. This is particularly useful to identify broadcast and multicast addressed packets\&. .IP .IP "\fBSOCAT_IP_IF\fP (output)" With all IPv4 based RECVFROM addresses where address option ip\-recvif (BSD) or ip\-pktinfo (other platforms) is applied, socat sets this variable to the name of the interface where the packet was received\&. .IP .IP "\fBSOCAT_IP_LOCADDR\fP (output)" With all IPv4 based RECVFROM addresses where address option ip\-pktinfo is applied, socat sets this variable to the address of the interface where the packet was received\&. .IP .IP "\fBSOCAT_IP_TOS\fP (output)" With all IPv4 based RECVFROM addresses where address option ip\-recvtos is applied, socat sets this variable to the TOS (type of service) of the received packet\&. .IP .IP "\fBSOCAT_IP_TTL\fP (output)" With all IPv4 based RECVFROM addresses where address option ip\-recvttl is applied, socat sets this variable to the TTL (time to live) of the received packet\&. .IP .IP "\fBSOCAT_IPV6_HOPLIMIT\fP (output)" With all IPv6 based RECVFROM addresses where address option ipv6\-recvhoplimit is applied, socat sets this variable to the hoplimit value of the received packet\&. .IP .IP "\fBSOCAT_IPV6_DSTADDR\fP (output)" With all IPv6 based RECVFROM addresses where address option ipv6\-recvpktinfo is applied, socat sets this variable to the destination address of the received packet\&. .IP .IP "\fBSOCAT_IPV6_TCLASS\fP (output)" With all IPv6 based RECVFROM addresses where address option ipv6\-recvtclass is applied, socat sets this variable to the transfer class of the received packet\&. .IP .IP "\fBSOCAT_OPENSSL_X509_ISSUER\fP (output)" Issuer field from peer certificate .IP .IP "\fBSOCAT_OPENSSL_X509_SUBJECT\fP (output)" Subject field from peer certificate .IP .IP "\fBSOCAT_OPENSSL_X509_COMMONNAME\fP (output)" commonName entries from peer certificates subject\&. Multiple values are separated by \(dq\& // \(dq\&\&. .IP .IP "\fBSOCAT_OPENSSL_X509_*\fP (output)" all other entries from peer certificates subject .IP .IP "\fBSOCAT_OPENSSL_X509V3_DNS\fP (output)" DNS entries from peer certificates extensions \- subjectAltName field\&. Multiple values are separated by \(dq\& // \(dq\&\&. .IP .IP "\fBHOSTNAME\fP (input)" Is used to determine the hostname for logging (see \-lh)\&. .IP .IP "\fBLOGNAME\fP (input)" Is used as name for the socks client user name if no socksuser is given\&. .br With options su and su\-d, LOGNAME is set to the given user name\&. .IP .IP "\fBUSER\fP (input)" Is used as name for the socks client user name if no socksuser is given and LOGNAME is empty\&. .br With options su and su\-d, USER is set to the given user name\&. .IP .IP "\fBSHELL\fP (output)" With options su and su\-d, SHELL is set to the login shell of the given user\&. .IP .IP "\fBPATH\fP (output)" Can be set with option path for exec and system addresses\&. .IP .IP "\fBHOME\fP (output)" With options su and su\-d, HOME is set to the home directory of the given user\&. .IP .SH "CREDITS" .PP The work of the following groups and organizations was invaluable for this project: .PP The \fIFSF\fP (GNU, http://www\&.fsf\&.org/ project with their free and portable development software and lots of other useful tools and libraries\&. .PP The \fILinux developers community\fP (http://www\&.linux\&.org/) for providing a free, open source operating system\&. .PP The \fIOpen Group\fP (http://www\&.unix\-systems\&.org/) for making their standard specifications available on the Internet for free\&. .PP .SH "VERSION" .PP This man page describes version 1\&.7\&.3 of \fBsocat\fP\&. .PP .SH "BUGS" .PP Addresses cannot be nested, so a single socat process cannot, e\&.g\&., drive ssl over socks\&. .PP Address option ftruncate without value uses default 1 instead of 0\&. .PP Verbose modes (\-x and/or \-v) display line termination characters inconsistently when address options cr or crnl are used: They show the data \fIafter\fP conversion in either direction\&. .PP The data transfer blocksize setting (\-b) is ignored with address readline\&. .PP Send bug reports to .PP .SH "SEE ALSO" .PP nc\e(1), netcat6\e(1), sock\e(1), rinetd\e(8), cage\e(1), socks\&.conf\e(5), openssl\e(1), stunnel\e(8), pty\e(1), rlwrap\e(1), setsid\e(1) .PP \fBSocat\fP home page http://www\&.dest\-unreach\&.org/socat/ .PP .SH "AUTHOR" .PP Gerhard Rieger socat-1.7.3.1/doc/xio.help0000644000201000020100000034717712161511320015011 0ustar gerhardgerhard# source: xio.help # Copyright Gerhard Rieger 2001-2010 Operating systems: The options and features described in this document have been implemented (but not always tested) on the operating systems listed below, unless otherwise noted: SuSE 10.1 Linux on x86 Solaris 8 on Sparc with gcc FreeBSD 6.1 on x86 HP-UX B 11.11 on PA-RISC with gcc =============================================================================== The following sections describe the syntax and semantics of the socat command line stream arguments. Usually a socat stream argument defines a one- or bidirectional stream. There are two principal forms: * a single stream. Depending on use of the -u or -U options and implicit semantics of the stream, such an argument may be resolved to a one- or twodirectional stream. * two onedirectional streams, separated by '!!'. An argument of this form always specifies a twodirectional stream. The first single stream is only used for reading data, and the second is only used for writing data. The general structure of a single stream is: keyword[:required-parameters][,options] The options part starts with the first ',' of the argument. The required parameters are separated by ':' from their predecessor. The last required parameter is terminated by the end of the argument or by the first ',' that iitroduces the first option. The options are separated with ','. The last option is terminated by end-of-string or by '!!'. The are some abbreviations defined that allow to drop the keyword. In these cases the argument syntax is: required-parameter[:required-parameters][,options] The implemented abbreviations are: short form canonical form number FD:number # decimal number path GOPEN:path # must must contain at least one '/' and must not contain ':' or ',' and must not start with a decimal digit =============================================================================== Addresses: Every address specification starts with a keyword or an abbreviation. These keywords are case insensitive. Note: because the option group ANY applies for all addresses, it is not mentioned explicitely below. Bidirectional only addresses: ----------------------------- PIPE FIFO ECHO Opens an unnamed pipe (fifo) where outbound traffic is sent to and inbound traffic is read from. The special semantics of pipes results in an echo like behaviour. Option groups: FD, FIFO (no specific FIFO options are defined yet) Onedirectional only addresses: ------------------------------ Currently all addresses may be used bidirectional. Note: for regular files, behaviour when being used bidirectionally is undefined. One- and bidirectional addresses: --------------------------------- STDIO - ("minus") Uses stdin (FD 0) for inbound traffic and/or stdout (FD 1) for outbound traffic on this address. Option groups: FD; others dependent on actual types of stdin and stdout (FIFO, CHR, BLK, REG, and/or SOCKET). STDIN Uses stdin for traffic. This might fail for outbound traffic. Option groups: FD; dependent on actual type of stdin (FIFO, CHR, BLK, REG, or SOCKET). STDOUT Uses stdout for traffic. This might fail for inbound traffic. Option groups: FD; dependent on actual type of stdout (FIFO, CHR, BLK, REG, or SOCKET). STDERR Uses stdout for traffic. This might fail for inbound traffic. Option group: FD; dependent on actual types of sterr (FIFO, CHR, BLK, REG, or SOCKET). FD:num num Uses the already existing file descriptor for traffic. Option groups: FD; dependent on actual types of file descriptor (FIFO, CHR, BLK, REG, or SOCKET). READLINE Uses the GNU readline function and history capabilies (best known from bash). It always works on stdin and stdout; if stdio is not a tty, readline does not seem to work correctly. Because readline is blocking during line editing, it does not fit well into socats I/O philosophy. socat integrates readline by waiting in the select call as usual; when stdin reports available data, socat invokes readline(). readline blocks until the user presses ENTER or EOF. Data on socats other stream is not handling in this time. socat controls the ECHO flag of the stdin tty (off during select(), on for readline()). When using socat with readline as front end to a service like telnet, POP3 or an other authenticated service, please note that the password is entered as ordinary data, thus appears on the screen! Option groups: FD, READLINE, TERMIOS Useful options: history-file OPEN:path Applies an open() system call to the given path. If the path does not exist a file is created only if the option create is used; if a file, pipe, or device with this name already exists it is opened. Open for reading and/or writing depends on the rw parameter of the xioopen call, or on usage in a socat argument. If no perm option is used, xioopen uses 600 (which might be modified by umask then). Applying this function to files conforms to the semantics as described by the open(2) man page. Opening device files, like /dev/ttyS*, might block until the device gets active (until some peer is connected) With existing named pipes (fifos) please note the usual semantics: Opening the pipe in read/write mode results in an echo service; Opening the pipe in read mode blocks until a writer opens the pipe (close by writer gives EOF for the reader); with option nonblock the open call does not block. Opening the pipe in write mode blocks until a reader opens the pipe (close by reader gives "broken pipe" error on next write); with option nonblock the open call terminates with error "no such device or address" in absence of a reader. Opening a named UNIX stream socket with or without a listening peer might succeed depending on the operating system, but the resulting file descriptor erronously reports available data immediately, and the following read() or write() call always fails with "invalid argument". Even worse, while such a filesystem entry is identified as socket by "file" command and by fstat(), getsockopt() after open() gives error "Socket operation on non-socket". Use GOPEN for reasonable behaviour! Option groups: FD, OPEN, NAMED, and specific for data object type (FILE, FIFO, CHRDEV+TERMIOS, BLKDEV, or SOCKET). GOPEN:path path "Generic open". Tries to open the given path in a smarter way. If the path exists and is a socket, it is connected to; if connecting fails, socat assumes a datagram socket and later uses sendto() calls for data transfer. If the path exists and is not a socket, it is opened: in RDONLY environment for reading from position 0, in WRONLY environment for appending (O_APPEND), in RDWR env. for reading and/or writing starting from position 0. If the path does not exist: in RDONLY environment this is an error in WRONLY environment the file is created (O_CREAT) in RDWR env. for reading and/or writing starting from position 0. However, these flags may be overriden by user supplied options (e.g., "append=0") Option groups: FD, NAMED, and specific for data object type (FILE, FIFO, CHRDEV+TERMIOS, BLKDEV, or SOCKET). CREATE:path CREAT:path Opens the named file with creat(). With UNIX semantics, this address is just a variation of the OPEN address, see there for more details. Note: The creat() system call does not create a completely new file, but inherits some properties of the old file if it exists, e.g. permissions. Use option "unlink-early" to remove the old entry before. Option groups: FD, NAMED, FILE Useful options: unlink-late PIPE:path FIFO:path Creates and opens a pipe if path does not exist; opens path if it already exists. Option groups: FD, NAMED, FIFO Note: this address uses the mknod(2) system call to create the named pipe. On FreeBSD, this call requires root privilege EXEC:cmdline Forks off a child process after establishing a bidirectional communication channel (with socketpair, pipes, or pty). The child then starts "cmdline" with execvp(). Note: spaces and shell meta characters in cmdline must be quoted if socat is invoked from the command line. Option groups: FD, FORK, EXEC, SOCKET, SOCK_UNIX, FIFO, TERMIOS Useful options: path, fdin, fdout, chroot, su, pty, stderr Note: on AIX, search permissions on /dev/pts/ are required to use option pty. SYSTEM:cmdline Forks off a child process after establishing a bidirectional communication channel (with socketpair, pipes, or pty). The child then starts "cmdline" with system(). Note: spaces and shell meta characters in cmdline must be quoted if socat is invoked from the command line. Option groups: FD, FORK, EXEC, SOCKET, SOCK_UNIX, FIFO, TERMIOS Useful options: path, fdin, fdout, chroot, su, pty, stderr Note: there are slightly different semantics with options pty or pipes, because they do not communicate an EOF condition to the shell process. Therefore, the shell process and its child do not terminate due to EOF, but are explicitly killed during close of the socat file handle. Consider using exec:'/bin/sh -c command',pty... UNIX:path LOCAL:path Connects to a UNIX domain socket. Option groups: FD, SOCKET, SOCK_UNIX NOTE: you need rw permissions to connect to a local socket. My Linux answers with "connection refused" to insufficient permissions, not existing socket, not a socket, or just a socket entry without a listening process. NOTE: this address does not implement option group NAMED because its connect call succeeds only if there is already someone listening, but at this point the NAMED group actions no longer affect this socket, only the fs entry. UNIX-listen:path UNIX-l:path Create a listening UNIX domain socket. With the fork option, for each accepted connection a new process is forked off, and more connections are accepted on the parent socket. Without fork, only the first connection is accepted. Option groups: FD, NAMED, SOCKET, SOCK_UNIX, LISTEN, CHILD IP:host:protocol IP4:host:protocol Open a raw socket with IP4 protocol. This mode sends packets to and accepts them only from host. protocol is a number from 0 to 255, with 1 meaning ICMP, 6..TCP, 17..UDP, 255..raw IP; 0 might be unsupported by the local IP stack, resulting in an error. Requires root privilege. Note: my Linux 2.4.10 kernel seems to drop payloads smaller than 8 bytes on their way from the network to the application. Option groups: FD, SOCKET, SOCK_IP TCP:host:port TCP4:host:port INET:host:port Create a TCP/IP4 client socket and connect to the given host/port combination. Option groups: FD, SOCKET, SOCK_IP, IPAPP, IP_TCP Useful options: crlf, bind, tos, mtudiscover, mss, nodelay, TCP-l:port TCP-listen:port TCP4-l:port TCP4-listen:port INET-l:port INET-listen:port Create a TCP/IP4 server socket and wait for an incoming connection. With the fork option, for each accepted connection a new process is forked off, and more connections are accepted on the parent socket. Without fork, only the first connection is accepted. Option groups: FD, SOCKET, SOCK_IP, IPAPP, IP_TCP, LISTEN, RANGE, CHILD Useful options: fork, crlf, bind, backlog, mtu, tcpwrap UDP:host:port UDP-CONNECT:host:port Connects to port on host using UDP/IP version 4 or 6 depending on address specification, name resolution, or option pf. Please note that, due to UDP protocol properties, no real connection is established; data has to be sent for `connecting' to the server, and no end-of-file condition can be transported. Option groups: FD, SOCKET, SOCK_IP4, SOCK_IP6, IP_UDP Useful options: ttl UDP4:host:port UDP4-CONNECT:host:port Like UDP-CONNECT, but only supports IPv4 protocol. Option groups: FD, SOCKET, SOCK_IP, IPAPP, IP_UDP UDP-listen:port UDP-l:port Emulates a UDP server in the same way as netcat: Create a UDP/IP4 socket and bind to the given port. Then wait for the first packet, get its sender address (without consuming its data), connect() to this address, and leave xioopen(). Afterwards, our socket only communicates with this peer. Option groups: FD, SOCKET, SOCK_IP, IPAPP, IP_UDP, RANGE Note: with fork option, child processes might hang forever because UDP cannot transport EOF conditions. #UDP-dgram:port #UDP-d:port # #Create and use a pure datagram oriented UDP socket. #The following restrictions apply: #* range option does not work #* de facto this is a read-only endpoint: sending data to 0.0.0.0 might fail. TCP6:host:port INET6:host:port Create a TCP/IP6 client socket and connect to the given host/port combination. Option groups: FD, SOCKET, SOCK_IP, IPAPP, IP_TCP Note: Address syntax parsing is awkward, since the IPv6 address word separator is ':' which is used as port separator too. An FTP listen entry looks in netstat ":::21"! TCP6-l:port TCP6-listen:port INET6-l:port INET6-listen:port Create a TCP server socket and wait for an incoming connection. With the fork option, for each accepted connection a new process is forked off, and more connections are accepted on the parent socket. Without fork, only the first connection is accepted. Option groups: FD, SOCKET, SOCK_IP, IPAPP, IP_TCP, LISTEN, RANGE, CHILD SOCKS4:sockd:host:port SOCKS:sockd:host:port Use a socks server, socks protocol version 4, to build a TCP (IPv4) connection. Sockd is the name or address of the socks server, host and port specify the destination address. Use option socksport if the socks server does not listen on port 1080. Option groups: FD, SOCKET, SOCK_IP, IPAPP, IP_TCP, IP_SOCKS Useful options: sp, socksport, socksuser Note: If you do not specify option socksuser, xioopen tries to derive it from environment: LOGNAME or USER, and might therefore undisclose your identity. SOCKS4a:sockd:host:port Like SOCKS4, but use the socks version 4a extension for destination name resolution on the socks server. Option groups: FD, SOCKET, SOCK_IP, IPAPP, IP_TCP, IP_SOCKS PTY Creates a pseudo terminal (pty) and uses its master side. Another process may open the pty´s slave side using it like a serial line or terminal. Option groups: FD,NAMED,PTY,TERMIOS Useful options: link, openpty, mode, user, group OPENSSL-CONNECT:host:port OPENSSL:host:port Tries to establish a SSL connection to port on host using TCP/IPv4. Note: this is currently only an experimental integration of openssl! (it does not provide any trust between the peers because is does not check certificates!) Option groups: FD,SOCKET,SOCK_IP4,IP_TCP,OPENSSL,RETRY Useful options: cipher, method, verify, cafile, capath, certificate, bind, sourceport, retry OPENSSL-LISTEN:port Listens on tcp4 port. When a connection is accepted, this address behaves as SSL server. Option groups: FD,SOCKET,SOCK_IP4,TCP,LISTEN,CHILD,RANGE,OPENSSL,RETRY Usefule options: cipher, method, verify, cafile, capath, certificate, retry PROXY:proxy:host:port PROXY-CONNECT:proxy:host:port Connects to an HTTP proxy server on port 8080 using TCP/IPv4, and sends a CONNECT request for host:port. If the proxy grants access and succeeds to connect to the target, data transfer between socat and the target can start. Note that the traffic need not be HTTP but can be an arbitrary protocol. Option groups: FD,SOCKET,IP4,TCP,HTTP Useful options: proxyport, ignorecr, proxyauth, crnl, bind, mss, sourceport =============================================================================== Option Groups: Each option is member of one option group. Address definitions specify which option groups they support. This allows to reject unapplyable options in an early stage of address processing. Address groups are identified by single bit positions. Option definitions specify to which group the option belongs (some options are member or more than one group). Addresses use a bit pattern to specify which option groups they support. Currently the following option groups are defined: GROUP_FD: All addresses that result in one or more file descriptors. These options are typically applied with fcntl() or some special calls like fchown() or fchmod(). There is no documented restriction to apply these functions to any file descriptor; but they are not always meaningful, and sometimes lead to OS exceptions. GROUP_APPL: All addresses. The options do not need file descriptors, because they manipulate the data streams at application level (ignoreeof, line terminator conversion). GROUP_PROCESS: For options that change process related attributes, like user id (setuid). GROUP_FIFO: Options for pipes. Currently not used. GROUP_CHR: Options for character devices. Currently not used. GROUP_BLK: Options for block devices. Currently not used. GROUP_REG, GROUP_FILE: Options for regular files. Currently not used. GROUP_SOCKET: Options for arbitrary type sockets, e.g. so-sndbuf, so-linger. GROUP_NAMED: Options for file system entries, e.g. user-early, unlink. GROUP_OPEN: Options that are applied with the open() system call. GROUP_EXEC: Options for program or script execution, e.g. path. GROUP_FORK: Options for communication with children processes, e.g. fdin, pty. GROUP_LISTEN: Options for listening sockets. Only backlog. GROUP_DEVICE: not used GROUP_CHILD: Options for addresses that may fork off independent child processes. Currently only option fork. GROUP_RETRY: Options for failure handling. Currently not used. GROUP_TERMIOS: Options for terminal settings, e.g. echo, b38400, raw. GROUP_READLINE: Options for readline (GNU line editing and history). GROUP_RANGE: Options for checking peer address. Currently only range. GROUP_SOCK_UNIX: Options for UNIX domain sockets. Currently not used. GROUP_SOCK_IP4: Options for IP4 sockets. Currently not used. GROUP_SOCK_IP6: Options for IP6 sockets. Currently not used. GROUP_SOCK_IP: Options for IP sockets, e.g. mtu, ip-options, ttl. GROUP_IP_UDP: Options for UDP sockets. Currently not used. GROUP_IP_TCP: Options for TCP sockets, e.g. maxseg, nodelay. GROUP_IPAPP: Options for UDP and TCP sockets. Currently only sourceport. GROUP_IP_SOCKS4: Options for SOCKS client connections, e.g. socksuser. GROUP_PROCESS: Options for process wide attributes, e.g. su, chroot. GROUP_APPL: Options handled by application. Currently not used. GROUP_PTY: Options for pseudo terminals. Used with addresses PTY, EXEC, and SYSTEM. GROUP_OPENSSL: Options for the OPENSSL address. There are "combined" group definitions too: #define GROUP_ANY (GROUP_PROCESS|GROUP_APPL) #define GROUP_ALL 0xffffffff =============================================================================== Address Options Address options are identified by a case insensitive keyword. If the options needs a parameter value, the option syntax is always: OPTION=VALUE Currently there do not exist options that take more than one argument; sometimes, two values are combined to form one argument value, e.g. IP4 address and port: 192.168.0.1:80 Note: "Type" describes the type of data that may or must be given to the option and that is passed to the system. There are some options with boolean semantics (on/off or yes/no), but their values are passed to the system with an int parameter. This situation is indicated as "Logical type: bool" and "Physical type: int". In this case xioopen passes the physical value to the system, giving the user one more hacking playground. Option: append Type: BOOL Option group: FD Phase: LATE Platforms: all (UNIX98) Sets the O_APPEND flag via a fcntl() call and F_SETFL; with OPEN type addresses, this flag is applied with the open() call. All data written is appended to the actual file end, even if other processes have written to or truncated the file in the meantime. Option: async Type: BOOL Option group: FD Phase: LATE Platforms: FreeBSD, Linux, SunOS Sets the O_ASYNC (or FASYNC) flag via a fcntl() call and F_SETFL; with FILE addresses, this flag is applied with the open() call. Consult your kernel documentation for effects of this flag. NOTE: socat does not handle the SIGIO signal. Option: cloexec Type: BOOL Option group: FD Phase: LATE Platforms: all Sets the FD_CLOEXEC (close-on-exec) flag on the file descriptor via a fcntl()call with F_SETFD. Use with caution, because xioopen() makes use of this flag to archieve what we consider the most reasonable behaviour; using this option overrides xioopen's setting! Option: flock-ex Aliases: flock, lock Type: BOOL Option group: FD Phase: FD Platforms: FreeBSD, Linux Applies the flock(fd, LOCK_EX) call to the file descriptor(s). This locks a file exclusively (but only for processes also using flock() on this file - otherwise, they seem to have unrestricted access). If the file is already locked with flock, our flock call blocks until the other processes lock is released. Note: the "lock" option name alias applies to this option only if the fcntl locking mechanism is not available on a platform. Option: flock-ex-nb Aliases: flock-nb Type: BOOL Option group: FD Phase: FD Platforms: FreeBSD, Linux Applies the flock(fd, LOCK_EX|LOCK_NB) call to the file descriptor(s). This locks a file exclusively (but only for processes also using flock() on this file - otherwise, they seem to have unrestricted access). If the file is already locked with flock, our flock call returns the error "Resource temporarily unavailable". Option: flock-sh Type: BOOL Option group: FD Phase: FD Platforms: FreeBSD, Linux Applies a shared advisory lock to the file using the flock(fd, LOCK_SH) call. This prevents processes from locking the file exclusively. If the file has already an exclusive lock, our flock call blocks until the other processes lock is released. Option: flock-sh-nb Type: BOOL Option group: FD Phase: FD Platforms: FreeBSD, Linux Applies a shared advisory lock to the file using the flock(fd, LOCK_SH|LOCK_NB) call. This prevents processes from locking the file exclusively. If the file has already an exclusive lock, our flock call returns with error "Resource temporarily unavailable". Option: f-setlk-rd Aliases: setlk-rd Type: BOOL Option group: FD Phase: FD Platforms: all Locks the complete file with fcntl(fd, F_SETLK, {F_RDLCK}) (complete means from its start to its maximal length). This locks the file exclusively (but only if the other processes accessing this file also use f-setlk or f-setlkw - otherwise, they seem to have unrestricted access). If the file is already locked with f-setlk or f-setlkw, the fcntl call blocks until release by the other process. Option: f-setlk-wr Aliases: f-setlk, setlk-wr, setlk Type: BOOL Option group: FD Phase: FD Platforms: all Locks the complete file with fcntl(fd, F_SETLK, {F_WRLCK}) (complete means from its start to its maximal length). This locks the file exclusively (but only if the other processes accessing this file also use f-setlk or f-setlkw - otherwise, they seem to have unrestricted access). If the file is already locked with f-setlk or f-setlkw, the fcntl call blocks until release by the other process. Option: f-setlkw-rd Aliases: setlkw-rd Type: BOOL Option group: FD Phase: FD Platforms: all Locks the complete file with fcntl(fd, F_SETLKW, {F_RDLCK}) (complete means from its start to its maximal length). This locks the file exclusively (but only if the other processes accessing this file also use f-setlk or f-setlkw - otherwise, they seem to have unrestricted access). If the file is already locked with f-setlk or f-setlkw, fcntl returns with EAGAIN. Option: f-setlkw-wr Aliases: setlkw-wr, f-setlkw, setlkw, lockw, lock Type: BOOL Option group: FD Phase: FD Platforms: all Locks the complete file with fcntl(fd, F_SETLKW, {F_WRLCK}) (complete means from its start to its maximal length). This locks the file exclusively (but only if the other processes accessing this file also use f-setlk or f-setlkw - otherwise, they seem to have unrestricted access). If the file is already locked with f-setlk or f-setlkw, fcntl returns with EAGAIN. Option: fork Type: BOOL Option group: CHILD Phase: PASTACCEPT Platforms: all Without fork (or fork=0), the listening process accepts exactly one connections, and terminates afterwards. With fork set, it forks off a new socat child process for each incoming connection. It is very important to understand what socat does with this fork option: The parent process remains in a loop of accept() and fork() calls until terminated from outside. The child process leaves this loop and goes on with the socat processing. If the fork occurs in the first address argument, the child process continues with parsing and activating the second address argument. This will in most cases be what you want or expect. If the fork call occurs in socats second address argument, all children will inherit and share the already activated first address. Option: group=value Aliases: gid=value Type: GIDT or unsigned int Option group: NAMED Type: GIDT Platforms: all Takes one argument, a UNIX group name or a numeric group id. The first character of value is a digit for group ids. With NAMED addresses this option is applied via a chown() call, with a fchown() call otherwise. If groupname is a name it must be a valid groupname from /etc/group and is converted to a group id with a getgrnam(3) call. On most modern operating systems, the owner of the process must be member of the group being set; only root may set any group, even numbers without group name. A Linux 2.2.10 kernel SIGSEGVs the process in the fchown() call when this option is used with a socket or pipe. Is fixed with Linux 2.4. LINUXBUG TESTCASE: SH1: socat -D - unix-l:/tmp/socket,unlink-early SH2: socat -d -d -d -d -D gopen:/tmp/socket,group=floppy - Option: group-late=value Type: GIDT or string Option group: FD Type: GIDT Platforms: all Takes one argument, a UNIX group name or a numeric group id. The first character of value is a digit for group ids. This option is applied via a fchown(2) call. If groupname is a name it must be a valid groupname from /etc/group and is converted to a group id with a getgrnam(3) call. On most modern operating systems, the owner of the process must be member of the group being set; only root may set any group, even numberic group ids without group name. Option: o-nonblock Aliases: nonblock Type: BOOL Option group: FD Phase: FD Platforms: all (UNIX98) Sets the O_NONBLOCK flag of a file descriptor via a fcntl(2) call and F_SETFL; with OPEN type addresses, this flag is applied with the open() call. It does not change the behaviour of socat's data transfer loop because socat uses select() which blocks nevertheless. Currently is has only two documented uses: 1) With address TCP, the connect() call does not block; instead, it continues through the open step. The channel is passed to the select() call. If something is written to the channel before it is connected, this is an error. If connection fails, a read condition occurs and read() returns the error. 2) Opening a named pipe does not block with this option. Option: o-ndelay Aliases: ndelay Type: BOOL Option group: FD Phase: LATE Platforms: HP-UX, SunOS (UNIX98) Under Solaris it sets the O_NDELAY of the file descriptor via a fcntl(2) call and F_SETFL; with OPEN type addresses, this flag is applied with the open() call. With all other operating systems, this is just another name for the nonblock option. Option: o-noatime Aliases: noatime Type: BOOL Option group: FD Phase: FD Platforms: Linux Sets the O_NOATIME flag of a file descriptor via a fcntl(2) call and F_SETFL; with OPEN type addresses, this flag is applied with the open() call. It prevents the access time from being updated during read operations. Option: perm=value Aliases: mode=value Type: MODET (mode_t) Option group: NAMED Phase: FD Platforms: all This option changes the mode (permissions) of an addresses inode. xioopen tries to apply this option already during open phase. If the address does not have a open phase or if the option cannot be applied there, the value is applied directly on the file descriptor afterwards. It is up to you to (1) have the permission to change the permissions, and (2) not to set permissions that prevent you from performing your transactions :-) NOTE: At least with some Linux 2.2, setting permissions on an existing file or device with fchmod() does not change the permissions of its inode on disk. See perm-early which uses chmod() instead. NOTE: At least with some Linux 2.2, restricting mode on file descriptors does not restrict this file descriptors data transfer capabilities. Option: perm-late=value Type: MODET (mode_t) Option group: FD Phase: LATE Platforms: all This option changes the mode (permissions) of a file descriptor with fchmod() in the last phase of address processing. Option: seek-set=offset Aliases: lseek=offset, seek=offset Type: OFF32 or OFF64 Option group: BLK Phase: LATE Platforms: HP-UX, Linux, SunOS Positions the file at the given absolute offset, using lseek() (or lseek64() if available) with SEEK_SET. Option: seek-cur=offset Type: OFF32 or OFF64 Option group: BLK Phase: LATE Platforms: HP-UX, Linux, SunOS Positions the file at the given offset from the current position, using lseek() (or lseek64() if available) with SEEK_SET. Option: seek-end=offset Type: OFF32 or OFF64 Option group: BLK Phase: LATE Platforms: HP-UX, Linux, SunOS Positions the file at the given offset from the file end, using lseek() (or lseek64() if available) with SEEK_END. Option: lseek32-set=offset Aliases: lseek32=offset Type: OFF32 Option group: BLK Phase: LATE Platforms: HP-UX, Linux, SunOS Positions the file at the given absolute offset using lseek() with SEEK_SET. This call might fail for non random access data objects like character devices or sockets. NOTE: this option seems to be useless on files with O_APPEND set. Option: lseek32-cur=offset Type: OFF32 (instead of off_t) Option group: BLK Phase: LATE Platforms: HP-UX, Linux, SunOS Positions the file at the given offset from the current position using lseek() with SEEK_CUR. This call might fail for non random access data objects like character devices. On Linux, the seek() call fails on pipes, sockets and ttys but works on files and /dev/null NOTE: this option seems to be useless on files with O_APPEND set. Option: lseek32-end=offset Type: OFF32 Option group: BLK Phase: LATE Platforms: HP-UX, Linux, SunOS Positions the file at the given offset from the file end using lseek() with SEEK_END. This call might fail for non random access data objects like character devices. NOTE: this option seems to be useless on files with O_APPEND set. Option: lseek64-set=offset Aliases: lseek64=offset Type: OFF64 Option group: BLK Phase: LATE Platforms: all Positions the file at the given absolute offset using lseek64() with SEEK_SET. This call might fail for non random access data objects like character devices or sockets. NOTE: this option seems to be useless on files with O_APPEND set. Option: lseek64-cur=offset Type: OFF64 Option group: BLK Phase: LATE Platforms: all Positions the file at the given offset from the current position using lseek64() with SEEK_CUR. This call might fail for non random access data objects like character devices. NOTE: this option seems to be useless on files with O_APPEND set. Option: lseek64-end=offset Type: OFF64 Option group: BLK Phase: LATE Platforms: all Positions the file at the given offset from the file end using lseek64() with SEEK_END. This call might fail for non random access data objects like character devices. NOTE: this option seems to be useless on files with O_APPEND set. Option: chroot=path Type: STRING Option group: PROCESS Phase: LATE Platforms: all Invokes the chroot() system call with the given path after the address resolution, so the path names of the address must be specified with absolute pathes. Note: when you combine chroot with substuser, with substuser applied within the chroot environment, usually the etc/passwd and etc/group files in the chroot environment are used for group set etc. See appendix "generating a sandbox" Option: chroot-early=path Type: STRING Option group: PROCESS Phase: EARLY Platforms: all Invokes the chroot() system call with the given path before the address is resolved, this means before file opening in OPEN, GOPEN and before program execution in EXEC and SYSTEM, so their pathes must be specified related to their chroot directory. See appendix "generating a sandbox" Option: setgid=group Type: GIDT (gid_t or string) Option group: PROCESS Phase: LATE2 Platforms: all Invokes setgid() with the group id. For EXEC and SYSTEM this call is performed for the child process after the fork and therefore does not affect the socat process directly. For LISTEN group addresses with fork option, this call is performed only on the child processes. For all other addresses, it is performed in the late phase of address processing, so it does not affect the address where it is used, but for the next address (if any), and for the data loop. Note: setgid() does not remove any groups from the current process group set. Option: setuid=user Type: UIDT (uid_t or string) Option group: PROCESS Phase: LATE2 Platforms: all Invokes setuid() with the user id. For EXEC and SYSTEM this call is performed for the child process after the fork and therefore does not affect the socat process directly. For LISTEN group addresses with fork option, this call is performed only on the child processes. For all other addresses, it is performed in the late phase of address processing, so it does not affect the address where it is used, but the next address (if any), and the data loop. Note: setuid() is invoked AFTER setgid(), if both are applied. Note: setuid() does not influence the processes group set; in most cases, you want to prefer substuser option. Option: substuser=user Aliases: su=user Type: UIDT (uid_t or string) Option group: PROCESS Phase: LATE2 Platforms: all Tries to switch the process to the given user and its group set. To make sure that the groups are set correctly for the new process owner, the system calls initgroups(), setgid(), and setuid() are invoked with the appropriate arguments. On sane operating system, this option requires root privileges. Note: this option sets the user and group ids of the process, but does not change the environment; therefore, all variables including $USER, $HOME, $LOGNAME, $SHELL etc. are inherited from the old users environment. Note: starting a SETUID program after applying substuser or setuid gives the process the SETUID owner, which might give root privileges again. Option: substuser-delayed=user Aliases: su-d=user Type: UIDT (unsigned int or string) Option group: PROCESS Phase: INIT Platforms: all Like substuser, but reads the user and group information in an early phase of address processing, but applies the appropriate system calls in a late phase. This allows to use user information from the host in a chroot environment, without exposing this data within the sandbox. Option: o-trunc Aliases: trunc Type: BOOL Option group: OPEN Phase: LATE Platforms: all Sets the O_TRUNC flag of the open() call, thus truncating the file to zero length. #! block devices? Option: ftruncate=value Aliases: truncate=value Type: OFF32 or OFF64 Option group: REG Phase: LATE Platforms: HP-UX, Linux, SunOS Invokes the ftruncate() (or ftruncate64() if available) call for the file descriptor with the given value, thus reducing the length of the file to the given length. On Linux, ftruncate() fails on sockets and devices but works on regular files and pipes. #! block devices? Note: AIX docu says: for regular files only Option: ftruncate32=value Type: OFF32 Option group: REG Phase: LATE Platforms: HP-UX, Linux, SunOS Invokes the ftruncate() call (even if ftruncate64() is available) call for the file descriptor with the given value, thus reducing the length of the file to the given length. Option: ftruncate64=value Type: OFF64 Option group: REG Phase: LATE Platforms: all Invokes the ftruncate64() call if available, for the file descriptor with the given value, thus reducing the length of the file to the given length. Option: o-binary Aliases: binary, bin Type: BOOL Option group: FD Phase: OPEN Platforms: none; Cygwin Sets the O_BINARY flag with open() or fcntl() to avoid implicit line terminator conversions. Option: o-text Aliases: text Type: BOOL Option group: FD Phase: OPEN Platforms: none; Cygwin Sets the O_TEXT flag with open() or fcntl() to force implicit line terminator conversions. Option: o-noinherit Aliases: noinherit Type: BOOL Option group: FD Phase: OPEN Platforms: none; Cygwin Sets the O_NOINHERIT flag with open() or fcntl() to not keep this file open in a spawned process. Option: cool-write Aliases: coolwrite Type: BOOL Option group: FD Phase: INIT Platforms: all Takes it easy when write fails with EPIPE or ECONNRESET and logs the message with notice level instead of error. This prevents the log file from being filled with useless error messages when socat is used as a high volume server or proxy where clients often abort the connection. This option is experimental. Option: end-close Aliases: close Type: CONST Option group: FD Phase: INIT Platforms: all Changes the (address dependent) method to close a connection to just close the file descriptors. This is useful when the connection is to be reused by or shared with other processes. Normally, socket connections will be ended with shutdown(2) which terminates the socket even if it is shared by multiple processes. close(2) "unlinks" the socket from the process but keeps it active as long as there are still links from other processes. Similarly, when an address of type EXEC or SYSTEM is ended, socat usually will explicitely kill the sub process. With this option, it will just close the file descriptors. Option: user=value Aliases: owner=value, uid=value Type: UIDT (unsigned int or string) Option group: NAMED Phase: FD Platforms: all Takes one argument, a UNIX user name or a numeric user id. The first character of value is a digit for user ids. For NAMED addresses, if the file already exists, this option is applied via a chown() call, with fchown() for all other cases. If username is a name it must be a valid username from /etc/passwd and is converted to a user id with a getpwnam() call. On sane operating systems, the owner of the process must be root to change the owner of a file descriptor; root may even apply undefined (unnamed) user ids. My Linux 2.2 kernel SIGSEGVs the process in the fchown() call when this option is used with a (UNIX, unconnected or connected) socket or pipe. Linux 2.4.0 handles this call correctly. TESTCASE: ./socat -d -d -d -d - tcp:loopback:21,user=root Option: user-late=value Aliases: uid-l=value Type: UIDT (unsigned int or string) Option group: FD Phase: LATE Platforms: all Takes one argument, a UNIX user name or a numeric user id. The first character of value is a digit for user ids. This option is applied via a fchown() call just before xioopen_single() terminates. If username is a name it must be a valid username from /etc/passwd and is converted to a user id with a getpwnam() call. On sane operating systems, the owner of the process must be root to change the owner of a file descriptor; root may even apply undefined (unnamed) user ids. My Linux 2.2 kernel SIGSEGVs the process in the fchown() call when this option is used with a socket or pipe. =============================================================================== OPEN group options Options of this group may be used with all addresses that support OPEN group options. Option: o-rdonly Aliases: rdonly Type: BOOL (inherent - no value) Option group: OPEN Phase: OPEN Platforms: all Use O_RDONLY with the open() call instead of the position dependend default. Take care not to block later write operations. Option: o-wronly Aliases: wronly Type: BOOL (inherent - no value) Option group: OPEN Phase: OPEN Platforms: all Use O_WRONLY with the open() call instead of the position dependend default. Take care not to block later write operations. Option: o-rdwr Aliases: rdwr Type: BOOL (inherent - no value) Option group: OPEN Phase: OPEN Platforms: all Use O_RDWR with the open() call instead of the position dependend default. Option: o-create Aliases: create, creat Type: BOOL Option group: OPEN Phase: OPEN Platforms: all Sets the O_CREAT flag of the open() call. This means that it is not an error if the file does not exist. Option: o-defer Aliases: defer Type: BOOL Option group: OPEN Phase: OPEN Platforms: none Sets the O_DEFER flag of the open() call. This means that write data is stored in paging space until an fsync() call. Option: o-delay Aliases: delay Type: BOOL Option group: OPEN Phase: OPEN Platforms: none Sets the O_DELAY flag of the open() call. This lets open block until the share conditions are fulfilled (see nshare, rshare) Option: o-direct Aliases: direct Type: BOOL Option group: OPEN Phase: OPEN Platforms: FreeBSD, HP-UX, Linux Sets the O_DIRECT flag of the open() call. Option: o-directory Aliases: directory Type: BOOL Option group: OPEN Phase: OPEN Platforms: Linux Sets the O_DIRECTORY flag of the open() call. This lets open fail if the given path is not a directory. This does not seem to be useful with socat. Option: o-dsync Aliases: dsync Type: BOOL Option group: OPEN Phase: OPEN Platforms: HP-UX, Linux, SunOS (UNIX98) Sets the O_DSYNC flag with the open() call. This lets write() calls wait until modification metainfo is physically written to media. Option: o-excl Aliases: excl Type: BOOL Option group: OPEN Phase: OPEN Platforms: all Sets the O_EXCL flag of the open() call. Option: o-largefile Aliases: largefile Type: BOOL Option group: OPEN Phase: OPEN Platforms: HP-UX, Linux, SunOS Sets the O_LARGEFILE flag of the open() flag. Option: o-noctty Aliases: noctty Type: BOOL Option group: OPEN Phase: OPEN Platforms: all Sets the O_NOCTTY flag of the open() call, so the opened device does not become the controlling tty of the process. Option: o-nofollow Aliases: nofollow Type: BOOL Option group: OPEN Phase: OPEN Platforms: FreeBSD, Linux Sets the O_NOFOLLOW flag of the open() call. This means that the last component of the open path must no be a symlink. Option: o-sync Aliases: sync Type: BOOL Option group: OPEN Phase: OPEN Platforms: all (UNIX98) Sets the O_SYNC flag with the open() call. This lets write() calls wait until data is physically written to media. Option: o-rshare Aliases: rshare Type: BOOL Option group: OPEN Phase: OPEN Platforms: none Sets the O_RSHARE flag of the open() call. This means that the file must not be opened for writing by other processes ("read sharing"). Option: o-nshare Aliases: nshare Type: BOOL Option group: OPEN Phase: OPEN Platforms: none Sets the O_NSHARE flag of the open() call. This means that the file must not be shared with other processes ("no sharing"). Option: o-rsync Aliases: rsync Type: BOOL Option group: OPEN Phase: OPEN Platforms: HP-UX, Linux, SunOS (UNIX98) Sets the O_RSYNC flag with the open() call. This lets write() calls wait until read metainfo is physically written to media. Option: o-priv Aliases: priv Type: BOOL Option group: OPEN Phase: OPEN Platforms: none (Solaris) Sets the O_PRIV flag with the open() call. =============================================================================== NAMED group options This group is valid for all addresses that refer to a file system entry like file, device, named pipe, or named UNIX domain socket. Option: unlink-early Aliases: new Type: BOOL Option group: NAMED Phase: EARLY Platforms: all This options tries to remove the filesystem entry given in the address before starting any other processing (even before user-early, perm-early, or group-early). unlink() is called; note that this call, in contrast to rm(1), removes entries regardless of their permissions. Instead, ownership or root privileges and write permissions in the directory are required and sufficient. Option: unlink Type: BOOL Option group: NAMED Phase: PREOPEN Platforms: all This options tries to remove the filesystem entry given in the address before it is tried to open, but past user-early, perm-early, or group-early). unlink() is called; note that this call, in contrast to rm(1), removes entries regardless of their permissions. Instead, ownership or root privileges and write permissions in the directory are required and sufficient. Option: unlink-late Type: BOOL Option group: NAMED Phase: PASTOPEN Platforms: all This option tries to remove the filesystem entry after it has been opened. Options can still be applied to the file descriptor, and the node or files data can be used, but it can no longer be accessed by other processes (except by tricks?), and after closing the stream the data or node is completely removed. unlink() is called; note that this call, in contrast to rm(1), removes entries regardless of their permissions. Instead, ownership or root privileges and write permissions in the directory are required and sufficient. Option: perm-early=value Type: MODET (mode_t) Option group: NAMED Phase: PREOPEN Platforms: all This option changes the mode (permissions) of an already existing filesystem entry with chmod() before the file is opened or after the UNIX domain socket is bound, but before it listens/connects. Option: user-early=value Aliases: uid-e=value Type: UIDT (unsigned int or string) Option group: NAMED Phase: PREOPEN Platforms: all Takes one argument, a UNIX user name or a numeric user id. The first character of value is a digit for user ids. This option is applied via a chown() call before the file system entry is opened or after the UNIX domain socket is bound, but before it starts to listen/connect. If username is a name it must be a valid username from /etc/passwd and is converted to a user id with a getpwnam() call. On sane operating systems, the owner of the process must be root to change the owner of a file descriptor; root may even apply undefined (unnamed) user ids. Option: group-early=value Aliases: gid-e=value Type: GIDT (unsigned int or string) Option group: NAMED Phase: PREOPEN Platforms: all Takes one argument, a UNIX group name or a numeric group id. The first character of value is a digit for group ids. This option is applied via a chown() call before the file system entry is opened or after the UNIX domain socket is bound, but before it listens/connects. If groupname is a name it must be a valid groupname from /etc/group and is converted to a group id with a getgrnam() call. On most modern operating systems, the owner of the process must be member of the group being set; only root may set any group, even numbers without group name. Option: umask=value Type: MODET Option group: NAMED Phase: EARLY Platforms: all Sets the umask before opening a file or creating a UNIX domain socket. This is especially useful for these sockets, because there interface does not provide a mode argument. Option: unlink-close Type: BOOL Option group: NAMED Phase: LATE Platforms: all Remove the addresses file system entry when closing the address. For named pipes, listening unix domain sockets, and the symbolic links of pty addresses, the default is 1; for created files, opened files, generic opened files, and client unix domain sockets the default is 0. =============================================================================== FORK and EXEC options Option: path=string Type: STRING Option group: EXEC Phase: PREEXEC Platforms: all Changes the PATH environment variable in the child process before the exec() or system() call. Option: nofork Type: BOOL Option group: FORK Phase: BIGEN Platforms: all Does not fork a subprocess for executing the program, instead calls execvp() directly from the actual socat instance. This avoids the overhead of another process between the program and the communication peer, but introduces lots of restrictions: * this option can only be applied to the second socat() address. * the first socat address cannot be OPENSSL or READLINE * socat options -b, -t, -D, -l, -v, -x, -t become useless * for both addresses, options ignoreeof, cr and crnl become useless * for the second address (the one with option nofork), options append, async, cloexec, flock, user, group, mode, nonblock, perm-late, setlk, and setpgid cannot be applied, and should be used on the first address instead. Option: pipes Type: BOOL Option group: FORK Phase: BIGEN Platforms: all For communication between the exec() or system() subprocess with socat, use two unnamed pipes instead of creating a socket pair. Option: pty Type: BOOL Option group: FORK Phase: BIGEN Platforms: all For communication between the exec() or system() subprocess with socat, use a pseudo terminal instead of a socket pair. The executed program gets the slave side, and socat the controlling side of the pseudo terminal. This is especially useful if you want to use, e.g., chat with socat (see EXAMPLES). Plus, ptys do not buffer I/O. Note: implementation of pseudo terminals are differing between platforms, so extra porting struggles might be required for porting this feature. Option: fdin=num Type: USHORT Option group: FORK Phase: PASTBIGEN Platforms: all After forking the child process, assign the stream where the child receives data from socat, to file descriptor num instead of stdin. Option: fdout=num Type: USHORT Option group: FORK Phase: PASTBIGEN Platforms: all After forking the child process, assign the stream where the child writes data to socat, to file descriptor num instead of stdout. Option: stderr Type: BOOL Option group: FORK Phase: PASTFORK Platforms: all Normally, the stderr filedescriptor of the forked program is a clone of socat's stderr fd. If this option is used, the programs stderr filedescriptor is a copy of the "normal" data output of the program, i.e. of its stdout or fdout. Option: setsid Aliases: sid Type: BOOL Option group: PROCESS Phase: LATE Platforms: all Invokes setsid() to make the forked off subprocess the leader of a new session. This also generates a new process group with this process as leader. This is useful, e.g., when exec'ing ssh to get the password prompt into the I/O channel (see EXAMPLES) Option: setpgid Aliases: pgid Type: INT Option group: FORK Phase: LATE Platforms: all Invokes setpgid(0, val) from the child process. Option: tiocsctty Aliases: ctty Type: BOOL Option group: TERMIOS Phase: LATE2 Platforms: all Applies only in combination with the pty option or its variants. Tries to make the pty the controlling terminal. May require option setsid to work correctly. Option: dash Aliases: login Type: BOOL Option group: EXEC Phase: PREEXEC Platforms: all Prefixes argv[0] for the execvp() call with '-', thus making a shell behave as login shell. Option: sighup Type: CONST Option group: PARENT Phase: LATE Platforms: all Has socat pass an eventual SIGHUP signal to the sub process. If no address has this option, socat terminates on SIGHUP. Option: sigint Type: CONST Option group: PARENT Phase: LATE Platforms: all Has socat pass an eventual SIGINT signal to the sub process. If no address has this option, socat terminates on SIGINT. Option: sigquit Type: CONST Option group: PARENT Phase: LATE Platforms: all Has socat pass an eventual SIGQUIT signal to the sub process. If no address has this option, socat dumps core and terminates on SIGQUIT. =============================================================================== PTY options These options may be used with addresses that create a pseudo terminal (pty). In particular, these are addresses EXEC, SYSTEM, and PTY. Option: openpty Type: BOOL Option group: PTY Phase: BIGEN Platforms: FreeBSD, Linux Like pty, but only use the openpty mechanism, not any other way for pty generation. Option: ptmx Type: BOOL Option group: PTY Phase: BIGEN Platforms: HP-UX, Linux, SunOS Like pty, but only use the /dev/ptmx (/dev/ptc on AIX) mechanism, not any other way for pty generation. Option: symbolic-link=filename Type: FILENAME Option group: PTY Phase: LATE Platforms: all Generates a symbolic link that points to the actual pseudo terminal (pty). This might help to solve the problem that ptys are generated with more or less unpredictable names, making it difficult to directly access the socat generated pty automatically. With this option, the user can specify a "fix" point in the file hierarchy that helps him to access the actual pty. Option: pty-wait-slave Aliases: wait-slave, waitslave Type: BOOL Option group: PTY Phase: EARLY Platforms: all Blocks the open phase until a process opens the slave side of the pty. Usually, socat continues after generating the pty with opening the next address or with entering the transfer engine. With the wait-slave option, socat waits until some process opens the slave side of the pty before continuing. This option only works if the operating system provides the tt(poll()) system call. And it depends on an undocumented behaviour of pty's, so it does not work on all operating systems. It has successfully been tested on Linux, FreeBSD, NetBSD, and on Tru64 with openpty. Option: pty-interval Type: TIMESPEC Option group: PTY Phase: EARLY Platforms: all When the wait-slave option is set, socat periodically checks the HUP condition using poll() to find if the pty's slave side has been opened. The default polling interval is 1s. Use the pty-interval option to change this value. =============================================================================== SOCKET options These are options that may be applied to all socket type addresses: UNIX (LOCAL) domain sockets (even with EXEC type addresses if not pipes), IP, and IPv6. Option: so-debug Aliases: debug Logical type: bool Physical type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Sets the SO_DEBUG socket option. Requires root. Option: so-acceptconn Aliases: acceptconn Logical type: bool Physical type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Tries to set the SO_ACCEPTCONN socket option. Read-only! Option: so-broadcast Aliases: broadcast Logical type: bool Physical type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Sets the SO_BROADCAST socket option. Option: so-reuseaddr Aliases: reuseaddr Logical type: bool Physical type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Sets the SO_REUSEADDR socket option. Allows to bind to a port even if this port is already used for a connection. Option: so-keepalive Aliases: keepalive Logical type: bool Physical type: INT Option group: SOCKET Phase: FD Platforms: all (UNIX98) Sets the SO_KEEPALIVE socket option. Option: so-linger=value Aliases: linger=value Type: LINGER Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Activates the SO_LINGER option and sets a value (seconds) for it. This lets shutdown() or close() block until data transfers have finished or the given value timed out. Note: on some systems, the type for setsockopt() is struct { int; int; } In this case, xioopen() sets {1,value}. Option: so-oobinline Aliases: oobinline Logical type: bool Physical type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Sets the SO_OOBINLINE socket option. Option: so-sndbuf=value Aliases: sndbuf=value Type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Sets the SO_SNDBUF option of the socket to the given value. This option is applied after the socket() (or socketpair()) call. NOTE: The kernel might change the effective value: My Linux 2.2 with TCP doubles the value, but uses at least 2048. Option: so-sndbuf-late=value Aliases: sndbuf-late=value Type: INT Option group: SOCKET Phase: LATE Platforms: all (UNIX98) Sets the SO_SNDBUF option of the socket to the given value. This option is applied after the connect() or accept() (or socketpair) call. NOTE: The kernel might change the effective value: My Linux 2.2 with TCP doubles the value, but uses at least 2048, and a maximum of 131070 (system limit?). Option: so-rcvbuf=value Aliases: rcvbuf=value Type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Sets the SO_RCVBUF option of the socket to the given value. This option is applied after the socket() call. NOTE: The kernel might change the effective value: My Linux 2.2 with TCP connect doubles the value, but uses at least 256 and at most 131070. My Linux 2.2 with TCP listen doubles the value but uses at least 11772. NOTE: For applying the SO_RCVBUF options after the connect() or accept() calls see rcvbuf-late. Option: so-rcvbuf-late=value Aliases: rcvbuf-late=value Type: INT Option group: SOCKET Phase: LATE Platforms: all (UNIX98) Sets the SO_RCVBUF option of the socket to the given value. This option is applied after the connect() or listen() call. NOTE: The kernel might change the effective value: My Linux 2.2 with TCP doubles the value, but uses at least 256 and maximal 131070. NOTE: sequence of this call may be relevant for the effecting value (AIX 4.3.3). For applying the SO_RCVBUF option immediately after the socket() call see rcvbuf. Option: so-error Aliases: error Logical type: bool Physical type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Tries to set the SO_ERROR socket option which is a read-only option. On my Linux 2.2 it gives "protocol not available". Option: so-type=value Aliases: type=value Type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: all Set the sockettype argument of the socket() or socketpair() call. This overrides the per protocol default (e.g., TCP: SOCK_STREAM). Most values might not be supported by a given protocol. The following combinations are known to work at least under one OS: TCP SOCK_STREAM (system default) UDP SOCK_DGRAM (system default) IP SOCK_RAW (socat default) UNIX SOCK_STREAM (system default) UNIX SOCK_DGRAM Option: so-dontroute Aliases: dontroute Logical type: bool Physical type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Sets the SO_DONTROUTE socket option. Option: so-rcvlowat=value Aliases: rcvlowat=value Type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Sets the SO_RCVLOWAT socket option. Cannot be changed in Linux (always gives "protocol not available"). Option: so-rcvtimeo=value Aliases: rcvtimeo=value Provided type: double Physical type: TIMEVAL (long[2]) Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Sets the SO_RCVTIMOE socket option. Cannot be changed in Linux (always gives "protocol not available"). Option: so-sndlowat=value Aliases: sndlowat=value Type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Sets the SO_SNDLOWAT socket option. Cannot be changed in Linux (always gives "protocol not available"). Option: so-sndtimeo=value Aliases: sndtimeo=value Provided type: double Physical type: TIMEVAL (long[2]) Option group: SOCKET Phase: PASTSOCKET Platforms: all (UNIX98) Sets the SO_SNDTIMEO socket option. Cannot be changed in Linux (always gives "protocol not available"). Option: so-audit Aliases: audit Type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: none Sets the SO_AUDIT socket option. Option: so-attach-filter Aliases: attach-filter, attachfilter Type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: Linux Linux docu recommends to use libpcap for this feature. "protocol not available", need kernel CONFIG_FILTER! Option: so-detach-filter Aliases: detach-filter, detachfilter Type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: Linux See Linux "man 7 socket". "protocol not available", need kernel CONFIG_FILTER! Option: so-bindtodevice=string Aliases: bindtodevice, interface, if Type: NAME Option group: SOCKET Phase: PASTSOCKET Platforms: Linux Binds the socket to a net interface, e.g. lo0 or eth0 (interface names depend on operating system). Might require root privilege. Option: so-bsdcompat Aliases: bsdcompat Logical type: bool Physical type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: none Sets the SO_BSDCOMPAT socket option. See Linux "man 7 socket". Option: so-cksumrecv Aliases: cksumrecv Logical type: bool Physical type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: none Sets the SO_CKSUMRECV socket option. Option: so-kernaccept Aliases: kernaccept Logical type: bool Physical type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: none Sets the SO_KERNACCEPT socket option. Option: so-no-check Aliases: no-check, nocheck Logical type: bool Physical type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: Linux Sets the SO_NO_CHECK socket option." Intentionally undocumented" under Linux (see "man 7 socket"), don't know what it does.... Option: so-noreuseaddr Aliases: noreuseaddr Type: INT? Option group: SOCKET Phase: PASTSOCKET Platforms: none Sets the SO_NOREUSEADDR socket option. Option: passcred Aliases: so-passcred Type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: Linux Sets the SO_PASSCRED option of a socket. Option: so-peercred Aliases: peercred Type: INT3 or int[3]? Option group: SOCKET Phase: PASTSOCKET Platforms: Linux Enables receiving of credentials. Read only. Not really implemented yet. Nevertheless, Gives "Protocol not available". Option: so-priority=value Aliases: priority=value Type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: Linux Sets the protocol defined priority for all packets to be sent on this socket. Docu says it requires root privileges. Normal user may set 0..6 for UNIX domain and TCP client sockets on Linux 2.2. root may send any int value. Option: so-reuseport Aliases: reuseport Type: INT? Option group: SOCKET Phase: PASTSOCKET Platforms: FreeBSD, HP-UX Sets the SO_REUSEPORT socket option. Option: so-security-authentication Aliases: security-authentication, securityauthentication Type: INT? Option group: SOCKET Phase: PASTSOCKET Platforms: Linux Sets the SO_SECURITY_AUTHENTICATION socket option. Gives "protocol not available" error. In Linux 2.2.16 source, only exists in asm-*/socket.h Option: so-security-encryption-network Aliases: security-encryption-network, securityencryptionnetwork Type: INT? Option group: SOCKET Phase: PASTSOCKET Platforms: Linux Sets the SO_SECURITY_ENCRYPTION_NETWORK option of the socket. Gives "protocol not available" error. In Linux 2.2.16 source, only exists in asm-*/socket.h Option: so-security-encryption-transport Aliases: security-encryption-transport, securityencryptiontransport Type: INT? Option group: SOCKET Phase: PASTSOCKET Platforms: Linux Sets the SO_SECURITY_ENCRYPTION_TRANSPORT option of the socket. Gives "protocol not available" error. In Linux 2.2.16 source, only exists in asm-*/socket.h Option: so-use-ifbufs Aliases: use-ifbufs, useifbufs Type: INT? Option group: SOCKET Phase: PASTSOCKET Platforms: none Sets the SO_USE_IFBUFS socket option. Option: so-useloopback Aliases: useloopback Type: INT? Option group: SOCKET Phase: PASTSOCKET Platforms: FreeBSD, HP-UX, SunOS Sets the SO_USELOOPBACK socket option. Option: so-dgram-errind Aliases: dgram-errind, dgramerrind Logical type: bool? Physical type: INT? Option group: SOCKET Phase: PASTSOCKET Platforms: SunOS Sets the SO_DGRAM_ERRIND flag. Option: so-dontlinger Aliases: dontlinger Type: INT? Option group: SOCKET Phase: PASTSOCKET Platforms: SunOS Sets the SO_DONTLINGER socket option. Option: so-prototype Aliases: prototype Type: INT? Option group: SOCKET Phase: PASTSOCKET Platforms: HP-UX, SunOS Sets the SO_PROTOTYPE socket option. Option: type Type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: all Sets the type of the socket, usually as argument to the socket() or socketpair() call, to . Under Linux, 1 means stream oriented socket, 2 means datagram socket, and 3 means raw socket. Option: protocol-family Aliases: pf Type: STRING Option group: SOCKET Phase: PRESOCKET Platforms: all Forces the use of the specified IP version. can be something like "ip4" or "ip6". Option: fiosetown Logical type: bool Physical type: INT Option group: SOCKET Phase: PASTSOCKET Platforms: FreeBSD, Linux Sets the FIOSETOWN ioctl (in "man 7 socket" called FIOCSETOWN). #Option: ciocspgrp # #Allowed in addresses: SOCKET #Logical type: bool #Physical type: int # #Sets the CIOCSPGRP ioctl. #Option: addr=value # #Allowed in addresses: SOCKET #Type: socket-address # #For client socket, sets the local (bind) address. Not yet implemented. Option: bind=socketaddress Type: STRING Option group: SOCKET Phase: BIND Platforms: all Gives the address to be used in the bind(2) system call. The format of the socketaddress depends on the socket type (see below). For "client" sockets this option inserts a bind(2) call between socket(2) and connect(2) calls. For "server" sockets this option is ignored! For datagram sockets behaviour of this option is currently unspecified. Note: for client sockets in the UNIX domain this option is not useful: with the same address as connect it will conflict with the bind call of the server socket; another address for bind is ignored (with Linux 2.2). For TCP sockets these formats are currently implemented: HOSTNAME HOSTNAME:PORT IPADDR IPADDR:PORT :PORT .PORT Option: connect-timeout=seconds Type: TIMEVAL Option group: SOCKET Phase: PASTSOCKET Platforms: all Abort the connection attempt after the given time with error status. # Option: backlog=value Type: INT Option group: LISTEN Phase: LISTEN Platforms: all Sets the value to be used with the listen(2) system call. The default is 5. It does not seem to work for Linux 2.2; Linux seems to allow much more established connections, but then they stay even after server process shutdown... Option: range=address:mask, range=address/bits Type: STRING Option group: RANGE Phase: ACCEPT Platforms: all Implementation status: only for INET (IP4) addresses Defines a subnet where clients may connect from. If other clients connect the accepted connection is shut down immediately after examination of the client address. If this option is not used, the default is 0.0.0.0:0.0.0.0, allowing arbitrary client addresses. bits is the number of high order bits that must match between the range value and the clients address. Option: tcpwrap, tcpwrap=name Type: STRING_NULL Option group: RANGE Phase: ACCEPT Platforms: (depends on libwrap installation) Uses the rules introduced by Wietse Venema's libwrap (tcpd) library to check if the client is allowed to connect. The configuration files are /etc/hosts.allow and /etc/hosts.deny. See "man 5 hosts_access" for more information. is passed to the wrapper functions as daemon process name. If omitted, the basename of socats invokation (argv[0]) is passed. If both tcpwrap and and range options are applied to an address, both conditions must be fulfilled to allow the connection. Option: hosts-allow, tcpwrap-hosts-allow-table Type: FILENAME Option group: RANGE Phase: ACCEPT Platforms: (depends on libwrap installation) Takes the specified file instead of /etc/hosts.allow. Option: hosts-deny, tcpwrap-hosts-deny-table Type: FILENAME Option group: RANGE Phase: ACCEPT Platforms: (depends on libwrap installation) Takes the specified file instead of /etc/hosts.deny. Option: tcpwrap-etc, tcpwrap-dir Type: FILENAME Option group: RANGE Phase: ACCEPT Platforms: (depends on libwrap installation) Looks for hosts.allow and hosts.deny in the specified directory. Is overriden by options hosts-allow and hosts-deny. ------------------------------------------------------------------------------- IP options Option: ip-options=values Aliases: ipoptions Type: BIN Option group: SOCK_IP Phase: PASTSOCKET Platforms: all Sets the IP_OPTIONS values of the IP socket. For example, to send packets to destination D.D.D.D via a router G.G.G.G you have to specify G.G.G.G as the "normal" destination, and D.D.D.D in the source route: TCP:G.G.G.G:25,ip-options=x890704dddddddd Note that the destination will see G.G.G.G as sender of the packets, and therefore might not return the answers correctly. See RFC791 for detailed specification of IP option fields. Examples: x01 ... nop x8307040a000001 ... loose source route x890b040a000001c0c1c2c3 ... strict source route Note: with source routes, you should not specifiy destination address and hops as defined in RFC791 (first hop as IP header destination address, further hops and final destination in source route) because the (Linux?) kernel changes them to a more intuitive form (final destination as destination in IP header, gateways in source route). So, in destination address give the final destination, and in the source route the gateways! Note: this option may be mulitply applied per socket but the (Linux?) kernel pads each setting with 0' to align the options end to 4 octets. So you should better pad the options data with nops (01) yourself. Option: ip-pktinfo Aliases: ippktinfo, pktinfo Type: INT (should be struct in_pktinfo) Option group: SOCK_IP Phase: PASTSOCKET Platforms: Linux Status: Not completely implemented (ancillary messages are not supported by socat/xio) Pass an IP_PKTINFO ancillary message. Option: ip-recvtos Aliases: iprecvtos, recvtos Logical type: bool Physical type: INT Option group: SOCK_IP Phase: PASTSOCKET Platforms: Linux Status: Not completely implemented (ancillary messages are not supported by socat/xio) Set the IP_RECVTOS socket option which enables IP_TOS ancillary message passing. Option: ip-recvttl Aliases: iprecvttl, recvttl Logical type: bool Physical type: INT Option group: SOCK_IP Phase: PASTSOCKET Platforms: all Implementation status: No results. Set the IP_RECVTTL socket option. Option: ip-recvopts Aliases: iprecvopts, recvopts Logical type: bool Physical type: INT Option group: SOCK_IP Phase: PASTSOCKET Platforms: all Implementation status: No results. Set the IP_RECVOPTS socket option. Option: ip-retopts Aliases: ipretopts, retopts Logical type: bool Physical type: INT Option group: SOCK_IP Phase: PASTSOCKET Platforms: all Implementation status: No results. Set the IP_RETOPTS socket option. Option: ip-tos=value Aliases: iptos=value, tos=value Logical type: byte Physical type: INT Option group: SOCK_IP Phase: PASTSOCKET Platforms: all Sets the TOS (type of service) flags for the outgoing IP headers of the socket. My Linux 2.2 does not allow to set values other than 0 (probably needs some optional kernel features). Option: ip-ttl=value Aliases: ipttl=value, ttl=value Logical type: byte Physical type: INT Option group: SOCK_IP Phase: PASTSOCKET Platforms: all Sets the TTL (time to live) field for the outgoing IP headers of the socket. 0 does not seem to be useful and gives "invalid argument" error in Linux. This option can be used to implement a "poor mans traceroute" in conjunction with tcpdump. Option: ip-hdrincl Aliases: iphdrincl, hdrincl Logical type: bool Physical type: INT Option group: SOCK_IP Phase: PASTSOCKET Platforms: all Set the IP_HDRINCL socket option. User will supply IP header before user data. For raw IP sockets only. Not tested. Option: ip-recverr Aliases: iprecverr, recverr Type: INT Option group: SOCK_IP Phase: PASTSOCKET Platforms: Linux Set the IP_RECVERR socket option. Implementation status: No results. Option: ip-mtu-discover=value Aliases: ipmtudiscover=value, mtudiscover=value Type: INT (0..2) Option group: SOCK_IP Phase: PASTSOCKET Platforms: Linux Sets the IP_MTU_DISCOVER flag of the IP socket. In Linux there are three values defined: 0..dont(never), 1..want(per route), 2..do(always) Option: ip-mtu Aliases: ipmtu, mtu Type: INT Option group: SOCK_IP Phase: PASTSOCKET Platforms: none Sets the MTU (maximal transfer unit) of the socket. In Linux this is a read-only parameter and results in a "protocol not available" error. Option: ip-freebind Aliases: ipfreebind, freebind Logical type: bool Physical type: INT Option group: SOCK_IP Phase: PASTSOCKET Platforms: none Allows the socket to locally bind to any address, even those that are not covered by an interface address, alias address or a local subnet. Even broadcast and multicast addresses are possible. Note: this option has been found on Linux 2.4 in . This file might not be included per default, because it creates errors. To make this option available, "make" socat with the CCOPT environment variable set to "-DIP_FREEBIND=15" Option: ip-router-alert=value Aliases: iprouteralert, routeralert Type: INT Option group: SOCK_IP Phase: PASTSOCKET Platforms: Linux Sets the IP_ROUTER_ALERT socket option. Only works with raw sockets. "Invalid argument" Option: ip-add-membership=multicast-address:interface-address ip-add-membership=multicast-address:interface-name ip-add-membership=multicast-address:interface-index ip-add-membership=multicast-address:interface-address:interface-name ip-add-membership=multicast-address:interface-address:interface-index Aliases: add-membership ip-membership Type: IP_MREQN Option group: SOCK_IP Phase: PASTSOCKET Platforms: all Makes the socket member of the specified multicast group. This is currently only implemented for IPv4. The option takes the IP address of the multicast group and info about the desired network interface. The most common syntax is the first one, while the others are only available on systems that provide tt(struct mreqn) (Linux).nl() The indices of active network interfaces can be shown using the utility procan(). Option: ip-drop-membership Not implemented. #! Option: ipv6-join-group Option: ip-multicast-ttl=byte Aliases: ipmulticastttl, multicastttl Type: BYTE Option group: SOCK_IP Phase: PASTSOCKET Platforms: all Sets the TTL used for outgoing multicast traffic. Default is 1. Option: ip-multicast-loop Aliases: ipmulticastloop, multicastloop Logical type: bool Physical type: INT Option group: SOCK_IP Phase: PASTSOCKET Platforms: all Specifies if outgoing multicast traffic should loop back to the interface. Option: ip-multicast-if=hostname Aliases: multicast-if Type: IP4NAME Option group: SOCK_IP Phase: PASTSOCKET Platforms: all Specifies hostname or address of the network interface to be used for multicast traffic. Option: ip-pktoptions Aliases: ippktoptions, pktoptions, pktopts Type: INT? Option group: SOCK_IP Phase: PASTSOCKET Platforms: Linux Set the IP_PKTOPTIONS socket option. No docu found. Implementation status: "Protocol not available". Option: res-debug Type: BOOL Option group: SOCK_IP Phase: INIT Platforms: all Apply the debug resolver option to all queries of this XIO address. Option: res-aaonly Aliases: aaonly Type: BOOL Option group: SOCK_IP Phase: INIT Platforms: all Apply the aaonly resolver option to all queries of this XIO address. Option: res-usevc Aliases: usevc Type: BOOL Option group: SOCK_IP Phase: INIT Platforms: all Apply the usevc resolver option to all queries of this XIO address. Option: res-primary Aliases: primary Type: BOOL Option group: SOCK_IP Phase: INIT Platforms: all Apply the primary resolver option to all queries of this XIO address. Option: res-igntc Aliases: igntc Type: BOOL Option group: SOCK_IP Phase: INIT Platforms: all Apply the igntc resolver option to all queries of this XIO address. Option: res-recurse Aliases: recurse Type: BOOL Option group: SOCK_IP Phase: INIT Platforms: all Apply the recurse resolver option to all queries of this XIO address. Option: res-defnames Aliases: defnames Type: BOOL Option group: SOCK_IP Phase: INIT Platforms: all Apply the defnames resolver option to all queries of this XIO address. Option: res-stayopen Aliases: stayopen Type: BOOL Option group: SOCK_IP Phase: INIT Platforms: all Apply the stayopen resolver option to all queries of this XIO address. Option: res-dnsrch Aliases: dnsrch Type: BOOL Option group: SOCK_IP Phase: INIT Platforms: all Apply the dnsrch resolver option to all queries of this XIO address. ------------------------------------------------------------------------------- IP6 options Option: ipv6-v6only=value Alias: ipv6only, v6only Type: BOOL Option group: SOCK_IP6 Phase: PASTSOCKET Platforms: FreeBSD, Linux Apply the IPV6_V6ONLY socket option to the file descriptor. This controls if the socket listens only on the IPv6 protocol or also on IPv4. ------------------------------------------------------------------------------- IPAPP (TCP and UDP) options Option: sourceport=value Alias: sp=value Type: 2BYTE Option group: IPAPP (IP_TCP and IP_UDP) Phase: LATE Platforms: all For outgoing (client) TCP and UDP connections, it sets the source port (local port, client side port) of the socket connection. For server type addresses, requires the client to use this sourceport, otherwise socat immediately shuts down the connection. On UNIX class operating systems root privilege are required to set a source port between 1 and 1023 incl. 0 gives a "random" port number >= 1024, which is the default. Option: lowport Type: BOOL Option group: IPAPP (IP_TCP and IP_UDP) Phase: LATE Platforms: all For outgoing (client) TCP and UDP connections, it sets the source to an unused random port between 640 and 1023 incl. On UN*X type operating systems, this requires root privilege, and thus guaranties the peer to be root authorized. With TCP or UDP listen addresses, socat immediately shuts down the connection if the client does not use a sourceport <= 1023. This mechanism can provide limited authorization under some circumstances. ------------------------------------------------------------------------------- TCP options Option: tcp-nodelay Aliases: nodelay Logical type: bool Physical type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: all Sets the TCP_NODELAY flag of the TCP socket. This turns off Nagles algorithm. Option: tcp-maxseg Aliases: maxseg, mss Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: all Limits the MAXSEG (MSS) value of the TCP socket. This option is applied before the connect or listen call, so it is transferred in the SYN packet to the peer socket. Linux client: 0 gives "invalid argument", higher values are used in SYN negotiation, but effective MSS is n-12, at least 8. On AIX, this is a read-only option. Option: tcp-maxseg-late Aliases: maxseg-late, mss-late Type: INT Option group: IP_TCP Phase: CONNECTED Platforms: all Limits the MAXSEG (MSS) value of the TCP socket. This option is applied past the connect or accept call, so it is not transferred as MSS to the peer socket. Observation with Linux 2.2: does not influence the size of packets generated by the local socket. Option: tcp-cork Aliases: cork Logical type: bool Physical type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: Linux Sets the TCP_CORK option. Option: tcp-stdurg Aliases: stdurg Logical type: bool Physical type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: none Applies the TCP_STDURG option with setsockopt. This enables RFC 1122 compliant urgent point handling. Option: tcp-rfc1323 Aliases: rfc1323 Logical type: bool Physical type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: none Applies the TCP_RFC1323 option with setsockopt. This enables RFC1323 TCP enhancements (window scale, timestamp). Option: tcp-keepidle Aliases: keepidle Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: Linux Sets the TCP_KEEPIDLE value of the socket with setsockopt(). Starts keepalive after this period (in seconds?) Option: tcp-keepintvl Aliases: keepintvl Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: Linux Sets the TCP_KEEPINTVL value of the socket with setsockopt(). Interval between keepalives (in seconds?) Option: tcp-keepcnt Aliases: keepcnt Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: Linux Sets the TCP_KEEPCNT value of the socket with setsockopt(). Number of keepalives before death. Option: tcp-syncnt Aliases: syncnt Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: Linux Sets the TCP_SYNCNT value of the socket with setsockopt(). Number of SYN retransmits. Option: tcp-linger2 Aliases: linger2 Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: Linux Sets the TCP_LINGER2 value of the socket with setsockopt(). Life time of orphaned FIN-WAIT-2 state. Option: tcp-defer-accept Aliases: defer-accept Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: Linux Sets the TCP_DEFER_ACCEPT value of the socket with setsockopt(). accept() of the listener will only return when data arrived at the new connection. The value is converted to seconds by some algorithm. Option: tcp-window-clamp Aliases: window-clamp Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: Linux Sets the TCP_WINDOW_CLAMP value of the socket with setsockopt(). "Bound advertised window". Option: tcp-info Aliases: info Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: FreeBSD, Linux Sets the TCP_INFO value of the socket with setsockopt(). Is a read only option, so it always generates an error. Option: tcp-quickack Aliases: quickack Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: Linux Sets the TCP_QUICKACK option with setsockopt(). Option: tcp-md5sig Aliases: md5sig Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: none Enables generation of MD5 digests on the packets. Option: tcp-noopt Aliases: noopt Type: INT Option: group: IP_TCP Phase: PASTSOCKET Platforms: FreeBSD Disables use of TCP options. Option: tcp-nopush Aliases: nopush Type: INT Option: group: IP_TCP Phase: PASTSOCKET Platforms: FreeBSD Sets the TCP_NOPUSH option. Option: tcp-sack-disable Aliases: sack-disable Type: INT Option: group: IP_TCP Phase: PASTSOCKET Platforms: none Disables use the selective acknowledge feature. Option: tcp-signature-enable Aliases: signature-enable Type: INT Option: group: IP_TCP Phase: PASTSOCKET Platforms: none Enables generation of MD5 digests on the packets. Option: tcp-abort-threshold Aliases: abort-threshold Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: HP-UX, SunOS Sets the time to wait for an answer of the peer on an established connection. Option: tcp-conn-abort-threshold Aliases: conn-abort-threshold Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: HP-UX, SunOS Sets the time to wait for an answer of the server during the initial connect. Option: tcp-keepinit Aliases: keepinit Type: INT Option group: IP_TCP Phase: PASTSOCKET Platforms: none Sets the time to wait for an answer of the server during connect() before giving up. Value in half seconds, default is 150 (75s). Option: tcp-paws Aliases: paws Type: BOOL Option group: IP_TCP Phase: PASTSOCKET Platforms: none Enables the "protect against wrapped sequence numbers" feature. Option: tcp-sackena Aliases: sackena Type: BOOL Option group: IP_TCP Phase: PASTSOCKET Platforms: none Enables selective acknowledge. Option: tcp-tsoptena Aliases: tsoptena Type: BOOL Option group: IP_TCP Phase: PASTSOCKET Platforms: none Enables the time stamp option that allows RTT recalculation on existing connections. =============================================================================== SOCKS options Option: socksport Type: STRING Option group: IP_SOCKS4 Phase: LATE Platforms: all Overrides the default socks server port 1080 Option: socksuser Type: NAME Option group: IP_SOCKS4 Phase: LATE Platforms: all Overrides the system derived socks user name ($USER or $LOGNAME or "anonymous") =============================================================================== HTTP options Option: proxyport Type: STRING Option group: HTTP Phase: LATE Platforms: all Overrides the default HTTP proxy port 8080. Option: ignorecr Type: BOOL Option group: HTTP Phase: LATE Platforms: all The HTTP protocol requires the use of CR+NL as line terminator. When a proxy server violates this standard, socat might not understand its answer. This option directs socat to interprete NL as line terminator and to ignore CR in the answer. Nevertheless, socat sends CR+NL to the proxy. Option: proxyauth Type: STRING Option group: HTTP Phase: LATE Platforms: all Provide "basic" authentication to the proxy server. The argument to the option must be the username followed by ':' followed by the password. This string is used with a "Proxy-Authorize: Base" header in base64 encoded form. Option: resolve Type: BOOL Option group: HTTP Phase: LATE Platforms: all Per default, socat sends to the proxy a CONNECT request containing the target hostname. With this option, socat resolves the hostname locally and sends the IP address. =============================================================================== TERMIOS options These options are applied with tcsetattr calls with a struct termios. Attention: Applying these options to stdin/stdout when they refer to your terminal might directly effect your terminal! See Linux:"man 3 termios" and Linux:"man 2 stty" ------------------------------------------------------------------------------- TERMIOS combined modes Option: raw Type: CONST Option group: TERMIOS Phase: FD Platforms: all Is equivalent to ignbrk=0,brkint=0,ignpar=0,parmrk=0,inpck=0,istrip=0,inlcr=0,igncr=0,icrnl=0,ixon=0,ixoff=0,iuclc=0,ixany=0,imaxbel=0,opost=0,isig=0,icanon=0,xcase=0,vmin=1,vtime=0 Option: sane Type: CONST Option group: TERMIOS Phase: FD Platforms: all Is equivalent to cread,ignbrk=0,brkint,inlcr=0,igncr=0,icrnl,ixoff=0,iuclc=0,-ixany=0,imaxbel,opost,olcuc=0,ocrnl=0,onlcr,onocr=0,onlret=0,ofill=0,ofdel=0,nl0,cr0,tab0,bs0,vt0,ff0,isig,icanon,iexten,echo,echoe,echok,echonl=0,noflsh=0,xcase=0,tostop=0,echoprt=0,echoctl,echoke ------------------------------------------------------------------------------- TERMIOS input mode flags Option: ignbrk Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the IGNBRK flag of the terminal driver. Option: brkint Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the BRKINT flag of the terminal driver. Option: ignpar Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the IGNPAR flag of the terminal driver. Option: parmrk Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the PARMRK flag of the terminal driver. Option: inpck Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the INPCK flag of the terminal driver. Enables input parity checking. Option: istrip Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ISTRIP flag of the terminal driver. Strips off the eighth bit. Option: inlcr Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the INLCR flag of the terminal driver. Translates NL to CR on input. Option: igncr Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the IGNCR flag of the terminal driver. Ignores CR character on input. Option: icrnl Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ICRNL flag of the terminal driver. Translates CR to NL on input. This option is ignored when IGNCR is set. Option: iuclc Type: BOOL Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the IUCLC flag of the terminal driver. Changes characters in input from uppercase to lowercase. Option: ixon Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the IXON flag of the terminal driver. Enables XON/XOFF flow control on output (?). Option: ixany Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the IXANY flag of the terminal driver. Enables any character to restart output. Option: ixoff Aliases: tandem Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the IXOFF flag of the terminal driver. Enables XON/XOFF flow control on input. Option: imaxbel Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the IMAXBEL flag of the terminal driver. Rings the bell when the input queue is full. ------------------------------------------------------------------------------- TERMIOS output mode flags Option: opost Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the OPOST flag of the terminal driver. Option: olcuc Type: BOOL Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the OLCUC flag of the terminal driver. Option: onlcr Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ONLCR flag of the terminal driver. Option: ocrnl Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the OCRNL flag of the terminal driver. Option: onocr Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ONOCR flag of the terminal driver. Option: onlret Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ONLRET flag of the terminal driver. Option: ofill Type: BOOL Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the OFILL flag of the terminal driver. Option: ofdel Type: BOOL Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the OFDEL flag of the terminal driver. Option: nldly Type: BOOL Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the NLDLY flag of the terminal driver. 0 sets the value to NL0, and 1 to NL1. See nl0, nl1. Option: nl0 Type: CONST (const bool, always sets 0) Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the field NLDLY to the value NL0. Option: nl1 Type: CONST (const bool, always sets 1) Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the field NLDLY to the value NL1. Option: crdly=value Type: UINT (0..3) Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the field CRDLY to the given value. See cr0, cr1, cr2, cr3. Option: cr0 Type: CONST Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the CRDLY field to the value CR0. See crdly. Option: cr1 Type: CONST Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the CRDLY field to the value CR1. See crdly. Option: cr2 Type: CONST Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the CRDLY field to the value CR2. See crdly. Option: cr3 Type: CONST Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the CRDLY field to the value CR3. See crdly. Option: tab0 Type: CONST Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the horizontal tab delay mask to TAB0. See tabdly. Option: tab1 Type: CONST Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the horizontal tab delay mask to TAB1. See tabdly. Option: tab2 Type: CONST Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the horizontal tab delay mask to TAB2. See tabdly. Option: tab3 Type: CONST Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the horizontal tab delay mask to TAB3. See tabdly. Option: tabdly=value Type: UINT (0..3) Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the field TABDLY to the given value. See tab0, tab1, tab2, and tab3. Option: xtabs Type: CONST Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the horizontal tab delay mask to XTABS. Option: bs0 Type: CONST (0) Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the field BSDLY to the value BS0 Option: bs1 Type: CONST (1) Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the field BSDLY to the value BS1 Option: bsdly Type: BOOL Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the BSDLY flag of the terminal driver. 0 sets the value to BS0, and 1 to BS1. See bs0, bs1. Option: vt0 Type: CONST (0) Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the field VTDLY to the value VT0 Option: vt1 Type: CONST (1) Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the field VTDLY to the value VT1 Option: vtdly Type: BOOL Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the VTDLY flag of the terminal driver. 0 sets the value to VT0, and 1 to VT1. See vt0, vt1. Option: ff0 Type: CONST (0) Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the field FFDLY to the value FF0 See ffdly. Option: ff1 Type: CONST (1) Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the field FFDLY to the value FF1 See ffdly. Option: ffdly Type: BOOL (0..1) Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the FFDLY flag of the terminal driver. 0 sets the value to FF0, and 1 to FF1. See ff0, ff1. ------------------------------------------------------------------------------- TERMIOS control mode flags Option: cs5 Type: CONST Option group: TERMIOS Phase: FD Platforms: all Sets the field CSIZE to the value CS5 Option: cs6 Type: CONST Option group: TERMIOS Phase: FD Platforms: all Sets the field CSIZE to the value CS6 Option: cs7 Type: CONST Option group: TERMIOS Phase: FD Platforms: all Sets the field CSIZE to the value CS7 Option: cs8 Type: CONST Option group: TERMIOS Phase: FD Platforms: all Sets the field CSIZE to the value CS8 Option: csize Type: UINT (0..3) Option group: TERMIOS Phase: FD Platforms: all Sets the field CSIZE. 0..CS5, 1..CS6, 2..CS7, 3..CS8 Option: cstopb Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the flag CSTOPB. Option: cread Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the value of the CREAD flag. Option: parenb Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the PARENB flag of the terminal driver. Option: parodd Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the PARODD flag of the terminal driver. Option: hupcl Aliases: hup Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the HUPCL flag of the terminal driver. Option: clocal Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the CLOCAL flag of the terminal driver. Option: crtscts Type: BOOL Option group: TERMIOS Phase: FD Platforms: FreeBSD, Linux, SunOS Sets the CRTSCTS flag of the terminal driver. Option: b0 (HP-UX, Linux, SunOS) Option: b50 (HP-UX, Linux, SunOS) Option: b75 (HP-UX, Linux, SunOS) Option: b110 (HP-UX, Linux, SunOS) Option: b134 (HP-UX, Linux, SunOS) Option: b150 (HP-UX, Linux, SunOS) Option: b200 (HP-UX, Linux, SunOS) Option: b300 (HP-UX, Linux, SunOS) Option: b600 (HP-UX, Linux, SunOS) Option: b900 (HP-UX) Option: b1200 (HP-UX, Linux, SunOS) Option: b1800 (HP-UX, Linux, SunOS) Option: b2400 (HP-UX, Linux, SunOS) Option: b3600 (HP-UX) Option: b4800 (HP-UX, Linux, SunOS) Option: b7200 (HP-UX) Option: b9600 (HP-UX, Linux, SunOS) Option: b19200 (HP-UX, Linux, SunOS) Option: b38400 (HP-UX, Linux, SunOS) Option: b57600 (HP-UX, Linux, SunOS) Option: b115200 (HP-UX, Linux, SunOS) Option: b230400 (HP-UX, Linux, SunOS) Option: b460800 (HP-UX, Linux, SunOS) Option: b500000 (Linux) Option: b576000 (Linux) Option: b921600 (Linux) Option: b1000000 (Linux) Option: b1152000 (Linux) Option: b1500000 (Linux) Option: b2000000 (Linux) Option: b2500000 (Linux) Option: b3000000 (Linux) Option: b3500000 (Linux) Option: b4000000 (Linux) Type: CONST Option group: TERMIOS Phase: FD Sets the baud rate to the implied value. b0 "hangs up" the connection. Option: ispeed Type: UINT Option group: TERMIOS Phase: FD Platforms: FreeBSD, Linux Sets the input baud rate to the specified value. This works on systems where struct termios has a special c_ispeed field. Option: ospeed Type: UINT Option group: TERMIOS Phase: FD Platforms: FreeBSD, Linux Sets the input baud rate to the specified value. This works on systems where struct termios has a special c_ospeed field. ------------------------------------------------------------------------------- TERMIOS local mode flags Option: isig Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ISIG flag of the terminal driver. Option: icanon Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ICANON flag of the terminal driver. Option: xcase Type: BOOL Option group: TERMIOS Phase: FD Platforms: HP-UX, Linux, SunOS Sets the XCASE flag of the terminal driver. Option: echo Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ECHO flag of the terminal driver. Option: echoe Aliases: crterase Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ECHOE flag of the terminal driver. Option: echok Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ECHOK flag of the terminal driver. Option: echonl Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ECHONL flag of the terminal driver. Option: echoctl Aliases: ctlecho Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ECHOCTL flag of the terminal driver. Option: echoprt Aliases: prterase Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ECHOPRT flag of the terminal driver. Option: echoke Aliases: crtkill Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the ECHOKE flag of the terminal driver. Option: flusho Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the FLUSHO flag of the terminal driver. Option: noflsh Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the NOFLSH flag of the terminal driver. Option: tostop Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the TOSTOP flag of the terminal driver. Option: pendin Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the PENDIN flag of the terminal driver. Option: iexten Type: BOOL Option group: TERMIOS Phase: FD Platforms: all Sets the IEXTEN flag of the terminal driver. ------------------------------------------------------------------------------- TERMIOS options for functional characters Option: vintr=value Aliases: intr=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: tested Sets the value for the VINTR character that interrupts the current process. On UNIX systems the preset value usually is 3 (^C). Option: vquit=value Aliases: quit=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: tested Sets the value for the VQUIT character that quits the current process. On my Linux 2.2 system the preset value is 0x1c (^\). Option: verase=value Aliases: erase=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: tested Sets the value for the VERASE character that erases the last character. On many UNIX systems the preset value is 0x7f. Option: vkill=value Aliases: kill=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: tested Sets the value for the VKILL character that kills (erases) the current line. On my Linux 2.2 system systems the preset value is 0x15 (^U). Option: veof=value Aliases: eof=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: tested Sets the value for the VEOF character that kills indicate end of file. On most UNIX systems the preset value is 0x04 (^D). Option: vtime=value Aliases: time=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: not tested Sets the value of VTIME. See "man 1 stty" / time. On my Linux 2.2 system the preset value is 0. Option: vmin=value Aliases: min=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: not tested Sets the value of VMIN. See "man 1 stty" / time. On my Linux 2.2 system the preset value is 1. Option: vswtc=value Aliases: swtc=value, swtch=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: Linux Status: not tested Sets the value of VSWTC. "Switches to a different shell layer". On my Linux 2.2 system the preset value is 0. Option: vstart=value Aliases: start=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: tested Sets the value for the VSTART character that resumes data flow after a stop. Usually the preset value is 0x11 (^Q). Option: vstop=value Aliases: stop=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: tested Sets the value for the VSTOP character that stops output. Usually the preset value is 0x13 (^S) Option: vsusp=value Aliases: susp=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: tested Sets the value for the VSUSP character that suspends the current foreground process and reactivates the shell. Usually the preset value is 0x1a (^Z) Option: vdsusp=value Aliases: dsusp=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: FreeBSD, HP-UX, SunOS Status: tested Sets the value for the VDSUSP character that suspends the current foreground process and reactivates the shell. Option: veol=value Aliases: eol=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: tested with awkward results Sets the value for the VEOL character that should indicate end of line. Not clear what differentiates it from the return key; xterm window put "xterm" into the input buffer. On my Linux 2.2 system the preset value is 0 (disabled) Option: vreprint=value Aliases: reprint=value, rprnt=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: FreeBSD, Linux, SunOS Status: not tested Sets the value for the VREPRINT character that should reprint the current line. On my Linux 2.2 system the preset value is 0x12 (^R). Nevertheless, bash enters backward search mode. Option: vdiscard=value Aliases: discard=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: FreeBSD, Linux, SunOS Status: not tested Sets the value for the VDISCARD character. On my Linux 2.2 system the preset value is 0x0f (^O) Option: vwerase=value Aliases: werase=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: tested Sets the value for the VWERASE character that erases the last word. On my Linux 2.2 system the preset value is 0x17 (^W) Option: vlnext=value Aliases: lnext=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: tested Sets the value for the VLNEXT character that lets the next input character raw (not interpreted). On my Linux 2.2 system the preset value is 0x16 (^V) Option: veol2=value Aliases: eol2=value Type: BYTE Option group: TERMIOS Phase: FD Platforms: all Status: not tested Sets the value for the VEOL2 character. On my Linux 2.2 system the preset value is 0 (disabled). =============================================================================== READLINE options Option: history-file=filename Aliases: history=filename Type: STRING Option group: READLINE Phase: LATE Platforms: (depends on libreadline installation) Without this option, the readline address uses only a per process history list. With this option, socat tries to read history lines during initialization from the given file, and on termination writes the old and new lines to the file. NOTE: currently, no mechanism is implemented for limiting the length of the history file. NOTE: filename must be a valid relativ or absolute path; "~" is not supported! Option: noprompt Type: BOOL Option group: READLINE Phase: LATE Platforms: all Since version 1.3.3, socat per default tries to determine a prompt - that is then passed to the readline call - by remembering the last incomplete line of the output. With this option, socat does not pass a prompt to the readline call, so it might set the cursor to the first column of the terminal. Option: noecho Type: STRING Option group: READLINE Phase: LATE Platforms: all Specifies a regular pattern for a prompt that prevents the following input line from being displayed on the screen and from being added to the history. The prompt is defined as the text that was output to the readline address after the lastest newline character and before an input character was typed. The pattern is a regular expression, e.g. "^[Pp]assword:.*$" or "([Uu]ser:|[Pp]assword:)". See regex(7) for details. Option: prompt Type: STRING Option group: READLINE Phase: LATE Platforms: all Passes the string as prompt to the readline function. readline prints this prompt when stepping through the history. If this string matches a constant prompt issued by an interactive program on the other socat address, consistent look and feel can be archieved. =============================================================================== OPENSSL options Option: openssl-cipherlist=string Aliases: cipherlist=string, ciphers=string, cipher=string Type: STRING Option group: OPENSSL Phase: SPEC Platforms: (depends on openssl installation) Selects the list of ciphers that may be used for the connection. See the man page ciphers(1), section CIPHER LIST FORMAT, for detailed information about syntax, values, and default of the cipherlist string. Several cipher strings may be given, separated by ':'. Some simple cipher strings: 3DES Uses a cipher suite with triple DES. MD5 Uses a cipher suite with MD5. aNULL Uses a cipher suite without authentication. NULL Does not use encryption. HIGH Uses a cipher suite with "high" encryption. Note that the peer must support the selected property, or the negotiation will fail. Option: openssl-method=string Aliases: method=string Type: STRING Option group: OPENSSL Phase: SPEC Platforms: (depends on openssl installation) Sets the protocol version to be used. Valid strings (not case sensitive) are: SSLv2 Select SSL protocol version 2. SSLv3 Select SSL protocol version 3. SSLv23 Select SSL protocol version 2 or 3. This is the default when this option is not provided. TLSv1 Select TLS protocol version 1. Option: openssl-verify=bool Aliases: verify=bool Type: BOOL Option group: OPENSSL Phase: SPEC Platforms: (depends on openssl installation) Controls check of the peer's certificate. Default is 1 (true). Disabling verify might open your socket for everyone! Option: openssl-certificate=file Aliases: cert=file Type: FILENAME Option group: OPENSSL Phase: SPEC Platforms: (depends on openssl installation) Specifies the file with the certificate. The certificate must be in OpenSSL format (*.pem). With openssl-listen, this option is strongly recommended: except with cipher aNULL, "no shared ciphers" error might occur when no certificate is given. Option: openssl-key=file Aliases: key Type: FILENAME Option group: OPENSSL Phase: SPEC Platforms: (depends on openssl installation) Specifies the file with the private key. The private key may be in this file or in the file given with the ref(cert) option. The party that has to proof that it is the owner of a certificate needs the private key. Option: openssl-cafile=file Aliases: cafile Type: FILENAME Option group: OPENSSL Phase: SPEC Platforms: (depends on openssl installation) Specifies the file with the trusted (root) authority certificates. The file must be in PEM format and should contain one or more certificates. Option: openssl-capath=directory Aliases: capath Type: FILENAME Option group: OPENSSL Phase: SPEC Platforms: (depends on openssl installation) Specify the directory with the trusted (root) certificates. The directory must contain certificates in PEM format and their hashes (see OpenSSL documentation) Option: openssl-egd=file Aliases: egd Type: FILENAME Option group: OPENSSL Phase: SPEC Platforms: (depends on openssl installation) On some systems, openssl requires an explicit source of random data. Specify the socket name where an entropy gathering daemon like egd provides random data, e.g. /dev/egd-pool. Option: openssl-pseudo Aliases: pseudo Type: BOOL Option group: OPENSSL Phase: SPEC Platforms: (depends on openssl installation) On systems where openssl cannot find an entropy source and where no entropy gathering daemon can be utilized, this option activates a mechanism for providing pseudo entropy. This is archieved by taking the current time in microseconds for feeding the libc pseudo random number generator with an initial value. openssl is then feeded with output from random calls. NOTE:This mechanism is not sufficient for generation of secure keys! Option: openssl-fips Aliases: fips Type: BOOL Option group: BOOL Phase: SPEC Platforms: (depends on OpenSSL installation and FIPS implementation) Enables FIPS mode if compiled in. For info about the FIPS encryption implementation standard see http://oss-institute.org/fips-faq.html. This mode might require that the involved certificates are generated with a FIPS enabled version of openssl. Setting or clearing this option on one socat address affects all OpenSSL addresses of this process. Option: openssl-compress Aliases: compress Type: STRING Option group: OPENSSL Phase: SPEC Platforms: (depends on openssl installation) Enable or disable the use of compression for a connection. Setting this to "none" disables compression, setting it to "auto" lets OpenSSL choose the best available algorithm supported by both parties. The default is to not touch any compression-related settings. NOTE: Requires OpenSSL 0.9.8 or higher. NOTE: Disabling compression with OpenSSL 0.9.8 affects all new connections in the same process. =============================================================================== Application specific address options Option: ignoreeof Aliases: ignoreof Type: BOOL Option group: APPL Phase: LATE Platforms: all This option has to be supported by the application. For socat it means that an EOF condition on this data source does not trigger termination procedures, but instead the read/write loop waits for one second and then tries to read more input data. This behaviour emulates "tail -f" and might not be useful for all kinds of input devices, but regular files and /dev/null are good candidates. Termination of socat then can only occur by EOF condition of the other input device, an error, or by external events. Option: cr Type: CONST Option group: APPL Phase: LATE Platforms: all The appropriate data endpoint uses CR ('\r', 0x0d) as line terminator character. Convert data to and from this stream appropriately. This is useful for, e.g., modems. Option: crnl Aliases: crlf Type: CONST Option group: APPL Phase: LATE Platforms: all The appropriate data endpoint uses CR+LF ("\r\n", 0x0d0a ) as line terminator string. Convert data to and from this stream appropriately. This is useful for, e.g., TCP protocols like SMTP and FTP. Option: readbytes=num Aliases: bytes Type: SIZE_T Option group: APPL Phase: LATE Platforms: all socat reads only so many bytes from this address (the address provides only so many bytes for transfer and pretends to be at EOF afterwards). Option: lockfile=filename Type: FILENAME Option group: APPL Phase: INIT Platforms: all If lockfile exists, exits with error. If lockfile does not exist, creates it and continues; removes lockfile on exit. Option: waitlock=filename Type: FILENAME Option group: APPL Phase: INIT Platforms: all If lockfile exists, waits until it disappears. When lockfile does not exist, creates it and continues; removes lockfile on exit. =============================================================================== RETRY options Option: retry= Type: UINT Option group: RETRY Phase: INIT Platforms: all Number of retries before the connection or listen attempt is aborted. Default is 0, which means just one attempt. Option: interval= Type: TIMESPEC Option group: RETRY Phase: INIT Platforms: all Time between consecutive attempts (seconds). Default is 1 second. Option: forever Type: BOOL Option group: RETRY Phase: INIT Platforms: all Performs an unlimited number of retry attempts. =============================================================================== EXT2 options Option: ext2-secrm= Aliases: secrm= Type: BOOL Option group: REG Phase: FD Platforms: Linux Sets the secrm file attribute on the file. Option: ext2-unrm= Aliases: unrm= Type: BOOL Option group: REG Phase: FD Platforms: Linux Sets the unrm file attribute on the file. Option: ext2-compr= Aliases: compr= Type: BOOL Option group: REG Phase: FD Platforms: Linux Sets the compr file attribute on the file. Option: ext2-sync= Type: BOOL Option group: REG Phase: FD Platforms: all Sets the sync file attribute on the file. Option: ext2-immutable= Aliases: immutable= Type: BOOL Option group: REG Phase: FD Platforms: Linux Sets the immutable file attribute on the file. Option: ext2-append= Type: BOOL Option group: REG Phase: FD Platforms: all Sets the append file attribute on the file. Option: ext2-nodump= Aliases: nodump= Type: BOOL Option group: REG Phase: FD Platforms: Linux Sets the nodump file attribute on the file. Option: ext2-noatime= Type: BOOL Option group: REG Phase: FD Platforms: Linux Sets the noatime file attribute on the file. Option: ext2-journal-data= Aliases: journal-data= Type: BOOL Option group: REG Phase: FD Platforms: Linux Sets the journal-data file attribute on the file. Option: ext2-notail= Aliases: notail= Type: BOOL Option group: REG Phase: FD Platforms: none Sets the notail file attribute on the file. Option: ext2-dirsync= Aliases: dirsync= Type: BOOL Option group: REG Phase: FD Platforms: Linux Sets the dirsync file attribute on the file. Option: ext2-topdir= Aliases: topdir= Type: BOOL Option group: REG Phase: FD Platforms: Linux Sets the topdir file attribute on the file. =============================================================================== Appendix: generating a sandbox (chroot environment) While it is possible to generate a sandbox almost anywhere in the file system, I recommend to use a file system that has been mounted with restrictions, especially nosuid and maybe nodev, or even ro. You may mount a dedicated file system for the sandbox, so it gets a little harder for the guests to determine for sure if they are within a sandbox when using "ls -id /" The following desribes typical steps for generating a sandbox. Depending on your operating system, application, and security requirements, your mileage may vary. With the below steps, you will be able to run some check programs to play around with the sandbox. I Installation 1) Create a sandbox group - but give it and all following "sandbox" ids a more cryptic name! 2) Create a sandbox user, only in sandbox group. If this user must never login, give it a useless shell like /bin/false 3) Check the sandbox home directory (e.g. /home/sandbox) and save and remove all .profile, public_html/ etc. 4) Optionally mount a new file system over the new home directory 5) Generate subdirectories bin, lib, etc, usr, usr/bin, usr/lib. Set their permissions and ownership equal to the original directories (or use only root.root) 6) Generate subdirectory home/sandbox (or similarly; like sandbox home) 7) Generate etc/passwd with users sandbox and root, but do not store original password hashes there! 8) Generate etc/group with only groups sandbox and root (or system on AIX) 9) Copy test programs and utilities to bin, e.g. su, id, ls, mount, strace (but without SUID/SGID) 10) Copy the required shared libraries and the shared library loader to their directories. On Linux, e.g. /lib/ld-linux.so.2, /lib/libnss_compat.so.2 Note: it is often difficult to find out what shared libraries are (still) not installed in the sandbox. The programs invoked in the sandbox typically do not give useful error messages. If chroot's exec call gives an error like "no such file or directory", and you do not know if it even found the program itself, then remove the test programs execute permission; the error message should change to "execute permission denied" or so. Redo the execute permissions and look for the shared libraries... List required libraries of a program: Linux: ldd AIX: xdb map 11) For testing purposes, install id, ls, su, mount, strace, and maybe sh in the sandbox. Test it. II Customization 12) Copy your applications, configuration files, and data to the appropriate directories within the sandbox. Test function of the application in the sandbox, and add missing files and libraries. If an application program gets killed immediately after start, it might miss a shared library. III Cleanup, check 13) Implement your own tricks how to improve security of the sandbox 14) Remove test programs like bin/sh, id, ls, mount, strace =============================================================================== socket types, modes and their security features: IP.v4.TCP.connect IP.v4.TCP.listen range tcpwrap srcport lowport IP.v4.UDP.connect IP.v4.UDP.listen range tcpwrap srcport lowport IP.v4.UDP.sendto IP.v4.UDP.recvfrom range tcpwrap srcport lowport IP.v4.UDP.recv range tcpwrap srcport lowport IP.v4.raw.sendto IP.v4.raw.recvfrom range tcpwrap IP.v4.raw.recv range tcpwrap IP.v6.TCP.connect IP.v6.TCP.listen range tcpwrap srcport lowport IP.v6.UDP.connect IP.v6.UDP.listen range tcpwrap srcport lowport IP.v6.UDP.sendto IP.v6.UDP.recvfrom range tcpwrap srcport lowport IP.v6.UDP.recv range tcpwrap srcport lowport IP.v6.raw.sendto IP.v6.raw.recvfrom range tcpwrap IP.v6.raw.recv srcport lowport UNIX.stream.connect UNIX.stream.listen UNIX.dgram.sendto UNIX.dgram.recvfrom UNIX.dgram.recv OPENSSL.connect OPENSSL.TCP4.listen range tcpwrap srcport lowport OPENSSL.TCP6.listen range tcpwrap srcport lowport =============================================================================== Missing features and Caveats: . no support for SIGIO mechanism . no support for socket ancillary messages . Probably many ioctls not implemented due to missing documentation . only limited implementation of raw sockets and interfaces, . no support for high level sockets beyond UNIX, INET, and INET6 domains socat-1.7.3.1/doc/socat-multicast.html0000644000201000020100000003513312161506654017342 0ustar gerhardgerhard IP Multicasting with Socat

IP Multicasting with Socat

Introduction

Multicasting (and broadcasting which is also discussed in this article) provides a means to direct a single packet to more than one host. Special addresses are defined for this purpose and are handled specially by network adapters, networking hardware, and IP stacks.

IPv4 specifications provide broadcasting and multicasting; IPv6 provides multicasting but replaces broadcasting by special multicast modes. UNIX domain sockets do not know broadcasting or multicasting.

The following examples use UDP/IPv4 only. However, they can easily be adapted for raw IPv4 sockets. IPv6 multicasting has not yet been successfully used with socat; please contact the author if you have positive experiences or ideas that go beyond IPV6_ADD_MEMBERSHIP.

All multicast examples presented in this document use multicast address 224.1.0.1; it can be replaced by any valid IPv4 multicast address (except all-systems).

We assume a local network with address 192.168.10.0 and mask 255.255.255.0; an eventual "client" has 192.168.10.1, example "server" and example peer have 192.168.10.2 in all examples. Change these addresses and mask to your own requirements.

All the following examples work bidirectionally except when otherwise noticed. For "clients" we just use STDIO, and for "servers" we use EXEC:hostname which ingores its input but shows us which host the reply comes from. Replace these socat addresses with what is appropriate for your needs (e.g. shell script invocations). Port 6666 can be replaced with any other port (but for ports < 1024 root privilege might be required).

Different kinds of broadcast addresses exist: 255.255.255.255 is local network only; for the IPv4 network 192.168.10.0/24 the "official" broadcast address is 192.168.10.255; the network address 192.168.10.0 is also interpreted as broadcast by some hosts. The two latter forms are routed by gateways. In the following examples we only use broadcast address 192.168.10.255.

Example 1: Multicast client and servers

This example builds something like a "supervisor" or "client" that communicates with a set of "servers". The supervisor may send packets to the multicast address, and the servers may send response packets. Note that the servers would also respond to other clients' requests.

Multicast server:

socat UDP4-RECVFROM:6666,ip-add-membership=224.1.0.1:192.168.10.2,fork EXEC:hostname

This command receives multicast packets addressed to 224.1.0.1 and forks a child process for each. The child processes may each send one or more reply packets back to the particular sender. 192.168.10.2 means the address of the interface where multicasts should be received. Run this command on a number of hosts, and they will all respond in parallel.

Multicast client:

socat STDIO UDP4-DATAGRAM:224.1.0.1:6666,range=192.168.10.0/24

This process transfers data from stdin to the multicast address, and transfers packets received from the local network to stdout. It does not matter in which direction the first data is passed. A packet from the network is accepted by the IP stack for our socket if:

  • it is an incoming UDP/IPv4 packet
  • its target port matches the local port assigned to the socket (random)
  • its target address matches one of the hosts local addresses or the any-host multicast address
Of these packets, socat handles only those matching the following criteria:
  • the source address is within the given range
  • the source port is 6666

Example 2: Broadcast client and servers

Broadcast server:

socat UDP4-RECVFROM:6666,broadcast,fork EXEC:hostname

This command receives packets addressed to a local broadcast address and forks a child process for each. The child processes may each send one or more reply packets back to the particular sender. Run this command on a number of hosts, and they will all respond in parallel.

Broadcast client:

socat STDIO UDP4-DATAGRAM:192.168.10.255:6666,broadcast,range=192.168.10.0/24

This process transfers data from stdin to the broadcast address, and transfers packets received from the local network to stdout. It does not matter in which direction the first data is passed. A packet from the network is accepted by the IP stack for our socket if:

  • it is an incoming UDP/IPv4 packet
  • its target port matches the local port assigned to the socket (6666)
  • its target address matches one of the hosts local addresses or the any-host multicast address, or a local broadcast address
Of these packets, socat handles only those matching the following criteria:
  • the source address is within the given range
  • the source port is 6666

The broadcast option is only required for sending or receiving local broadcasts.

Example 3: Multicast peers

It is possible to combine multicast sender and receiver in one socat address. This allows to start processes on different hosts on the local network that will communicate symmetrically, so each process can send messages that are received by all the other ones.

socat STDIO UDP4-DATAGRAM:224.1.0.1:6666,bind=:6666,range=192.168.10.0/24,ip-add-membership=224.1.0.1:192.168.10.2

This command is valid for host 192.168.10.2; adapt this address to the particular interface addresses of the hosts.

Starting this process opens a socket on port 6666 that will receive packets directed to multicast address 224.1.0.1. Only packets with matching source address and source port 6666 will be handled though. When this process sends data to the network the packets will be addressed to 224.1.0.1:6666 and have a source address of 192.168.10.2:6666, matching the accept criteria of the peers on the local network.

Note: this command receives the packets it just has sent; add option ip-multicast-loop=0 if this in undesired.

Example 4: Broadcast peers

Just as with multicast, it is possible to combine broadcast sender and receiver in one socat address.

socat STDIO UDP4-DATAGRAM:255.255.255.255:6666,bind=:6666,range=192.168.10.0/24,broadcast

Starting this process opens a socket on port 6666 that will receive packets directed to a local broadcast addresses. Only packets with matching source address and source port 6666 will be handled though. When this process sends data to the network the packets will be addressed to 255.255.255.255:6666 and have a source address of 192.168.10.2:6666, matching the accept criteria of the peers on the local network.

Note: this command receives the packets it just has sent; there does not seem to exist a simple way to prevent this.

Troubleshooting

If you do not get an error message during operation, but the packets do not reach the target processes, use tcpdump to see if the packets have the correct source and destination addresses and ports, and if they leave and enter the hosts as expected.

The following subsections discuss some typical sources of trouble.

IP filters

If you do not succeed in receiving multicast or broadcast packets, check if iptables are activated on the receiving or sending host. They might be configured to disallow this traffic.

Do not bind()

When using multicast communications, you should not bind the sockets to a specific IP address. It seems that the (Linux) IP stack compares the destination address with the bind address, not taking care of the multicast property of the incoming packet.

Routing

When you receive an error like:

... E sendto(3, 0x80c2e44, 4, 0, AF=2 224.1.0.1:6666, 16): Network is unreachable

you have a routing problem. The (Linux) IP stack seems to handle multicast addresses just like unicast addresses when determining their route (interface and gateway), i.e. the routing table needs an entry that somehow matches the target address.

For the same reason, multicast packets will probably leave your host on the interface with the default route if it is specified.

Set a multicast/broadcast route with the following command (Linux):

route add -net 224.0.0.0/3 gw 192.168.10.2

ALL-SYSTEMS multicast address

224.0.0.1 is the all-systems multicast address: all datagram sockets appear to be automatically member of this group on all interfaces. This membership cannot be dropped on Linux (you need iptables to filter packets).

(In)Security

When you use the above examples you should understand that all datagram sockets without exception accept all packets that are directly addressed to them; the multi- and broadcast receiving features are just extensions to this functionality. socat currently has no means to handle incoming packets differently whether they are addressed to unicast, multicast, or broadcast addresses. However, for EXEC'd scripts socat can provide this info in environment variables.

Authentication or encryption are not available.

It is very easy to fake the source address of UDP (or raw IP) packets. You should understand whether your network is protected from address spoofing attacks.

Broadcast and multicast traffic can trivially be received by any host on the local network.

History

Starting with version 1.5.0, socat provides a set of address types that allow various operations on datagram oriented sockets:
SENDTO
send packets to a remote socket and receive packet from this remote socket only
RECV
receive all packets that arrive on the local socket, but do not reply
RECVFROM
receive all packets that arrive on the local socket, and reply using child processes

These modes already enable several different client/server oriented operations. Moreover, the SENDTO addresses can send to multicast and broadcast addresses (the latter requires the broadcast option though). RECV and RECVFROM also would accept packets addressed to a local broadcast address (with option broadcast) or the all-systems multicast address.

These address types had, however, two major caveats:

  • Missing control of multicast group membership in the RECV and RECVFROM addresses
  • The SENDTO address would never accept a reply to a broadcast or multicast addressed packet because the source address of incoming replies would not match the target address of the sent packet.

New Features in socat 1.6.0

socat version 1.6.0 addresses these problems and provides a new more generic datagram address type (*-DATAGRAM) and the new address option IP-ADD-MEMBERSHIP.

Please note that the new features could not be successfully tested on IPv6; these sections thus apply to IPv4 only.

New Features in socat 1.7.0

socat version 1.7.0 helps to find more information about incoming packets in environment variables that can be used in scripts or programs invoked by socat. The option ip-pktinfo (on non-BSD systems) or ip-recvdstaddr (on BSD systems) is required to get basic information about incoming packets.

Example: Start a receiver of the following form (tried on Linux):

socat -u UDP-RECVFROM:8888,reuseaddr,ip-add-membership=224.1.0.1:192.168.10.2,ip-pktinfo,fork SYSTEM:export

Then send a multicast packet from the client:

echo |socat -u STDIO UDP-DATAGRAM:224.1.0.1:8888

On the server the following text should appear (only interesting lines shown):

export SOCAT_IP_DSTADDR="224.1.0.1"
export SOCAT_IP_IF="eth0"
export SOCAT_IP_LOCADDR="192.168.10.2"
export SOCAT_PEERADDR="192.168.10.1"
export SOCAT_PEERPORT="41159"

SOCAT_IP_IF shows the interface where the packet entered the server; SOCAT_IP_LOCADDR shows the IP address of this interface; SOCAT_IP_DSTADDR shows the target address of the packet; SOCAT_PEERADDR and SOCAT_PEERPORT are the client socket values.

More info about socat datagrams

Links regarding this tutorial

address UDP4-DATAGRAM
address UDP4-RECVFROM
option range
option broadcast
option ip-add-membership
option fork
option bind

Other datagram addresses

address UDP4-RECV: pure datagram receiver
address UDP4-SENDTO: communicate with one peer address
address UDP4-LISTEN: pseudo stream server
address UDP4-CONNECT: pseudo stream client

Related socat option groups

IP options
socket options
file descriptor options
range options
child process options

References

socat home page
socat man page
multicasting on Wikipedia
broadcasting on Wikipedia

This document was last modified in May 2009.
Copyright: Gerhard Rieger 2007-2009
License: GNU Free Documentation License (FDL)

socat-1.7.3.1/xioexit.c0000644000201000020100000000123212460670272014421 0ustar gerhardgerhard/* source: xioexit.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for the extended exit function */ #include "xiosysincludes.h" #include "compat.h" #include "xio.h" #include "error.h" /* this function closes all open xio sockets on exit, if they are still open. It must be registered with atexit(). */ void xioexit(void) { int i; diag_in_handler = 0; Debug("starting xioexit()"); for (i = 0; i < XIO_MAXSOCK; ++i) { if (sock[i] != NULL && sock[i]->tag != XIO_TAG_INVALID) { xioclose(sock[i]); } } Debug("finished xioexit()"); } socat-1.7.3.1/README.FIPS0000644000201000020100000000513710573352764014222 0ustar gerhardgerhard David Acker has patched socat to add OpenSSL FIPS. See http://oss-institute.org/fips-faq.html and http://linuxdevices.com/news/NS4742716157.html for more information. The patch that is integrated into socat 1.5 does the following: Add support for LDFLAGS in Makefile. LDFLAGS can be specified on the configure command line and then will be carried over into the make. Add fips support. Requires OpenSSL 0.9.7j-fips-dev from http://www.openssl.org/source/OpenSSL-fips-1.0.tar.gz built with fips support turned on. use ./Configure fips [os-arc], for example ./Configure fips linux-pentium The LDFLAGS is needed to point a build against a library located in a non-standard location. For example, if you download and build openssl manually, it gets installed in /usr/local/ssl by default. The FIPS support patches involve adding an option to enable/disable fips in configure (enabled by default), checking the system for FIPS support during configure, and then adding a fips option to socats openssl address to turn on fips mode. The openssl binary uses an environment variable instead of a command line flag. FIPS mode requires both a compile time flag of OPENSSL_FIPS and a runtime call of FIPS_mode_set(1). Fips mode requires building with the fipsld script provided by OpenSSL. FIPS tracks the pid of the process that initializes things so after a fork, the child must reinitialize. When the ssl code detects a forks occur and if FIPS mode was enabled, it reinitializes FIPS by disabling and then enabling it again. To produce Davids enviroment, do the following: To build openssl download OpenSSL 0.9.7j-fips-dev from http://www.openssl.org/source/OpenSSL-fips-1.0.tar.gz tar xzf OpenSSL-fips-1.0.tar.gz cd openssl ./Configure fips linux-pentium make make test (become root) make install This leaves an install in /usr/local/ssl To build socat: setup directory with socat 1.5 or higher. cd socat-1.5.0.0 ./configure CPPFLAGS=-I/usr/local/ssl/include/ LDFLAGS=-L/usr/local/ssl/lib/ FIPSLD=/usr/local/ssl/bin/fipsld make (become root) make install To run tests we make sure the new openssl is used: export PATH=/usr/local/ssl/bin:$PATH ./test.sh fips There are two tests in test.sh that depend on fips: OPENSSL_FIPS_BOTHAUTH performs a SSL client to server connection with certificate based authentication in both directions. If it works FIPS mode seems to be ok. OPENSSL_FIPS_SECURITY generates a certificaet/key pair without fips support. It then tries a SSL connection in "normal" mode which is expected to work. In the second phase it uses fips mode with these credentials which is expected to fail. If so, the test succeeded. socat-1.7.3.1/sysincludes.h0000644000201000020100000001163012460670272015305 0ustar gerhardgerhard/* source: sysincludes.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __sysincludes_h_included #define __sysincludes_h_included 1 #if HAVE_STDBOOL_H #include /* bool, true, false */ #endif #if HAVE_INTTYPES_H #include /* uint16_t */ #endif #if HAVE_LIMITS_H #include /* USHRT_MAX */ #endif #include /* HUGE_VAL */ #include #include /* for msg() */ #include /* strerror(), strchr() */ #if HAVE_STRINGS_H #include /* strcasecmp(), bzero() for FD_ZERO */ #endif #include /* malloc(), free() */ #include /* isdigit() */ #include /* FILE */ #include /* errno */ #if HAVE_SYSLOG_H #include /* openlog(), syslog(), closelog() */ #endif #include /* signal(), SIGPIPE, SIG_IGN */ #include /* struct timeval, strftime(), clock_gettime() */ #if 0 #include /* struct timeb */ #endif #if HAVE_UNISTD_H #include /* select(), read(), write(), stat(), fork() */ #endif #if HAVE_PWD_H #include /* getpwnam() */ #endif #if HAVE_GRP_H #include /* getgrnam() */ #endif #if HAVE_PTY_H && (_WITH_TERMIOS || HAVE_OPENPTY) #include #endif #if HAVE_SYS_PARAM_H #include /* Linux 2.4 NGROUPS */ #endif #if HAVE_SYS_TIME_H #include /* select(); OpenBSD: struct timespec */ #endif #if HAVE_STDINT_H #include /* uint8_t */ #endif #if HAVE_SYS_TYPES_H #include /* pid_t, select(), socket(), connect(), open(), u_short */ #endif #if HAVE_POLL_H #include /* poll() */ #elif HAVE_SYS_POLL_H #include /* poll() */ #endif #if HAVE_SYS_SOCKET_H #include /* struct sockaddr, struct linger, socket(), connect() */ #endif #if HAVE_SYS_UIO_H #include /* struct iovec */ #endif #if HAVE_SYS_STAT_H #include /* struct stat, stat(), open() */ #endif #if HAVE_SYS_WAIT_H #include /* WNOHANG */ #endif #if HAVE_FCNTL_H #include /* open(), O_RDWR */ #endif #if HAVE_NETDB_H && (_WITH_IP4 || _WITH_IP6) #include /* struct hostent, gethostbyname() */ #endif #if HAVE_SYS_UN_H && WITH_UNIX #include /* struct sockaddr_un, unix domain sockets */ #endif #if HAVE_SYS_IOCTL_H #include /* ioctl() */ #endif #if HAVE_SYS_SELECT_H #include /* select(), fdset on AIX 4.1 */ #endif #if HAVE_SYS_FILE_H #include /* LOCK_EX, on AIX directly included */ #endif #if WITH_IP4 || WITH_IP6 # if HAVE_NETINET_IN_H #include /* struct sockaddr_in, htonl() */ # endif #endif /* _WITH_SOCKET */ #if _WITH_SOCKET && (_WITH_IP4 || _WITH_IP6) # if HAVE_NETINET_IN_SYSTM_H #include /* Solaris, FreeBSD: n_long */ # endif # if HAVE_NETINET_IP_H #include /* struct ip - past netinet/in.h on AIX! */ # endif # if HAVE_NETINET_TCP_H #include /* TCP_RFC1323 */ # endif # if HAVE_NETINET_IP6_H && _WITH_IP6 #include # endif # if HAVE_NETINET6_IN6_H && _WITH_IP6 #include # endif #include /* Linux: inet_aton() */ #if HAVE_ARPA_NAMESER_H #include /* req for resolv.h (esp. on MacOSX) */ #endif #include #if HAVE_NET_IF_DL_H #include /* FreeBSD: struct sockaddr_dl */ #endif #if HAVE_RESOLV_H #include /* _res */ #endif #endif /* _WITH_IP4 || _WITH_IP6 */ /*#include */ #if HAVE_NET_IF_H #include #endif /* HAVE_NET_IF_H */ #if HAVE_LINUX_TYPES_H #include /* __u32 for linux/errqueue.h */ #endif #if HAVE_LINUX_ERRQUEUE_H #include /* struct sock_extended_err */ #endif #if HAVE_NETPACKET_PACKET_H #include #endif #if HAVE_NETINET_IF_ETHER_H #include #endif #if HAVE_LINUX_IF_TUN_H #include #endif #if HAVE_TERMIOS_H && _WITH_TERMIOS #include #endif #if HAVE_SYS_UTSNAME_H #include /* uname(), struct utsname */ #endif #if HAVE_UTIL_H #include /* NetBSD, OpenBSD openpty() */ #endif #if HAVE_BSD_LIBUTIL_H #include /* FreeBSD openpty() */ #elif HAVE_LIBUTIL_H #include /* FreeBSD openpty() */ #endif #if HAVE_SYS_STROPTS_H #include /* SunOS I_PUSH ... */ #endif #if HAVE_REGEX_H #include #endif #if HAVE_LINUX_FS_H #include /* somewhere required for ext2_fs.h */ #endif #if HAVE_LINUX_EXT2_FS_H #include /* Linux ext2 filesystem definitions */ #endif #if WITH_READLINE # if HAVE_READLINE_READLINE_H #include # endif # if HAVE_READLINE_HISTORY_H #include # endif #endif /* WITH_READLINE */ #if WITH_OPENSSL #include #include #include #endif #endif /* !defined(__sysincludes_h_included) */ socat-1.7.3.1/xio-creat.c0000644000201000020100000000455311453022152014621 0ustar gerhardgerhard/* source: xio-creat.c */ /* Copyright Gerhard Rieger 2001-2006 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of create type */ #include "xiosysincludes.h" #if WITH_CREAT #include "xioopen.h" #include "xio-named.h" #include "xio-creat.h" static int xioopen_creat(int arg, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); /*! within stream model, this is a write-only address - use 2 instead of 3 */ const struct addrdesc addr_creat = { "create", 3, xioopen_creat, GROUP_FD|GROUP_NAMED|GROUP_FILE, 0, 0, 0 HELP(":") }; /* retrieve the mode option and perform the creat() call. returns the file descriptor or a negative value. */ static int _xioopen_creat(const char *path, int rw, struct opt *opts) { mode_t mode = 0666; int fd; retropt_modet(opts, OPT_PERM, &mode); if ((fd = Creat(path, mode)) < 0) { Error3("creat(\"%s\", 0%03o): %s", path, mode, strerror(errno)); return STAT_RETRYLATER; } return fd; } static int xioopen_creat(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3) { const char *filename = argv[1]; int rw = (xioflags&XIO_ACCMODE); bool exists; bool opt_unlink_close = false; int result; /* remove old file, or set user/permissions on old file; parse options */ if ((result = _xioopen_named_early(argc, argv, fd, groups, &exists, opts)) < 0) { return result; } retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); if (opt_unlink_close) { if ((fd->stream.unlink_close = strdup(filename)) == NULL) { Error1("strdup(\"%s\"): out of memory", filename); } fd->stream.opt_unlink_close = true; } Notice2("creating regular file \"%s\" for %s", filename, ddirection[rw]); if ((result = _xioopen_creat(filename, rw, opts)) < 0) return result; fd->stream.fd = result; applyopts_named(filename, opts, PH_PASTOPEN); if ((result = applyopts2(fd->stream.fd, opts, PH_PASTOPEN, PH_LATE2)) < 0) return result; applyopts_cloexec(fd->stream.fd, opts); applyopts_fchown(fd->stream.fd, opts); if ((result = _xio_openlate(&fd->stream, opts)) < 0) return result; return 0; } #endif /* WITH_CREAT */ socat-1.7.3.1/xioclose.c0000644000201000020100000000611412161506654014561 0ustar gerhardgerhard/* source: xioclose.c */ /* Copyright Gerhard Rieger 2001-2009 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source of the extended close function */ #include "xiosysincludes.h" #include "xioopen.h" #include "xiolockfile.h" #include "xio-termios.h" /* close the xio fd; must be valid and "simple" (not dual) */ int xioclose1(struct single *pipe) { if (pipe->tag == XIO_TAG_INVALID) { Notice("xioclose1(): invalid file descriptor"); errno = EINVAL; return -1; } #if WITH_READLINE if ((pipe->dtype & XIODATA_MASK) == XIODATA_READLINE) { Write_history(pipe->para.readline.history_file); /*xiotermios_setflag(pipe->fd, 3, ECHO|ICANON);*/ /* error when pty closed */ } #endif /* WITH_READLINE */ #if WITH_OPENSSL if ((pipe->dtype & XIODATA_MASK) == XIODATA_OPENSSL) { if (pipe->para.openssl.ssl) { /* e.g. on TCP connection refused, we do not yet have this set */ sycSSL_shutdown(pipe->para.openssl.ssl); sycSSL_free(pipe->para.openssl.ssl); pipe->para.openssl.ssl = NULL; } Close(pipe->fd); pipe->fd = -1; if (pipe->para.openssl.ctx) { sycSSL_CTX_free(pipe->para.openssl.ctx); pipe->para.openssl.ctx = NULL; } } else #endif /* WITH_OPENSSL */ #if WITH_TERMIOS if (pipe->ttyvalid) { if (Tcsetattr(pipe->fd, 0, &pipe->savetty) < 0) { Warn2("cannot restore terminal settings on fd %d: %s", pipe->fd, strerror(errno)); } } #endif /* WITH_TERMIOS */ if (pipe->fd >= 0) { switch (pipe->howtoend) { case END_KILL: case END_SHUTDOWN_KILL: case END_CLOSE_KILL: if (pipe->para.exec.pid > 0) { if (Kill(pipe->para.exec.pid, SIGTERM) < 0) { Msg2(errno==ESRCH?E_INFO:E_WARN, "kill(%d, SIGTERM): %s", pipe->para.exec.pid, strerror(errno)); } } default: break; } switch (pipe->howtoend) { case END_CLOSE: case END_CLOSE_KILL: if (Close(pipe->fd) < 0) { Info2("close(%d): %s", pipe->fd, strerror(errno)); } break; #if _WITH_SOCKET case END_SHUTDOWN: case END_SHUTDOWN_KILL: if (Shutdown(pipe->fd, 2) < 0) { Info3("shutdown(%d, %d): %s", pipe->fd, 2, strerror(errno)); } break; #endif /* _WITH_SOCKET */ case END_NONE: default: break; } } /* unlock */ if (pipe->havelock) { xiounlock(pipe->lock.lockfile); pipe->havelock = false; } if (pipe->opt_unlink_close && pipe->unlink_close) { if (Unlink(pipe->unlink_close) < 0) { Info2("unlink(\"%s\"): %s", pipe->unlink_close, strerror(errno)); } free(pipe->unlink_close); } pipe->tag = XIO_TAG_INVALID; return 0; /*! */ } /* close the xio fd */ int xioclose(xiofile_t *file) { int result; if (file->tag == XIO_TAG_INVALID) { Error("xioclose(): invalid file descriptor"); errno = EINVAL; return -1; } if (file->tag == XIO_TAG_DUAL) { result = xioclose1(file->dual.stream[0]); result |= xioclose1(file->dual.stream[1]); file->tag = XIO_TAG_INVALID; } else { result = xioclose1(&file->stream); } return result; } socat-1.7.3.1/xio-fdnum.h0000644000201000020100000000061411453022152014633 0ustar gerhardgerhard/* source: xio-fdnum.h */ /* Copyright Gerhard Rieger 2001-2006 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_fdnum_h_included #define __xio_fdnum_h_included 1 extern const struct addrdesc addr_fd; extern int xioopen_fd(struct opt *opts, int rw, xiosingle_t *xfd, int numfd, int dummy2, int dummy3); #endif /* !defined(__xio_fdnum_h_included) */ socat-1.7.3.1/compat.h0000644000201000020100000004164612460670272014235 0ustar gerhardgerhard/* source: compat.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __compat_h_included #define __compat_h_included 1 #if !HAVE_DECL_ENVIRON && HAVE_VAR_ENVIRON extern char **environ; #endif /*****************************************************************************/ /* I dont like this system dependent part, but it would be quite a challenge for configure */ /* define if the following does not work: socket() connect() -> Connection refused connect() -> ok instead, it needs close() and socket() between the two connect() attmpts: */ #if __FreeBSD__ || __APPLE__ || _AIX || __hpux__ || __osf__ # undef SOCKET_CAN_RECOVER #else # define SOCKET_CAN_RECOVER 1 #endif /* define if stat() says that pipes are sockets */ #if __APPLE__ # define PIPE_STATES_SOCKET 1 #else # undef PIPE_STATES_SOCKET #endif /*****************************************************************************/ /* substitute some features that might be missing on some platforms */ #if !HAVE_TYPE_SIG_ATOMIC_T typedef int sig_atomic_t; #endif #ifndef SHUT_RD # define SHUT_RD 0 #endif #ifndef SHUT_WR # define SHUT_WR 1 #endif #ifndef SHUT_RDWR # define SHUT_RDWR 2 #endif #ifndef MIN # define MIN(x,y) ((x)<=(y)?(x):(y)) #endif #ifndef MAX # define MAX(x,y) ((x)>=(y)?(x):(y)) #endif /* O_ASYNC: Linux 2.2.10 */ #if !defined(O_ASYNC) && defined(FASYNC) # define O_ASYNC FASYNC #endif /* NGROUPS not defined on Solaris */ #if !defined(NGROUPS) && defined(NGROUPS_MAX) # define NGROUPS NGROUPS_MAX #endif /* UNIX_PATH_MAX: AIX 4.3.3 */ #ifndef UNIX_PATH_MAX # define UNIX_PATH_MAX 104 /*! why 104? Linux: 108 ! */ #endif /* SOL_IP: AIX 4.3.3 */ #ifndef SOL_IP # define SOL_IP 0 #endif /* SOL_TCP: AIX 4.3.3 */ #ifndef SOL_TCP # ifdef IPPROTO_TCP # define SOL_TCP IPPROTO_TCP # endif #endif /* POSIX.1 doesn't seem to know sockets */ #ifndef S_ISSOCK # define S_ISSOCK(fmode) 0 #endif #if defined(IPPROTO_IPV6) && !defined(SOL_IPV6) # define SOL_IPV6 IPPROTO_IPV6 #endif /* all unsigned */ #if !defined(HAVE_BASIC_SIZE_T) || !HAVE_BASIC_SIZE_T # undef HAVE_BASIC_SIZE_T # define HAVE_BASIC_SIZE_T 6 #endif #if HAVE_BASIC_SIZE_T==2 # define SIZET_MAX USHRT_MAX # define SSIZET_MIN SHRT_MIN # define SSIZET_MAX SHRT_MAX # define F_Zd "%hd" # define F_Zu "%hu" #elif HAVE_BASIC_SIZE_T==4 # define SIZET_MAX UINT_MAX # define SSIZET_MIN INT_MIN # define SSIZET_MAX INT_MAX # define F_Zd "%""d" # define F_Zu "%u" #elif HAVE_BASIC_SIZE_T==6 # define SIZET_MAX ULONG_MAX # define SSIZET_MIN LONG_MIN # define SSIZET_MAX LONG_MAX # define F_Zd "%ld" # define F_Zu "%lu" #elif HAVE_BASIC_SIZE_T==8 # define SIZET_MAX ULLONG_MAX # define SSIZET_MIN LLONG_MIN # define SSIZET_MAX LLONG_MAX # define F_Zd "%Ld" # define F_Zu "%Lu" #else # error "HAVE_BASIC_SIZE_T is out of range:" HAVE_BASIC_SIZE_T #endif #if HAVE_FORMAT_Z # undef F_Zd # undef F_Zu # define F_Zd "%Zd" # define F_Zu "%Zu" #endif /* mode_t is always unsigned; default: unsigned int */ #if !defined(HAVE_BASIC_MODE_T) || !HAVE_BASIC_MODE_T # undef HAVE_BASIC_MODE_T # define HAVE_BASIC_MODE_T 4 #endif #ifndef F_mode # if HAVE_BASIC_MODE_T==1 || HAVE_BASIC_MODE_T==2 #define F_mode "0%03ho" # elif HAVE_BASIC_MODE_T==3 || HAVE_BASIC_MODE_T==4 #define F_mode "0%03o" # elif HAVE_BASIC_MODE_T==5 || HAVE_BASIC_MODE_T==6 #define F_mode "0%03lo" # else #error "HAVE_BASIC_MODE_T is out of range:" HAVE_BASIC_MODE_T # endif #endif /* default: unsigned int */ #if !defined(HAVE_BASIC_PID_T) || !HAVE_BASIC_PID_T # undef HAVE_BASIC_PID_T # define HAVE_BASIC_PID_T 4 #endif #ifndef F_pid # if HAVE_BASIC_PID_T==1 #define F_pid "%hd" # elif HAVE_BASIC_PID_T==2 #define F_pid "%hu" # elif HAVE_BASIC_PID_T==3 #define F_pid "%""d" # elif HAVE_BASIC_PID_T==4 #define F_pid "%u" # elif HAVE_BASIC_PID_T==5 #define F_pid "%ld" # elif HAVE_BASIC_PID_T==6 #define F_pid "%lu" # else #error "HAVE_BASIC_PID_T is out of range:" HAVE_BASIC_PID_T # endif #endif /* default: unsigned int */ #if !defined(HAVE_BASIC_UID_T) || !HAVE_BASIC_UID_T # undef HAVE_BASIC_UID_T # define HAVE_BASIC_UID_T 4 #endif #ifndef F_uid # if HAVE_BASIC_UID_T==1 #define F_uid "%hd" # elif HAVE_BASIC_UID_T==2 #define F_uid "%hu" # elif HAVE_BASIC_UID_T==3 #define F_uid "%""d" # elif HAVE_BASIC_UID_T==4 #define F_uid "%u" # elif HAVE_BASIC_UID_T==5 #define F_uid "%ld" # elif HAVE_BASIC_UID_T==6 #define F_uid "%lu" # else #error "HAVE_BASIC_UID_T is out of range:" HAVE_BASIC_UID_T # endif #endif /* default: unsigned int */ #if !defined(HAVE_BASIC_GID_T) || !HAVE_BASIC_GID_T # undef HAVE_BASIC_GID_T # define HAVE_BASIC_GID_T 4 #endif #ifndef F_gid # if HAVE_BASIC_GID_T==1 #define F_gid "%hd" # elif HAVE_BASIC_GID_T==2 #define F_gid "%hu" # elif HAVE_BASIC_GID_T==3 #define F_gid "%""d" # elif HAVE_BASIC_GID_T==4 #define F_gid "%u" # elif HAVE_BASIC_GID_T==5 #define F_gid "%ld" # elif HAVE_BASIC_GID_T==6 #define F_gid "%lu" # else #error "HAVE_BASIC_GID_T is out of range:" HAVE_BASIC_GID_T # endif #endif /* all signed; default: long */ #if !defined(HAVE_BASIC_TIME_T) || !HAVE_BASIC_TIME_T # undef HAVE_BASIC_TIME_T # define HAVE_BASIC_TIME_T 5 #endif #ifndef F_time # if HAVE_BASIC_TIME_T==1 #define F_time "%hd" # elif HAVE_BASIC_TIME_T==2 #define F_time "%hu" # elif HAVE_BASIC_TIME_T==3 #define F_time "%""d" # elif HAVE_BASIC_TIME_T==4 #define F_time "%u" # elif HAVE_BASIC_TIME_T==5 #define F_time "%ld" # elif HAVE_BASIC_TIME_T==6 #define F_time "%lu" # elif HAVE_BASIC_TIME_T==7 #define F_time "%Ld" # elif HAVE_BASIC_TIME_T==8 #define F_time "%Lu" # else #error "HAVE_BASIC_TIME_T is out of range:" HAVE_BASIC_TIME_T # endif #endif /* default: int */ #if !defined(HAVE_BASIC_SOCKLEN_T) || !HAVE_BASIC_SOCKLEN_T # undef HAVE_BASIC_SOCKLEN_T # define HAVE_BASIC_SOCKLEN_T 3 #endif #ifndef F_socklen # if HAVE_BASIC_SOCKLEN_T==1 #define F_socklen "%hd" # elif HAVE_BASIC_SOCKLEN_T==2 #define F_socklen "%hu" # elif HAVE_BASIC_SOCKLEN_T==3 #define F_socklen "%""d" # elif HAVE_BASIC_SOCKLEN_T==4 #define F_socklen "%u" # elif HAVE_BASIC_SOCKLEN_T==5 #define F_socklen "%ld" # elif HAVE_BASIC_SOCKLEN_T==6 #define F_socklen "%lu" # elif HAVE_BASIC_SOCKLEN_T==7 #define F_socklen "%Ld" # elif HAVE_BASIC_SOCKLEN_T==8 #define F_socklen "%Lu" # else #error "HAVE_BASIC_SOCKLEN_T is out of range:" HAVE_BASIC_SOCKLEN_T # endif #endif #if !defined(HAVE_BASIC_OFF_T) || !HAVE_BASIC_OFF_T # undef HAVE_BASIC_OFF_T # define HAVE_BASIC_OFF_T 5 /*long*/ #endif #ifndef F_off # if HAVE_BASIC_OFF_T==3 # define F_off "%""d" # elif HAVE_BASIC_OFF_T==5 # define F_off "%ld" # elif HAVE_BASIC_OFF_T==7 # define F_off "%Ld" # else #error "HAVE_BASIC_OFF_T is out of range:" HAVE_BASIC_OFF_T # endif #endif /* default: long long */ #if !defined(HAVE_BASIC_OFF64_T) || !HAVE_BASIC_OFF64_T # undef HAVE_BASIC_OFF64_T # define HAVE_BASIC_OFF64_T 7 #endif #ifndef F_off64 # if HAVE_BASIC_OFF64_T==1 #define F_off64 "%hd" # elif HAVE_BASIC_OFF64_T==2 #define F_off64 "%hu" # elif HAVE_BASIC_OFF64_T==3 #define F_off64 "%""d" # elif HAVE_BASIC_OFF64_T==4 #define F_off64 "%u" # elif HAVE_BASIC_OFF64_T==5 #define F_off64 "%ld" # elif HAVE_BASIC_OFF64_T==6 #define F_off64 "%lu" # elif HAVE_BASIC_OFF64_T==7 #define F_off64 "%Ld" # elif HAVE_BASIC_OFF64_T==8 #define F_off64 "%Lu" # else #error "HAVE_BASIC_OFF64_T is out of range:" HAVE_BASIC_OFF64_T # endif #endif /* all unsigned; default: unsigned long */ #if !defined(HAVE_BASIC_DEV_T) || !HAVE_BASIC_DEV_T # undef HAVE_BASIC_DEV_T # define HAVE_BASIC_DEV_T 6 #endif #ifndef F_dev # if HAVE_BASIC_DEV_T==1 #define F_dev "%hd" # elif HAVE_BASIC_DEV_T==2 #define F_dev "%hu" # elif HAVE_BASIC_DEV_T==3 #define F_dev "%""d" # elif HAVE_BASIC_DEV_T==4 #define F_dev "%u" # elif HAVE_BASIC_DEV_T==5 #define F_dev "%ld" # elif HAVE_BASIC_DEV_T==6 #define F_dev "%lu" # elif HAVE_BASIC_DEV_T==7 #define F_dev "%Ld" # elif HAVE_BASIC_DEV_T==8 #define F_dev "%Lu" # else #error "HAVE_BASIC_DEV_T is out of range:" HAVE_BASIC_DEV_T # endif #endif /* all unsigned; default; unsigned long */ #if !defined(HAVE_TYPEOF_ST_INO) || !HAVE_TYPEOF_ST_INO # undef HAVE_TYPEOF_ST_INO # define HAVE_TYPEOF_ST_INO 6 #endif #ifndef F_st_ino # if HAVE_TYPEOF_ST_INO==1 #define F_st_ino "%hd" # elif HAVE_TYPEOF_ST_INO==2 #define F_st_ino "%hu" # elif HAVE_TYPEOF_ST_INO==3 #define F_st_ino "%""d" # elif HAVE_TYPEOF_ST_INO==4 #define F_st_ino "%u" # elif HAVE_TYPEOF_ST_INO==5 #define F_st_ino "%ld" # elif HAVE_TYPEOF_ST_INO==6 #define F_st_ino "%lu" # elif HAVE_TYPEOF_ST_INO==7 /* Cygwin 1.5 */ #define F_st_ino "%Ld" # elif HAVE_TYPEOF_ST_INO==8 #define F_st_ino "%Lu" # else #error "HAVE_TYPEOF_ST_INO is out of range:" HAVE_TYPEOF_ST_INO # endif #endif /* all unsigned; default; unsigned long long */ #if !defined(HAVE_TYPEOF_ST64_INO) || !HAVE_TYPEOF_ST64_INO # undef HAVE_TYPEOF_ST64_INO # define HAVE_TYPEOF_ST64_INO 8 #endif #ifndef F_st64_ino # if HAVE_TYPEOF_ST64_INO==1 #define F_st64_ino "%hd" # elif HAVE_TYPEOF_ST64_INO==2 #define F_st64_ino "%hu" # elif HAVE_TYPEOF_ST64_INO==3 #define F_st64_ino "%""d" # elif HAVE_TYPEOF_ST64_INO==4 #define F_st64_ino "%u" # elif HAVE_TYPEOF_ST64_INO==5 #define F_st64_ino "%ld" # elif HAVE_TYPEOF_ST64_INO==6 #define F_st64_ino "%lu" # elif HAVE_TYPEOF_ST64_INO==7 #define F_st64_ino "%Ld" # elif HAVE_TYPEOF_ST64_INO==8 #define F_st64_ino "%Lu" # else #error "HAVE_TYPEOF_ST64_INO is out of range:" HAVE_TYPEOF_ST64_INO # endif #endif /* default: unsigned short */ #if !defined(HAVE_TYPEOF_ST_NLINK) || !HAVE_TYPEOF_ST_NLINK # undef HAVE_TYPEOF_ST_NLINK # define HAVE_TYPEOF_ST_NLINK 2 #endif #ifndef F_st_nlink # if HAVE_TYPEOF_ST_NLINK==1 #define F_st_nlink "%hd" # elif HAVE_TYPEOF_ST_NLINK==2 #define F_st_nlink "%hu" # elif HAVE_TYPEOF_ST_NLINK==3 #define F_st_nlink "%""d" # elif HAVE_TYPEOF_ST_NLINK==4 #define F_st_nlink "%u" # elif HAVE_TYPEOF_ST_NLINK==5 #define F_st_nlink "%ld" # elif HAVE_TYPEOF_ST_NLINK==6 #define F_st_nlink "%lu" # elif HAVE_TYPEOF_ST_NLINK==7 #define F_st_nlink "%Ld" # elif HAVE_TYPEOF_ST_NLINK==8 #define F_st_nlink "%Lu" # else #error "HAVE_TYPEOF_ST_NLINK is out of range:" HAVE_TYPEOF_ST_NLINK # endif #endif /* all signed; default: long */ #if !defined(HAVE_TYPEOF_ST_SIZE) || !HAVE_TYPEOF_ST_SIZE # undef HAVE_TYPEOF_ST_SIZE # define HAVE_TYPEOF_ST_SIZE 5 #endif #ifndef F_st_size # if HAVE_TYPEOF_ST_SIZE==1 #define F_st_size "%hd" # elif HAVE_TYPEOF_ST_SIZE==2 #define F_st_size "%hu" # elif HAVE_TYPEOF_ST_SIZE==3 #define F_st_size "%""d" # elif HAVE_TYPEOF_ST_SIZE==4 #define F_st_size "%u" # elif HAVE_TYPEOF_ST_SIZE==5 #define F_st_size "%ld" # elif HAVE_TYPEOF_ST_SIZE==6 #define F_st_size "%lu" # elif HAVE_TYPEOF_ST_SIZE==7 #define F_st_size "%Ld" # elif HAVE_TYPEOF_ST_SIZE==8 #define F_st_size "%Lu" # else #error "HAVE_TYPEOF_ST_SIZE is out of range:" HAVE_TYPEOF_ST_SIZE # endif #endif /* all signed; default: long long */ #if !defined(HAVE_TYPEOF_ST64_SIZE) || !HAVE_TYPEOF_ST64_SIZE # undef HAVE_TYPEOF_ST64_SIZE # define HAVE_TYPEOF_ST64_SIZE 7 #endif #ifndef F_st64_size # if HAVE_TYPEOF_ST64_SIZE==1 #define F_st64_size "%hd" # elif HAVE_TYPEOF_ST64_SIZE==2 #define F_st64_size "%hu" # elif HAVE_TYPEOF_ST64_SIZE==3 #define F_st64_size "%""d" # elif HAVE_TYPEOF_ST64_SIZE==4 #define F_st64_size "%u" # elif HAVE_TYPEOF_ST64_SIZE==5 #define F_st64_size "%ld" # elif HAVE_TYPEOF_ST64_SIZE==6 #define F_st64_size "%lu" # elif HAVE_TYPEOF_ST64_SIZE==7 #define F_st64_size "%Ld" # elif HAVE_TYPEOF_ST64_SIZE==8 #define F_st64_size "%Lu" # else #error "HAVE_TYPEOF_ST64_SIZE is out of range:" HAVE_TYPEOF_ST64_SIZE # endif #endif /* very different results; default: long */ #if !defined(HAVE_TYPEOF_ST_BLKSIZE) || !HAVE_TYPEOF_ST_BLKSIZE # undef HAVE_TYPEOF_ST_BLKSIZE # define HAVE_TYPEOF_ST_BLKSIZE 5 #endif #ifndef F_st_blksize # if HAVE_TYPEOF_ST_BLKSIZE==1 #define F_st_blksize "%hd" # elif HAVE_TYPEOF_ST_BLKSIZE==2 #define F_st_blksize "%hu" # elif HAVE_TYPEOF_ST_BLKSIZE==3 #define F_st_blksize "%""d" # elif HAVE_TYPEOF_ST_BLKSIZE==4 #define F_st_blksize "%u" # elif HAVE_TYPEOF_ST_BLKSIZE==5 #define F_st_blksize "%ld" # elif HAVE_TYPEOF_ST_BLKSIZE==6 #define F_st_blksize "%lu" # elif HAVE_TYPEOF_ST_BLKSIZE==7 #define F_st_blksize "%Ld" # elif HAVE_TYPEOF_ST_BLKSIZE==8 #define F_st_blksize "%Lu" # else #error "HAVE_TYPEOF_ST_BLKSIZE is out of range:" HAVE_TYPEOF_ST_BLKSIZE # endif #endif /* default: long */ #if !defined(HAVE_TYPEOF_ST_BLOCKS) || !HAVE_TYPEOF_ST_BLOCKS # undef HAVE_TYPEOF_ST_BLOCKS # define HAVE_TYPEOF_ST_BLOCKS 5 #endif #ifndef F_st_blocks # if HAVE_TYPEOF_ST_BLOCKS==1 #define F_st_blocks "%hd" # elif HAVE_TYPEOF_ST_BLOCKS==2 #define F_st_blocks "%hu" # elif HAVE_TYPEOF_ST_BLOCKS==3 #define F_st_blocks "%""d" # elif HAVE_TYPEOF_ST_BLOCKS==4 #define F_st_blocks "%u" # elif HAVE_TYPEOF_ST_BLOCKS==5 #define F_st_blocks "%ld" # elif HAVE_TYPEOF_ST_BLOCKS==6 #define F_st_blocks "%lu" # elif HAVE_TYPEOF_ST_BLOCKS==7 #define F_st_blocks "%Ld" # elif HAVE_TYPEOF_ST_BLOCKS==8 #define F_st_blocks "%Lu" # else #error "HAVE_TYPEOF_ST_BLOCKS is out of range:" HAVE_TYPEOF_ST_BLOCKS # endif #endif /* default: long long */ #if !defined(HAVE_TYPEOF_ST64_BLOCKS) || !HAVE_TYPEOF_ST64_BLOCKS # undef HAVE_TYPEOF_ST64_BLOCKS # define HAVE_TYPEOF_ST64_BLOCKS 7 #endif #ifndef F_st64_blocks # if HAVE_TYPEOF_ST64_BLOCKS==1 #define F_st64_blocks "%hd" # elif HAVE_TYPEOF_ST64_BLOCKS==2 #define F_st64_blocks "%hu" # elif HAVE_TYPEOF_ST64_BLOCKS==3 #define F_st64_blocks "%""d" # elif HAVE_TYPEOF_ST64_BLOCKS==4 #define F_st64_blocks "%u" # elif HAVE_TYPEOF_ST64_BLOCKS==5 #define F_st64_blocks "%ld" # elif HAVE_TYPEOF_ST64_BLOCKS==6 #define F_st64_blocks "%lu" # elif HAVE_TYPEOF_ST64_BLOCKS==7 #define F_st64_blocks "%Ld" # elif HAVE_TYPEOF_ST64_BLOCKS==8 #define F_st64_blocks "%Lu" # else #error "HAVE_TYPEOF_ST64_BLOCKS is out of range:" HAVE_TYPEOF_ST64_BLOCKS # endif #endif /* at least for Linux */ #define F_tv_sec "%ld" /* default: long */ #if !defined(HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC) || !HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC # undef HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC # define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 #endif #ifndef F_tv_usec # if HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC==1 #define F_tv_usec "%06hd" # elif HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC==2 #define F_tv_usec "%06hu" # elif HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC==3 #define F_tv_usec "%06d" # elif HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC==4 #define F_tv_usec "%06u" # elif HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC==5 #define F_tv_usec "%06ld" # elif HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC==6 #define F_tv_usec "%06lu" # elif HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC==7 #define F_tv_usec "%06Ld" # elif HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC==8 #define F_tv_usec "%06Lu" # else #error "HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC is out of range:" HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC # endif #endif /* default: long */ #if !defined(HAVE_TYPEOF_RLIM_MAX) || !HAVE_TYPEOF_RLIM_MAX # undef HAVE_TYPEOF_RLIM_MAX # define HAVE_TYPEOF_RLIM_MAX 5 #endif #ifndef F_rlim_max # if HAVE_TYPEOF_RLIM_MAX==1 #define F_rlim_max "hd" # elif HAVE_TYPEOF_RLIM_MAX==2 #define F_rlim_max "hu" # elif HAVE_TYPEOF_RLIM_MAX==3 #define F_rlim_max "d" # elif HAVE_TYPEOF_RLIM_MAX==4 #define F_rlim_max "u" # elif HAVE_TYPEOF_RLIM_MAX==5 #define F_rlim_max "ld" # elif HAVE_TYPEOF_RLIM_MAX==6 #define F_rlim_max "lu" # elif HAVE_TYPEOF_RLIM_MAX==7 #define F_rlim_max "Ld" # elif HAVE_TYPEOF_RLIM_MAX==8 #define F_rlim_max "Lu" # else #error "HAVE_TYPEOF_RLIM_MAX is out of range:" HAVE_TYPEOF_RLIM_MAX # endif #endif /* default: socklen_t */ #if !defined(HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN) || !HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN # undef HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN # define HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN HAVE_BASIC_SOCKLEN_T #endif #ifndef F_cmsg_len # if HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN==1 #define F_cmsg_len "%""hd" # elif HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN==2 #define F_cmsg_len "%""hu" # elif HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN==3 #define F_cmsg_len "%""d" # elif HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN==4 #define F_cmsg_len "%""u" # elif HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN==5 #define F_cmsg_len "%""ld" # elif HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN==6 #define F_cmsg_len "%""lu" # elif HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN==7 #define F_cmsg_len "%""Ld" # elif HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN==8 #define F_cmsg_len "%""Lu" # else #error "HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN is out of range:" HAVE_TYPEOF_STRUCT_CMSGHDR_CMSG_LEN # endif #endif /* Cygwin 1.3.22 has the prototypes, but not the type... */ #ifndef HAVE_TYPE_STAT64 # undef HAVE_STAT64 # undef HAVE_FSTAT64 # undef HAVE_LSTAT64 #endif #ifndef HAVE_TYPE_OFF64 # undef HAVE_LSEEK64 # undef HAVE_FTRUNCATE64 #endif #if !defined(NETDB_INTERNAL) && defined(h_NETDB_INTERNAL) # define NETDB_INTERNAL h_NETDB_INTERNAL #endif #ifndef INET_ADDRSTRLEN # define INET_ADDRSTRLEN sizeof(struct sockaddr_in) #endif #if !HAVE_PROTOTYPE_HSTRERROR /* with MacOSX this is char * */ extern const char *hstrerror(int); #endif #endif /* !defined(__compat_h_included) */ socat-1.7.3.1/xioshutdown.c0000644000201000020100000001150112460670272015323 0ustar gerhardgerhard/* source: xioshutdown.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source of the extended shutdown function */ #include "xiosysincludes.h" #include "xioopen.h" static pid_t socat_kill_pid; /* here we pass the pid to be killed in sighandler */ static void signal_kill_pid(int dummy) { int _errno; _errno = errno; diag_in_handler = 1; Notice("SIGALRM while waiting for wo child process to die, killing it now"); Kill(socat_kill_pid, SIGTERM); diag_in_handler = 0; errno = _errno; } int xioshutdown(xiofile_t *sock, int how) { int result = 0; if (sock->tag == XIO_TAG_INVALID) { Error("xioshutdown(): invalid file descriptor"); errno = EINVAL; return -1; } if (sock->tag == XIO_TAG_DUAL) { if ((how+1)&1) { result = xioshutdown((xiofile_t *)sock->dual.stream[0], 0); } if ((how+1)&2) { result |= xioshutdown((xiofile_t *)sock->dual.stream[1], 1); } return result; } switch (sock->stream.howtoshut) { char writenull; case XIOSHUT_NONE: return 0; case XIOSHUT_CLOSE: if (Close(sock->stream.fd) < 0) { Info2("close(%d): %s", sock->stream.fd, strerror(errno)); } return 0; case XIOSHUT_DOWN: if ((result = Shutdown(sock->stream.fd, how)) < 0) { Info3("shutdown(%d, %d): %s", sock->stream.fd, how, strerror(errno)); } return 0; #if _WITH_SOCKET case XIOSHUT_NULL: /* send an empty packet; only useful on datagram sockets? */ xiowrite(sock, &writenull, 0); return 0; #endif /* _WITH_SOCKET */ default: ; } if (false) { ; #if WITH_OPENSSL } else if ((sock->stream.dtype & XIODATA_MASK) == XIODATA_OPENSSL) { sycSSL_shutdown (sock->stream.para.openssl.ssl); /*! what about half/full close? */ #endif /* WITH_OPENSSL */ } else if ((sock->stream.dtype & XIODATA_MASK) == XIODATA_PIPE) { if ((how+1)&1) { if (Close(sock->stream.fd) < 0) { Info2("close(%d): %s", sock->stream.fd, strerror(errno)); } } if ((how+1)&2) { if (Close(sock->stream.para.bipipe.fdout) < 0) { Info2("close(%d): %s", sock->stream.para.bipipe.fdout, strerror(errno)); } } } else if ((sock->stream.dtype & XIODATA_MASK) == XIODATA_2PIPE) { if ((how+1)&1) { if (Close(sock->stream.fd) < 0) { Info2("close(%d): %s", sock->stream.fd, strerror(errno)); } } if ((how+1)&2) { if (Close(sock->stream.para.exec.fdout) < 0) { Info2("close(%d): %s", sock->stream.para.exec.fdout, strerror(errno)); } } #if _WITH_SOCKET } else if (sock->stream.howtoend == END_SHUTDOWN) { if ((result = Shutdown(sock->stream.fd, how)) < 0) { Info3("shutdown(%d, %d): %s", sock->stream.fd, how, strerror(errno)); } } else if (sock->stream.howtoend == END_SHUTDOWN_KILL) { if ((result = Shutdown(sock->stream.fd, how)) < 0) { Info3("shutdown(%d, %d): %s", sock->stream.fd, how, strerror(errno)); } if ((sock->stream.flags&XIO_ACCMODE) == XIO_WRONLY) { /* the child process might want to flush some data before terminating */ int status = 0; /* we wait for the child process to die, but to prevent timeout we raise an alarm after some time. NOTE: the alarm does not terminate waitpid() on Linux/glibc (BUG?), therefore we have to do the kill in the signal handler */ { struct sigaction act; sigfillset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = signal_kill_pid; Sigaction(SIGALRM, &act, NULL); } socat_kill_pid = sock->stream.para.exec.pid; #if HAVE_SETITIMER /*! with next feature release, we get usec resolution and an option */ #else Alarm(1 /*! sock->stream.para.exec.waitdie */); #endif /* !HAVE_SETITIMER */ if (Waitpid(sock->stream.para.exec.pid, &status, 0) < 0) { Warn3("waitpid("F_pid", %p, 0): %s", sock->stream.para.exec.pid, &status, strerror(errno)); } Alarm(0); } } else if ((sock->stream.dtype & XIODATA_MASK) == (XIODATA_RECVFROM & XIODATA_MASK)) { if (how >= 1) { if (Close(sock->stream.fd) < 0) { Info2("close(%d): %s", sock->stream.fd, strerror(errno)); } sock->stream.eof = 2; sock->stream.fd = -1; } #endif /* _WITH_SOCKET */ #if 0 } else { Error1("xioshutdown(): bad data type specification %d", sock->stream.dtype); return -1; #endif } #if 0 else if (sock->stream.howtoend == END_CLOSE && sock->stream.dtype == DATA_STREAM) { return result; } #if WITH_TERMIOS if (sock->stream.ttyvalid) { if (Tcsetattr(sock->stream.fd, 0, &sock->stream.savetty) < 0) { Warn2("cannot restore terminal settings on fd %d: %s", sock->stream.fd, strerror(errno)); } } #endif /* WITH_TERMIOS */ #endif return result; } socat-1.7.3.1/README0000644000201000020100000002657612460743157013471 0ustar gerhardgerhard about ----- socat is a relay for bidirectional data transfer between two independent data channels. Each of these data channels may be a file, pipe, device (serial line etc. or a pseudo terminal), a socket (UNIX, IP4, IP6 - raw, UDP, TCP), an SSL socket, proxy CONNECT connection, a file descriptor (stdin etc.), the GNU line editor (readline), a program, or a combination of two of these. These modes include generation of "listening" sockets, named pipes, and pseudo terminals. socat can be used, e.g., as TCP port forwarder (one-shot or daemon), as an external socksifier, for attacking weak firewalls, as a shell interface to UNIX sockets, IP6 relay, for redirecting TCP oriented programs to a serial line, to logically connect serial lines on different computers, or to establish a relatively secure environment (su and chroot) for running client or server shell scripts with network connections. Many options are available to refine socats behaviour: terminal parameters, open() options, file permissions, file and process owners, basic socket options like bind address, advanced socket options like IP source routing, linger, TTL, TOS (type of service), or TCP performance tuning. More capabilities, like daemon mode with forking, client address check, "tail -f" mode, some stream data processing (line terminator conversion), choosing sockets, pipes, or ptys for interprocess communication, debug and trace options, logging to syslog, stderr or file, and last but not least precise error messages make it a versatile tool for many different purposes. In fact, many of these features already exist in specialized tools; but until now, there does not seem to exists another tool that provides such a generic, flexible, simple and almost comprehensive (UNIX) byte stream connector. packages -------- before bothering with compilers, dependencies and include files, you might try to get a binary distribution that matches your platform. Have a look at the projects home page for actual information regarding socat binary distributions. platforms --------- socat 1.7.0 was compiled and more or less successfully tested under the following operating systems: Debian lenny/sid on x86, kernel 2.6.24 FreeBSD 6.1 on x86 NetBSD 4.0 on x86 OpenBSD 4.3 on x86 OpenSolaris 10 on x86 with gcc Mac OS X 10.5.5 on iMac G5, with libreadline HP-UX 11.23 AIX 5.3 on 64bit Power4 with gcc Cygwin 1.5.25 on i686 tests on Tru64 can no longer be performed because HP testdrive has taken down these hosts. Some versions of socat have been reported to successfully compile under older Linux versions back to RedHat 2.1 (kernel 1.2.13, gcc 2.7.0), under AIX 4.1 and 4.3, SunOS 5.7-5.8, FreeBSD 4.2 - 4.9, MacOS X 10.1, Cygwin, Solaris 8 on x86, OSR 5.0.6, NetBSD 1.6.1 and 2.0.2, OpenBSD 3.4 and 3.8, Tru64 5.1B, Mac OS X 10.1-10.2, and HP-UX 11 It might well compile and run under other UNIX like operating systems. install ------- Get the tarball and extract it: tar xzf socat.tar.gz cd socat-1.7.3.0 ./configure make su make install # installs socat, filan, and procan in /usr/local/bin For compiling socat, gcc (or egc) is recommended. If gcc is not available, the configure script will fail to determine some features; then you'd better begin with one of the Makefiles and config.h's from the Config directory. If you have problems with the OpenSSL library, you can apply the option "--disable-openssl" to configure. If you have problems with the readline library or (n)curses, you can apply the option "--disable-readline" to configure. If you have problems with the tcp wrappers library, you can apply the option "--disable-libwrap" to configure. If you still get errors or a tremendous amount of warnings you can exclude the features for system call tracing and file descriptor analyzing by applying the options "--disable-sycls --disable-filan" to configure. You still need the functions vsnprintf and snprintf that are in the GNU libc, but might not be available with some proprietary libc's. The configure script looks for headers and libraries of openssl, readline, and tcp wrappers in the OS'es standard places and in the subdirectories include/ and lib/ of the following places: /sw/ /usr/local/ /opt/freeware/ /usr/sfw/ and for openssl also in: /usr/local/ssl/ In case of unexpected behaviour it is important to understand that configure first searches for the appropriate include file and then expects to find the library in the associated lib directory. That means, when e.g. a OpenSSL installation resides under /usr/local and there is a symbolic link from /usr/include/ssl/ssl.h to /usr/local/ssl/include/ssl/ssl.h, configure will find the /usr/include/... header and will therefore expect libssl in /usr/lib instead of /usr/local/... If configure does not find a header file or library but you know where it is, you can specify additional search locations, e.g.: export LIBS="-L$HOME/lib" export CPPFLAGS="-I$HOME/include" before running configure and make. For other operating systems, if socat does not compile without errors, refer to the file PORTING. platform specifics - redhat --------------------------- Install the following packages before building socat: tcp_wrappers-devel readline-devel openssl-devel On RedHat Linux 9.0, including openssl/ssl.h might fail due to problems with the krb5-devel package. configure reacts with disabling openssl integration. To solve this issue, help cpp to find the krb5.h include file: CPPFLAGS="-I/usr/kerberos/include" ./configure platform specifics - aix ------------------------ The flock() prototype is not available but the function is. Thus, to enable the socat flock options, run configure and then change in config.h the line /* #undef HAVE_FLOCK */ to #define HAVE_FLOCK 1 and continue the build process. When using the OpenSSL rpm provided by IBM, configure might need the environment variable setting: LIBS="-L/opt/freeware/lib" When using the OpenSSL bundle provided by IBM, egd needs to be installed too to get enough entropy. socat compiles not only with gcc, but also with xlc. Just adapt the Makefile: replace gcc by /usr/vac/bin/xlc and remove gcc specific options "-Wall -Wno-parentheses". When linking with the OpenSSL library provided by IBM, errors may occur: ld: 0711-317 ERROR: Undefined symbol: .__umoddi3 In this case, you need to link with libgcc or compile libcrypt yourself using xlc, or disable SSL (in config.h, undefine WITH_OPENSSL and recompile) The score of test.sh can be improved by uncommenting MISCDELAY=1 in this script. platform specifics - solaris ---------------------------- If libreadline or libssl are in a directory not searched by the loader per default, e.g. /opt/sfw/lib, you must add this directory to $LD_LIBRARY_PATH, for running both configure and the socat executables, e.g.: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/sfw/lib For some shell scripts, it is preferable to have /usr/xpg4/bin at a prominent position in $PATH. With the default compiler define _GNU_SOURCE, the CMSG_* macros are not available, and therefore ancillary messages cannot be used. To enable these try the following: After running ./configure, edit Makefile and replace "-D_GNU_SOURCE" with "-D_XPG4_2 -D__EXTENSIONS__" and run make platform specifics - hp-ux -------------------------- Ancillary messages cannot be compiled in with socat: both struct msghdr and struct cmsghdr are required. Compiling with -D_XOPEN_SOURCE_EXTENDED provides struct msghdr but disables struct cmsghdr while -D_OPEN_SOURCE disables struct msghdr but disables struct cmsghdr. Please contact socat development if you know a solution. Shutting down the write channel of a UNIX domain socket does not seem to trigger an EOF on the peer socket. This makes problems with the exec and system addresses. This OS provides the type "long long", but not the strtoll() function to read data into a long long variable. UNIX domain sockets are only supported with SOCK_STREAM, not with datagrams (see man 7 unix). With UDP sockets it seems to happen that the select() call reports available data (or EOF) but a subsequent read() call hangs. platform specifics - tru64 -------------------------- When the use of the readline address fails with an error like: socat: /sbin/loader: Fatal Error: Reference to unresolvable symbol "tgetent" in ".../libreadline.so.4" and you still want to use shared libraries, try the following workaround: $ make distclean; LIBS="-static" ./configure remove the "-static" occurrence in Makefile $ make documentation ------------- These files reside in the doc subdirectory: socat.1 is the man page, socat.html is the HTML based man page. It is actual, but describes only the more useful options. xio.help is an older, but more exact description in text form; with socat version 1.6.0 it is outdated. doc/socat-openssltunnel.html is a simple tutorial for a private SSL connection. doc/socat-multicast.html is a short tutorial for multicast and broadcast communications. doc/socat-tun shows how to build a virtual network between two hosts. socat.1 and socat.html can be generated from socat.yo (which is released with socat 1.6.0.1 and later) using the yodl document language package. Maintenance of yodl had been discontinued by its author (http://www.xs4all.nl/~jantien/yodl/) (there seems to be a revival at http://yodl.sourceforge.net/ though). For socat, the old version 1.31 is used; an rpm is still distributed with recent OpenSuSE versions (confirmed for OpenSuSE 10.1 in suse/i586/yodl-1.31.18-1142.i586.rpm). It appears to install smoothly also under RedHat Linux. After yodl 1.31 installation, the following correction must be performed in /usr/share/yodl/shared.yo in two places: < whenhtml(htmlcommand())) > whenhtml(htmlcommand())) license ------- socat is distributed under the terms of the GNU GPLv2; except for install-sh, which is copyright MIT, with its own license; In addition, as a special exception, the copyright holder gives permission to link the code of this program with any version of the OpenSSL library which is distributed under a license identical to that listed in the included COPYING.OpenSSL file, and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than OpenSSL. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2 of the License This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. contact ------- For questions, bug reports, ideas, contributions etc. please contact socat@dest-unreach.org For socat source distribution, bug fixes, and latest news see http://www.dest-unreach.org/socat/ www.socat.org is an alternate site providing the same contents. public git repository: git://repo.or.cz/socat.git http://repo.or.cz/r/socat.git socat-1.7.3.1/xio-udp.h0000644000201000020100000000236711453022152014321 0ustar gerhardgerhard/* source: xio-udp.h */ /* Copyright Gerhard Rieger 2001-2007 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_udp_h_included #define __xio_udp_h_included 1 extern const struct addrdesc addr_udp_connect; extern const struct addrdesc addr_udp_listen; extern const struct addrdesc addr_udp_sendto; extern const struct addrdesc addr_udp_datagram; extern const struct addrdesc addr_udp_recvfrom; extern const struct addrdesc addr_udp_recv; extern const struct addrdesc addr_udp4_connect; extern const struct addrdesc addr_udp4_listen; extern const struct addrdesc addr_udp4_sendto; extern const struct addrdesc addr_udp4_datagram; extern const struct addrdesc addr_udp4_recvfrom; extern const struct addrdesc addr_udp4_recv; extern const struct addrdesc addr_udp6_connect; extern const struct addrdesc addr_udp6_listen; extern const struct addrdesc addr_udp6_sendto; extern const struct addrdesc addr_udp6_datagram; extern const struct addrdesc addr_udp6_recvfrom; extern const struct addrdesc addr_udp6_recv; extern int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, unsigned groups, int af, int ipproto, int protname); #endif /* !defined(__xio_udp_h_included) */ socat-1.7.3.1/xio-stdio.h0000644000201000020100000000072611453022152014650 0ustar gerhardgerhard/* source: xio-stdio.h */ /* Copyright Gerhard Rieger 2001-2006 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_stdio_h_included #define __xio_stdio_h_included 1 extern int xioopen_stdio_bi(xiofile_t *sock); extern const struct addrdesc addr_stdio; extern const struct addrdesc addr_stdin; extern const struct addrdesc addr_stdout; extern const struct addrdesc addr_stderr; #endif /* !defined(__xio_stdio_h_included) */ socat-1.7.3.1/install-sh0000755000201000020100000001272107237331173014575 0ustar gerhardgerhard#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 socat-1.7.3.1/error.c0000644000201000020100000003135712460670272014074 0ustar gerhardgerhard/* source: error.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* the logging subsystem */ #include "config.h" #include "sysincludes.h" #include "mytypes.h" #include "compat.h" #include "utils.h" #include "vsnprintf_r.h" #include "snprinterr.h" #include "error.h" #include "sysincludes.h" #include "sycls.h" /* translate MSG level to SYSLOG level */ int syslevel[] = { LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARNING, LOG_ERR, LOG_CRIT }; struct diag_opts { const char *progname; int msglevel; int exitlevel; int syslog; FILE *logfile; int logfacility; bool micros; int exitstatus; /* pass signal number to error exit */ bool withhostname; /* in custom logs add hostname */ char *hostname; } ; static void _diag_exit(int status); struct diag_opts diagopts = { NULL, E_ERROR, E_ERROR, 0, NULL, LOG_DAEMON, false, 0 } ; static void msg2( #if HAVE_CLOCK_GETTIME struct timespec *now, #elif HAVE_GETTIMEOFDAY struct timeval *now, #else time_t *now, #endif int level, int exitcode, int handler, const char *text); static void _msg(int level, const char *buff, const char *syslp); sig_atomic_t diag_in_handler; /* !=0 indicates to msg() that in signal handler */ sig_atomic_t diag_immediate_msg; /* !=0 prints messages even from within signal handler instead of deferring them */ sig_atomic_t diag_immediate_exit; /* !=0 calls exit() from diag_exit() even when in signal handler. For system() */ static struct wordent facilitynames[] = { {"auth", (void *)LOG_AUTH}, #ifdef LOG_AUTHPRIV {"authpriv", (void *)LOG_AUTHPRIV}, #endif #ifdef LOG_CONSOLE {"console", (void *)LOG_CONSOLE}, #endif {"cron", (void *)LOG_CRON}, {"daemon", (void *)LOG_DAEMON}, #ifdef LOG_FTP {"ftp", (void *)LOG_FTP}, #endif {"kern", (void *)LOG_KERN}, {"local0", (void *)LOG_LOCAL0}, {"local1", (void *)LOG_LOCAL1}, {"local2", (void *)LOG_LOCAL2}, {"local3", (void *)LOG_LOCAL3}, {"local4", (void *)LOG_LOCAL4}, {"local5", (void *)LOG_LOCAL5}, {"local6", (void *)LOG_LOCAL6}, {"local7", (void *)LOG_LOCAL7}, {"lpr", (void *)LOG_LPR}, {"mail", (void *)LOG_MAIL}, {"news", (void *)LOG_NEWS}, #ifdef LOG_SECURITY {"security", (void *)LOG_SECURITY}, #endif {"syslog", (void *)LOG_SYSLOG}, {"user", (void *)LOG_USER}, {"uucp", (void *)LOG_UUCP} } ; /* serialize message for sending from signal handlers */ struct sermsg { int severity; #if HAVE_CLOCK_GETTIME struct timespec ts; #else struct timeval tv; #endif } ; static int diaginitialized; static int diag_sock_send = -1; static int diag_sock_recv = -1; static int diag_msg_avail = 0; /* !=0: messages from within signal handler may be waiting */ static int diag_init(void) { int handlersocks[2]; if (diaginitialized) { return 0; } diaginitialized = 1; /* gcc with GNU libc refuses to set this in the initializer */ diagopts.logfile = stderr; if (socketpair(AF_UNIX, SOCK_DGRAM, 0, handlersocks) < 0) { diag_sock_send = -1; diag_sock_recv = -1; return -1; } diag_sock_send = handlersocks[1]; diag_sock_recv = handlersocks[0]; return 0; } #define DIAG_INIT ((void)(diaginitialized || diag_init())) void diag_set(char what, const char *arg) { DIAG_INIT; switch (what) { const struct wordent *keywd; case 'y': diagopts.syslog = true; if (arg && arg[0]) { if ((keywd = keyw(facilitynames, arg, sizeof(facilitynames)/sizeof(struct wordent))) == NULL) { Error1("unknown syslog facility \"%s\"", arg); } else { diagopts.logfacility = (int)(size_t)keywd->desc; } } openlog(diagopts.progname, LOG_PID, diagopts.logfacility); if (diagopts.logfile != NULL && diagopts.logfile != stderr) { fclose(diagopts.logfile); } diagopts.logfile = NULL; break; case 'f': if (diagopts.logfile != NULL && diagopts.logfile != stderr) { fclose(diagopts.logfile); } if ((diagopts.logfile = fopen(arg, "a")) == NULL) { Error2("cannot open log file \"%s\": %s", arg, strerror(errno)); } break; case 's': if (diagopts.logfile != NULL && diagopts.logfile != stderr) { fclose(diagopts.logfile); } diagopts.logfile = stderr; break; /* logging to stderr is default */ case 'p': diagopts.progname = arg; openlog(diagopts.progname, LOG_PID, diagopts.logfacility); break; case 'd': --diagopts.msglevel; break; case 'u': diagopts.micros = true; break; default: msg(E_ERROR, "unknown diagnostic option %c", what); } } void diag_set_int(char what, int arg) { DIAG_INIT; switch (what) { case 'D': diagopts.msglevel = arg; break; case 'e': diagopts.exitlevel = arg; break; case 'x': diagopts.exitstatus = arg; break; case 'h': diagopts.withhostname = arg; if ((diagopts.hostname = getenv("HOSTNAME")) == NULL) { struct utsname ubuf; uname(&ubuf); diagopts.hostname = strdup(ubuf.nodename); } break; default: msg(E_ERROR, "unknown diagnostic option %c", what); } } int diag_get_int(char what) { DIAG_INIT; switch (what) { case 'y': return diagopts.syslog; case 's': return diagopts.logfile == stderr; case 'd': case 'D': return diagopts.msglevel; case 'e': return diagopts.exitlevel; } return -1; } const char *diag_get_string(char what) { DIAG_INIT; switch (what) { case 'p': return diagopts.progname; } return NULL; } /* Linux and AIX syslog format: Oct 4 17:10:37 hostname socat[52798]: D signal(13, 1) */ void msg(int level, const char *format, ...) { struct diag_dgram diag_dgram; va_list ap; /* does not perform a system call if nothing todo, thanks diag_msg_avail */ diag_dgram._errno = errno; /* keep for passing from signal handler to sock. reason is that strerror is definitely not async-signal-safe */ DIAG_INIT; /* in normal program flow (not in signal handler) */ /* first flush the queue of datagrams from the socket */ if (diag_msg_avail && !diag_in_handler) { diag_msg_avail = 0; /* _before_ flush to prevent inconsistent state when signal occurs inbetween */ diag_flush(); } if (level < diagopts.msglevel) { va_end(ap); return; } va_start(ap, format); /* we do only a minimum in the outer parts which may run in a signal handler these are: get actual time, level, serialized message and write them to socket */ diag_dgram.op = DIAG_OP_MSG; #if HAVE_CLOCK_GETTIME clock_gettime(CLOCK_REALTIME, &diag_dgram.now); #elif HAVE_GETTIMEOFDAY gettimeofday(&diag_dgram.now, NULL); #else diag_dgram.now = time(NULL); #endif diag_dgram.level = level; diag_dgram.exitcode = diagopts.exitstatus; vsnprintf_r(diag_dgram.text, sizeof(diag_dgram.text), format, ap); if (diag_in_handler && !diag_immediate_msg) { send(diag_sock_send, &diag_dgram, sizeof(diag_dgram)-TEXTLEN + strlen(diag_dgram.text)+1, MSG_DONTWAIT #ifdef MSG_NOSIGNAL |MSG_NOSIGNAL #endif ); diag_msg_avail = 1; va_end(ap); return; } msg2(&diag_dgram.now, diag_dgram.level, diagopts.exitstatus, 0, diag_dgram.text); va_end(ap); return; } void msg2( #if HAVE_CLOCK_GETTIME struct timespec *now, #elif HAVE_GETTIMEOFDAY struct timeval *now, #else time_t *now, #endif int level, /* E_INFO... */ int exitcode, /* on exit use this exit code */ int handler, /* message comes from signal handler */ const char *text) { time_t epoch; unsigned long micros; #if HAVE_STRFTIME struct tm struct_tm; #endif #define BUFLEN 512 char buff[BUFLEN], *bufp, *syslp; size_t bytes; #if HAVE_CLOCK_GETTIME epoch = now->tv_sec; #elif HAVE_GETTIMEOFDAY epoch = now->tv_sec; #else epoch = *now; #endif #if HAVE_STRFTIME bytes = strftime(buff, 20, "%Y/%m/%d %H:%M:%S", localtime_r(&epoch, &struct_tm)); buff[bytes] = '\0'; #else bytes = snprintf(buff, 11, F_time, epoch); #endif if (diagopts.micros) { #if HAVE_CLOCK_GETTIME micros = now->tv_nsec/1000; #elif HAVE_GETTIMEOFDAY micros = now->tv_usec; #else micros = 0; #endif bytes += sprintf(buff+19, ".%06lu ", micros); } else { buff[19] = ' '; buff[20] = '\0'; } bytes = strlen(buff); bufp = buff + bytes; if (diagopts.withhostname) { bytes = sprintf(bufp, "%s ", diagopts.hostname), bufp+=bytes; } bytes = sprintf(bufp, "%s["F_pid"] ", diagopts.progname, getpid()); bufp += bytes; syslp = bufp; *bufp++ = "DINWEF"[level]; #if 0 /* only for debugging socat */ if (handler) bufp[-1] = tolower(bufp[-1]); /* for debugging, low chars indicate messages from signal handlers */ #endif *bufp++ = ' '; strncpy(bufp, text, BUFLEN-(bufp-buff)-1); strcat(bufp, "\n"); _msg(level, buff, syslp); if (level >= diagopts.exitlevel) { if (E_NOTICE >= diagopts.msglevel) { snprintf_r(syslp, 16, "N exit(%d)\n", exitcode?exitcode:(diagopts.exitstatus?diagopts.exitstatus:1)); _msg(E_NOTICE, buff, syslp); } exit(exitcode?exitcode:(diagopts.exitstatus?diagopts.exitstatus:1)); } } static void _msg(int level, const char *buff, const char *syslp) { if (diagopts.syslog) { /* prevent format string attacks (thanks to CoKi) */ syslog(syslevel[level], "%s", syslp); } if (diagopts.logfile) { fputs(buff, diagopts.logfile); fflush(diagopts.logfile); } } /* handle the messages in the queue */ void diag_flush(void) { struct diag_dgram recv_dgram; char exitmsg[20]; while (recv(diag_sock_recv, &recv_dgram, sizeof(recv_dgram)-1, MSG_DONTWAIT) > 0) { recv_dgram.text[TEXTLEN-1] = '\0'; switch (recv_dgram.op) { case DIAG_OP_EXIT: /* we want the actual time, not when this dgram was sent */ #if HAVE_CLOCK_GETTIME clock_gettime(CLOCK_REALTIME, &recv_dgram.now); #elif HAVE_GETTIMEOFDAY gettimeofday(&recv_dgram.now, NULL); #else recv_dgram.now = time(NULL); #endif if (E_NOTICE >= diagopts.msglevel) { snprintf_r(exitmsg, sizeof(exitmsg), "exit(%d)", recv_dgram.exitcode?recv_dgram.exitcode:1); msg2(&recv_dgram.now, E_NOTICE, recv_dgram.exitcode?recv_dgram.exitcode:1, 1, exitmsg); } exit(recv_dgram.exitcode?recv_dgram.exitcode:1); case DIAG_OP_MSG: if (recv_dgram._errno) { /* there might be a %m control in the string (glibc compatible, replace with strerror(...errno) ) */ char text[TEXTLEN]; errno = recv_dgram._errno; snprinterr(text, TEXTLEN, recv_dgram.text); msg2(&recv_dgram.now, recv_dgram.level, recv_dgram.exitcode, 1, text); } else { msg2(&recv_dgram.now, recv_dgram.level, recv_dgram.exitcode, 1, recv_dgram.text); } break; } } } /* use a new log output file descriptor that is dup'ed from the current one. this is useful when socat logs to stderr but fd 2 should be redirected to serve other purposes */ int diag_dup(void) { int newfd; DIAG_INIT; if (diagopts.logfile == NULL) { return -1; } newfd = dup(fileno(diagopts.logfile)); if (diagopts.logfile != stderr) { fclose(diagopts.logfile); } if (newfd >= 0) { diagopts.logfile = fdopen(newfd, "w"); } return newfd; } /* this function is kind of async-signal-safe exit(). When invoked from signal handler it defers exit. */ void diag_exit(int status) { struct diag_dgram diag_dgram; if (diag_in_handler && !diag_immediate_exit) { diag_dgram.op = DIAG_OP_EXIT; diag_dgram.exitcode = status; send(diag_sock_send, &diag_dgram, sizeof(diag_dgram)-TEXTLEN, MSG_DONTWAIT #ifdef MSG_NOSIGNAL |MSG_NOSIGNAL #endif ); return; } _diag_exit(status); } static void _diag_exit(int status) { Exit(status); } /* a function that appears to the application like select() but that also monitors the diag socket diag_sock_recv and processes its messages. Do not call from within a signal handler. */ int diag_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { int result; fd_set save_readfds, save_writefds, save_exceptfds; if (readfds) { memcpy(&save_readfds, readfds, sizeof(*readfds)); } if (writefds) { memcpy(&save_writefds, writefds, sizeof(*writefds)); } if (exceptfds) { memcpy(&save_exceptfds, exceptfds, sizeof(*exceptfds)); } while (1) { FD_SET(diag_sock_recv, readfds); result = Select(nfds, readfds, writefds, exceptfds, timeout); if (!FD_ISSET(diag_sock_recv, readfds)) { /* select terminated not due to diag_sock_recv, normalt continuation */ break; } diag_flush(); if (readfds) { memcpy(readfds, &save_readfds, sizeof(*readfds)); } if (writefds) { memcpy(writefds, &save_writefds, sizeof(*writefds)); } if (exceptfds) { memcpy(exceptfds, &save_exceptfds, sizeof(*exceptfds)); } } return result; } socat-1.7.3.1/xio-openssl.c0000644000201000020100000015121012652637326015220 0ustar gerhardgerhard/* source: xio-openssl.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the implementation of the openssl addresses */ #include "xiosysincludes.h" #if WITH_OPENSSL /* make this address configure dependend */ #include #include #include "xioopen.h" #include "xio-fd.h" #include "xio-socket.h" /* _xioopen_connect() */ #include "xio-listen.h" #include "xio-ipapp.h" #include "xio-openssl.h" /* the openssl library requires a file descriptor for external communications. so our best effort is to provide any possible kind of un*x file descriptor (not only tcp, but also pipes, stdin, files...) for tcp we want to provide support for socks and proxy. read and write functions must use the openssl crypt versions. but currently only plain tcp4 is implemented. */ /* Linux: "man 3 ssl" */ /* generate a simple openssl server for testing: 1) generate a private key openssl genrsa -out server.key 1024 2) generate a self signed cert openssl req -new -key server.key -x509 -days 3653 -out server.crt enter fields... 3) generate the pem file cat server.key server.crt >server.pem openssl s_server (listens on 4433/tcp) */ /* 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, unsigned groups, int dummy1, int dummy2, int dummy3); /* 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, unsigned groups, int dummy1, int dummy2, int dummy3); static int openssl_SSL_ERROR_SSL(int level, const char *funcname); static int openssl_handle_peer_certificate(struct single *xfd, 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 openssl_delete_cert_info(void); /* description record for ssl connect */ const struct addrdesc addr_openssl = { "openssl", /* keyword for selecting this address type in xioopen calls (canonical or main name) */ 3, /* data flow directions this address supports on API layer: 1..read, 2..write, 3..both */ xioopen_openssl_connect, /* a function pointer used to "open" these addresses.*/ GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_OPENSSL|GROUP_RETRY, /* bitwise OR of address groups this address belongs to. You might have to specify a new group in xioopts.h */ 0, /* an integer passed to xioopen_openssl; makes it possible to use the same xioopen_openssl function for slightly different address types. */ 0, /* like previous argument */ 0 /* like previous arguments, but pointer type. No trailing comma or semicolon! */ HELP("::") /* a text displayed from xio help function. No trailing comma or semicolon! only generates this text if WITH_HELP is != 0 */ } ; #if WITH_LISTEN /* description record for ssl listen */ const struct addrdesc addr_openssl_listen = { "openssl-listen", /* keyword for selecting this address type in xioopen calls (canonical or main name) */ 3, /* data flow directions this address supports on API layer: 1..read, 2..write, 3..both */ xioopen_openssl_listen, /* a function pointer used to "open" these addresses.*/ GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_OPENSSL|GROUP_RETRY, /* bitwise OR of address groups this address belongs to. You might have to specify a new group in xioopts.h */ 0, /* an integer passed to xioopen_openssl_listen; makes it possible to use the same xioopen_openssl_listen function for slightly different address types. */ 0, /* like previous argument */ 0 /* like previous arguments, but pointer type. No trailing comma or semicolon! */ HELP(":") /* a text displayed from xio help function. No trailing comma or semicolon! only generates this text if WITH_HELP is != 0 */ } ; #endif /* WITH_LISTEN */ /* both client and server */ const struct optdesc opt_openssl_cipherlist = { "openssl-cipherlist", "ciphers", OPT_OPENSSL_CIPHERLIST, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC }; const struct optdesc opt_openssl_method = { "openssl-method", "method", OPT_OPENSSL_METHOD, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC }; const struct optdesc opt_openssl_verify = { "openssl-verify", "verify", OPT_OPENSSL_VERIFY, GROUP_OPENSSL, PH_SPEC, TYPE_BOOL, OFUNC_SPEC }; const struct optdesc opt_openssl_certificate = { "openssl-certificate", "cert", OPT_OPENSSL_CERTIFICATE, GROUP_OPENSSL, PH_SPEC, TYPE_FILENAME, OFUNC_SPEC }; const struct optdesc opt_openssl_key = { "openssl-key", "key", OPT_OPENSSL_KEY, GROUP_OPENSSL, PH_SPEC, TYPE_FILENAME, OFUNC_SPEC }; const struct optdesc opt_openssl_dhparam = { "openssl-dhparam", "dh", OPT_OPENSSL_DHPARAM, GROUP_OPENSSL, PH_SPEC, TYPE_FILENAME, OFUNC_SPEC }; const struct optdesc opt_openssl_cafile = { "openssl-cafile", "cafile", OPT_OPENSSL_CAFILE, GROUP_OPENSSL, PH_SPEC, TYPE_FILENAME, OFUNC_SPEC }; const struct optdesc opt_openssl_capath = { "openssl-capath", "capath", OPT_OPENSSL_CAPATH, GROUP_OPENSSL, PH_SPEC, TYPE_FILENAME, OFUNC_SPEC }; const struct optdesc opt_openssl_egd = { "openssl-egd", "egd", OPT_OPENSSL_EGD, GROUP_OPENSSL, PH_SPEC, TYPE_FILENAME, OFUNC_SPEC }; const struct optdesc opt_openssl_pseudo = { "openssl-pseudo", "pseudo", OPT_OPENSSL_PSEUDO, GROUP_OPENSSL, PH_SPEC, TYPE_BOOL, OFUNC_SPEC }; #if OPENSSL_VERSION_NUMBER >= 0x00908000L const struct optdesc opt_openssl_compress = { "openssl-compress", "compress", OPT_OPENSSL_COMPRESS, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC }; #endif #if WITH_FIPS const struct optdesc opt_openssl_fips = { "openssl-fips", "fips", OPT_OPENSSL_FIPS, GROUP_OPENSSL, PH_SPEC, TYPE_BOOL, OFUNC_SPEC }; #endif const struct optdesc opt_openssl_commonname = { "openssl-commonname", "cn", OPT_OPENSSL_COMMONNAME, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC }; /* If FIPS is compiled in, we need to track if the user asked for FIPS mode. * On forks, the FIPS mode must be reset by a disable, then enable since * FIPS tracks the process ID that initializes things. * If FIPS is not compiled in, no tracking variable is needed * and we make the reset code compile out. This keeps the * rest of the code below free of FIPS related #ifs */ #if WITH_FIPS static bool xio_openssl_fips = false; int xio_reset_fips_mode(void) { if (xio_openssl_fips) { if(!sycFIPS_mode_set(0) || !sycFIPS_mode_set(1)) { ERR_load_crypto_strings(); ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE)); Error("Failed to reset OpenSSL FIPS mode"); xio_openssl_fips = false; return -1; } } return 0; } #else #define xio_reset_fips_mode() 0 #endif static void openssl_conn_loginfo(SSL *ssl) { Notice1("SSL connection using %s", SSL_get_cipher(ssl)); #if OPENSSL_VERSION_NUMBER >= 0x00908000L { const COMP_METHOD *comp, *expansion; comp = sycSSL_get_current_compression(ssl); expansion = sycSSL_get_current_expansion(ssl); Notice1("SSL connection compression \"%s\"", comp?sycSSL_COMP_get_name(comp):"none"); Notice1("SSL connection expansion \"%s\"", expansion?sycSSL_COMP_get_name(expansion):"none"); } #endif } /* 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), writing (1), or both (2) ? */ xiofile_t *xxfd, /* a xio file descriptor structure, already allocated */ unsigned groups, /* the matching address groups... */ int dummy1, /* first transparent integer value from addr_openssl */ int dummy2, /* second transparent integer value from addr_openssl */ int dummy3) /* transparent pointer value from addr_openssl */ { struct single *xfd = &xxfd->stream; struct opt *opts0 = NULL; const char *hostname, *portname; int pf = PF_UNSPEC; int ipproto = IPPROTO_TCP; int socktype = SOCK_STREAM; bool dofork = false; union sockaddr_union us_sa, *us = &us_sa; union sockaddr_union them_sa, *them = &them_sa; socklen_t uslen = sizeof(us_sa); socklen_t themlen = sizeof(them_sa); bool needbind = false; bool lowport = false; int level; SSL_CTX* ctx; bool opt_ver = true; /* verify peer certificate */ char *opt_cert = NULL; /* file name of client certificate */ const char *opt_commonname = NULL; /* for checking peer certificate */ int result; if (!(xioflags & XIO_MAYCONVERT)) { Error("address with data processing not allowed here"); return STAT_NORETRY; } xfd->flags |= XIO_DOESCONVERT; if (argc != 3) { Error1("%s: 2 parameters required", argv[0]); return STAT_NORETRY; } hostname = argv[1]; portname = argv[2]; if (hostname[0] == '\0') { /* we catch this explicitely because empty commonname (peername) disables commonName check of peer certificate */ Error1("%s: empty host name", argv[0]); return STAT_NORETRY; } xfd->howtoend = END_SHUTDOWN; if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); retropt_bool(opts, OPT_FORK, &dofork); retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert); retropt_string(opts, OPT_OPENSSL_COMMONNAME, (char **)&opt_commonname); if (opt_commonname == NULL) { opt_commonname = hostname; } result = _xioopen_openssl_prepare(opts, xfd, false, &opt_ver, opt_cert, &ctx); if (result != STAT_OK) return STAT_NORETRY; result = _xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto, xfd->para.socket.ip.res_opts[1], xfd->para.socket.ip.res_opts[0], them, &themlen, us, &uslen, &needbind, &lowport, socktype); if (result != STAT_OK) return STAT_NORETRY; if (xioopts.logopt == 'm') { Info("starting connect loop, switching to syslog"); diag_set('y', xioopts.syslogfac); xioopts.logopt = 'y'; } else { Info("starting connect loop"); } do { /* loop over failed connect and SSL handshake attempts */ #if WITH_RETRY if (xfd->forever || xfd->retry) { level = E_INFO; } else #endif /* WITH_RETRY */ level = E_ERROR; /* this cannot fork because we retrieved fork option above */ result = _xioopen_connect(xfd, needbind?(struct sockaddr *)us:NULL, uslen, (struct sockaddr *)them, themlen, opts, pf, socktype, ipproto, lowport, level); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: if (xfd->forever || xfd->retry) { dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); if (result == STAT_RETRYLATER) { Nanosleep(&xfd->intervall, NULL); } --xfd->retry; continue; } return STAT_NORETRY; #endif /* WITH_RETRY */ default: return result; } /*! isn't this too early? */ if ((result = _xio_openlate(xfd, opts)) < 0) { return result; } result = _xioopen_openssl_connect(xfd, 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) { Close(xfd->fd); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); if (result == STAT_RETRYLATER) { Nanosleep(&xfd->intervall, NULL); } --xfd->retry; continue; } #endif /* WITH_RETRY */ default: return STAT_NORETRY; } if (dofork) { xiosetchilddied(); /* set SIGCHLD handler */ } #if WITH_RETRY if (dofork) { pid_t pid; int level = E_ERROR; if (xfd->forever || xfd->retry) { level = E_WARN; } while ((pid = xio_fork(false, level)) < 0) { if (xfd->forever || --xfd->retry) { Nanosleep(&xfd->intervall, NULL); continue; } return STAT_RETRYLATER; } if (pid == 0) { /* child process */ xfd->forever = false; xfd->retry = 0; break; } /* parent process */ Close(xfd->fd); sycSSL_free(xfd->para.openssl.ssl); xfd->para.openssl.ssl = NULL; /* with and without retry */ Nanosleep(&xfd->intervall, NULL); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); continue; /* with next socket() bind() connect() */ } #endif /* WITH_RETRY */ break; } while (true); /* drop out on success */ openssl_conn_loginfo(xfd->para.openssl.ssl); /* fill in the fd structure */ return STAT_OK; } /* 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 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, bool opt_ver, const char *opt_commonname, SSL_CTX *ctx, int level) { SSL *ssl; unsigned long err; int result; /* create a SSL object */ if ((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)); } /*Error("SSL_new()");*/ return STAT_RETRYLATER; } xfd->para.openssl.ssl = ssl; result = xioSSL_set_fd(xfd, level); if (result != STAT_OK) { sycSSL_free(xfd->para.openssl.ssl); xfd->para.openssl.ssl = NULL; return result; } result = xioSSL_connect(xfd, opt_commonname, opt_ver, level); if (result != STAT_OK) { sycSSL_free(xfd->para.openssl.ssl); xfd->para.openssl.ssl = NULL; return result; } result = openssl_handle_peer_certificate(xfd, opt_commonname, opt_ver, level); if (result != STAT_OK) { sycSSL_free(xfd->para.openssl.ssl); xfd->para.openssl.ssl = NULL; return result; } return STAT_OK; } #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), writing (1), or both (2) ? */ xiofile_t *xxfd, /* a xio file descriptor structure, already allocated */ unsigned groups, /* the matching address groups... */ int dummy1, /* first transparent integer value from addr_openssl */ int dummy2, /* second transparent integer value from addr_openssl */ int dummy3) /* transparent pointer value from addr_openssl */ { struct single *xfd = &xxfd->stream; const char *portname; struct opt *opts0 = NULL; union sockaddr_union us_sa, *us = &us_sa; socklen_t uslen = sizeof(us_sa); int pf; int socktype = SOCK_STREAM; int ipproto = IPPROTO_TCP; /*! lowport? */ int level; SSL_CTX* ctx; bool opt_ver = true; /* verify peer certificate - changed with 1.6.0 */ char *opt_cert = NULL; /* file name of server certificate */ const char *opt_commonname = NULL; /* for checking peer certificate */ int result; if (!(xioflags & XIO_MAYCONVERT)) { Error("address with data processing not allowed here"); return STAT_NORETRY; } xfd->flags |= XIO_DOESCONVERT; if (argc != 2) { Error1("%s: 1 parameter required", argv[0]); return STAT_NORETRY; } #if WITH_IP4 && WITH_IP6 pf = xioopts.default_ip=='6'?PF_INET6:PF_INET; #elif WITH_IP6 pf = PF_INET6; #else pf = PF_INET; #endif portname = argv[1]; xfd->howtoend = END_SHUTDOWN; if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert); if (opt_cert == NULL) { Warn("no certificate given; consider option \"cert\""); } retropt_string(opts, OPT_OPENSSL_COMMONNAME, (char **)&opt_commonname); applyopts(-1, opts, PH_EARLY); result = _xioopen_openssl_prepare(opts, xfd, true, &opt_ver, opt_cert, &ctx); if (result != STAT_OK) return STAT_NORETRY; if (_xioopen_ipapp_listen_prepare(opts, &opts0, portname, &pf, ipproto, xfd->para.socket.ip.res_opts[1], xfd->para.socket.ip.res_opts[0], us, &uslen, socktype) != STAT_OK) { return STAT_NORETRY; } xfd->addr = &addr_openssl_listen; xfd->dtype = XIODATA_OPENSSL; while (true) { /* loop over failed attempts */ #if WITH_RETRY if (xfd->forever || xfd->retry) { level = E_INFO; } else #endif /* WITH_RETRY */ level = E_ERROR; /* tcp listen; this can fork() for us; it only returns on error or on successful establishment of tcp connection */ result = _xioopen_listen(xfd, xioflags, (struct sockaddr *)us, uslen, opts, pf, socktype, IPPROTO_TCP, #if WITH_RETRY (xfd->retry||xfd->forever)?E_INFO:E_ERROR #else E_ERROR #endif /* WITH_RETRY */ ); /*! not sure if we should try again on retry/forever */ switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: if (xfd->forever || xfd->retry) { dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); if (result == STAT_RETRYLATER) { Nanosleep(&xfd->intervall, NULL); } dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); --xfd->retry; continue; } return STAT_NORETRY; #endif /* WITH_RETRY */ default: return result; } result = _xioopen_openssl_listen(xfd, 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) { dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); if (result == STAT_RETRYLATER) { Nanosleep(&xfd->intervall, NULL); } dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); --xfd->retry; continue; } return STAT_NORETRY; #endif /* WITH_RETRY */ default: return result; } openssl_conn_loginfo(xfd->para.openssl.ssl); break; } /* drop out on success */ /* fill in the fd structure */ return STAT_OK; } int _xioopen_openssl_listen(struct single *xfd, bool opt_ver, const char *opt_commonname, SSL_CTX *ctx, int level) { char error_string[120]; unsigned long err; int errint, ret; /* create an SSL object */ if ((xfd->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)); } /*Error("SSL_new()");*/ return STAT_NORETRY; } /* assign the network connection to the SSL object */ if (sycSSL_set_fd(xfd->para.openssl.ssl, xfd->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)); } } #if WITH_DEBUG { int i = 0; const char *ciphers = NULL; Debug("available ciphers:"); do { ciphers = SSL_get_cipher_list(xfd->para.openssl.ssl, i); if (ciphers == NULL) break; Debug2("CIPHERS pri=%d: %s", i, ciphers); ++i; } while (1); } #endif /* WITH_DEBUG */ /* connect via SSL by performing handshake */ if ((ret = sycSSL_accept(xfd->para.openssl.ssl)) <= 0) { /*if (ERR_peek_error() == 0) Msg(level, "SSL_accept() failed");*/ errint = SSL_get_error(xfd->para.openssl.ssl, ret); switch (errint) { case SSL_ERROR_NONE: Msg(level, "ok"); break; case SSL_ERROR_ZERO_RETURN: Msg(level, "connection closed (wrong version number?)"); break; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_CONNECT: case SSL_ERROR_WANT_X509_LOOKUP: Msg(level, "nonblocking operation did not complete"); break; /*!*/ case SSL_ERROR_SYSCALL: if (ERR_peek_error() == 0) { if (ret == 0) { Msg(level, "SSL_accept(): socket closed by peer"); } else if (ret == -1) { Msg1(level, "SSL_accept(): %s", strerror(errno)); } } else { Msg(level, "I/O error"); /*!*/ while (err = ERR_get_error()) { ERR_error_string_n(err, error_string, sizeof(error_string)); Msg4(level, "SSL_accept(): %s / %s / %s / %s", error_string, ERR_lib_error_string(err), ERR_func_error_string(err), ERR_reason_error_string(err)); } /* Msg1(level, "SSL_accept(): %s", ERR_error_string(e, buf));*/ } break; case SSL_ERROR_SSL: /*ERR_print_errors_fp(stderr);*/ openssl_SSL_ERROR_SSL(level, "SSL_accept"); break; default: Msg(level, "unknown error"); } return STAT_RETRYLATER; } if (openssl_handle_peer_certificate(xfd, opt_commonname, opt_ver, E_ERROR/*!*/) < 0) { return STAT_NORETRY; } return STAT_OK; } #endif /* WITH_LISTEN */ #if OPENSSL_VERSION_NUMBER >= 0x00908000L /* In OpenSSL 0.9.7 compression methods could be added using * SSL_COMP_add_compression_method(3), but the implemntation is not compatible * with the standard (RFC3749). */ static int openssl_setup_compression(SSL_CTX *ctx, char *method) { STACK_OF(SSL_COMP)* comp_methods; assert(method); /* Getting the stack of compression methods has the intended side-effect of * initializing the SSL library's compression part. */ comp_methods = SSL_COMP_get_compression_methods(); if (!comp_methods) { Info("OpenSSL built without compression support"); return STAT_OK; } if (strcasecmp(method, "auto") == 0) { Info("Using default OpenSSL compression"); return STAT_OK; } if (strcasecmp(method, "none") == 0) { /* Disable compression */ #ifdef SSL_OP_NO_COMPRESSION Info("Disabling OpenSSL compression"); SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION); #else /* SSL_OP_NO_COMPRESSION was only introduced in OpenSSL 0.9.9 (released * as 1.0.0). Removing all compression methods is a work-around for * earlier versions of OpenSSL, but it affects all SSL connections. */ Info("Disabling OpenSSL compression globally"); sk_SSL_COMP_zero(comp_methods); #endif return STAT_OK; } /* zlib compression in OpenSSL before version 0.9.8e-beta1 uses the libc's * default malloc/free instead of the ones passed to OpenSSL. Should socat * ever use custom malloc/free functions for OpenSSL, this must be taken * into consideration. See OpenSSL bug #1468. */ Error1("openssl-compress=\"%s\": unknown compression method", method); return STAT_NORETRY; } #endif int _xioopen_openssl_prepare(struct opt *opts, struct single *xfd,/* a xio file descriptor structure, already allocated */ bool server, /* SSL client: false */ bool *opt_ver, const char *opt_cert, SSL_CTX **ctx) { bool opt_fips = false; const SSL_METHOD *method = NULL; char *me_str = NULL; /* method string */ char *ci_str = "HIGH:-NULL:-PSK:-aNULL"; /* cipher string */ char *opt_key = NULL; /* file name of client private key */ char *opt_dhparam = NULL; /* file name of DH params */ char *opt_cafile = NULL; /* certificate authority file */ char *opt_capath = NULL; /* certificate authority directory */ char *opt_egd = NULL; /* entropy gathering daemon socket path */ #if OPENSSL_VERSION_NUMBER >= 0x00908000L char *opt_compress = NULL; /* compression method */ #endif bool opt_pseudo = false; /* use pseudo entropy if nothing else */ unsigned long err; int result; xfd->addr = &addr_openssl; xfd->dtype = XIODATA_OPENSSL; retropt_bool(opts, OPT_OPENSSL_FIPS, &opt_fips); retropt_string(opts, OPT_OPENSSL_METHOD, &me_str); retropt_string(opts, OPT_OPENSSL_CIPHERLIST, &ci_str); retropt_bool(opts, OPT_OPENSSL_VERIFY, opt_ver); retropt_string(opts, OPT_OPENSSL_CAFILE, &opt_cafile); retropt_string(opts, OPT_OPENSSL_CAPATH, &opt_capath); retropt_string(opts, OPT_OPENSSL_KEY, &opt_key); retropt_string(opts, OPT_OPENSSL_DHPARAM, &opt_dhparam); retropt_string(opts, OPT_OPENSSL_EGD, &opt_egd); retropt_bool(opts,OPT_OPENSSL_PSEUDO, &opt_pseudo); #if OPENSSL_VERSION_NUMBER >= 0x00908000L retropt_string(opts, OPT_OPENSSL_COMPRESS, &opt_compress); #endif #if WITH_FIPS if (opt_fips) { if (!sycFIPS_mode_set(1)) { ERR_load_crypto_strings(); ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE)); Error("Failed to set FIPS mode"); } else { xio_openssl_fips = true; } } #endif openssl_delete_cert_info(); OpenSSL_add_all_algorithms(); OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); sycSSL_load_error_strings(); /* OpenSSL preparation */ sycSSL_library_init(); /*! actions_to_seed_PRNG();*/ if (!server) { if (me_str != NULL) { if (false) { ; /* for canonical reasons */ #if HAVE_SSLv2_client_method } else if (!strcasecmp(me_str, "SSL2")) { method = sycSSLv2_client_method(); #endif #if HAVE_SSLv3_client_method } else if (!strcasecmp(me_str, "SSL3")) { method = sycSSLv3_client_method(); #endif #if HAVE_SSLv23_client_method } else if (!strcasecmp(me_str, "SSL23")) { method = sycSSLv23_client_method(); #endif #if HAVE_TLSv1_client_method } else if (!strcasecmp(me_str, "TLS1") || !strcasecmp(me_str, "TLS1.0")) { method = sycTLSv1_client_method(); #endif #if HAVE_TLSv1_1_client_method } else if (!strcasecmp(me_str, "TLS1.1")) { method = sycTLSv1_1_client_method(); #endif #if HAVE_TLSv1_2_client_method } else if (!strcasecmp(me_str, "TLS1.2")) { method = sycTLSv1_2_client_method(); #endif #if HAVE_DTLSv1_client_method } else if (!strcasecmp(me_str, "DTLS") || !strcasecmp(me_str, "DTLS1")) { method = sycDTLSv1_client_method(); #endif } else { Error1("openssl-method=\"%s\": method unknown or not provided by library", me_str); } } else { #if HAVE_SSLv23_client_method method = sycSSLv23_client_method(); #elif HAVE_TLSv1_2_client_method method = sycTLSv1_2_client_method(); #elif HAVE_TLSv1_1_client_method method = sycTLSv1_1_client_method(); #elif HAVE_TLSv1_client_method method = sycTLSv1_client_method(); #elif HAVE_SSLv3_client_method method = sycSSLv3_client_method(); #elif HAVE_SSLv2_client_method method = sycSSLv2_client_method(); #else # error "OpenSSL does not seem to provide client methods" #endif } } else /* server */ { if (me_str != 0) { if (false) { ; /* for canonical reasons */ #if HAVE_SSLv2_server_method } else if (!strcasecmp(me_str, "SSL2")) { method = sycSSLv2_server_method(); #endif #if HAVE_SSLv3_server_method } else if (!strcasecmp(me_str, "SSL3")) { method = sycSSLv3_server_method(); #endif #if HAVE_SSLv23_server_method } else if (!strcasecmp(me_str, "SSL23")) { method = sycSSLv23_server_method(); #endif #if HAVE_TLSv1_server_method } else if (!strcasecmp(me_str, "TLS1") || !strcasecmp(me_str, "TLS1.0")) { method = sycTLSv1_server_method(); #endif #if HAVE_TLSv1_1_server_method } else if (!strcasecmp(me_str, "TLS1.1")) { method = sycTLSv1_1_server_method(); #endif #if HAVE_TLSv1_2_server_method } else if (!strcasecmp(me_str, "TLS1.2")) { method = sycTLSv1_2_server_method(); #endif #if HAVE_DTLSv1_server_method } else if (!strcasecmp(me_str, "DTLS") || !strcasecmp(me_str, "DTLS1")) { method = sycDTLSv1_server_method(); #endif } else { Error1("openssl-method=\"%s\": method unknown or not provided by library", me_str); } } else { #if HAVE_SSLv23_server_method method = sycSSLv23_server_method(); #elif HAVE_TLSv1_2_server_method method = sycTLSv1_2_server_method(); #elif HAVE_TLSv1_1_server_method method = sycTLSv1_1_server_method(); #elif HAVE_TLSv1_server_method method = sycTLSv1_server_method(); #elif HAVE_SSLv3_server_method method = sycSSLv3_server_method(); #elif HAVE_SSLv2_server_method method = sycSSLv2_server_method(); #else # error "OpenSSL does not seem to provide client methods" #endif } } if (opt_egd) { sycRAND_egd(opt_egd); } if (opt_pseudo) { long int randdata; /* initialize libc random from actual microseconds */ struct timeval tv; struct timezone tz; tz.tz_minuteswest = 0; tz.tz_dsttime = 0; if ((result = Gettimeofday(&tv, &tz)) < 0) { Warn2("gettimeofday(%p, {0,0}): %s", &tv, strerror(errno)); } srandom(tv.tv_sec*1000000+tv.tv_usec); while (!RAND_status()) { randdata = random(); Debug2("RAND_seed(0x{%lx}, "F_Zu")", randdata, sizeof(randdata)); RAND_seed(&randdata, sizeof(randdata)); } } if ((*ctx = sycSSL_CTX_new(method)) == NULL) { if (ERR_peek_error() == 0) Error("SSL_CTX_new()"); while (err = ERR_get_error()) { Error1("SSL_CTX_new(): %s", ERR_error_string(err, NULL)); } /*ERR_clear_error;*/ return STAT_RETRYLATER; } { static unsigned char dh2048_p[] = { 0x00,0xdc,0x21,0x64,0x56,0xbd,0x9c,0xb2,0xac,0xbe,0xc9,0x98,0xef,0x95,0x3e, 0x26,0xfa,0xb5,0x57,0xbc,0xd9,0xe6,0x75,0xc0,0x43,0xa2,0x1c,0x7a,0x85,0xdf, 0x34,0xab,0x57,0xa8,0xf6,0xbc,0xf6,0x84,0x7d,0x05,0x69,0x04,0x83,0x4c,0xd5, 0x56,0xd3,0x85,0x09,0x0a,0x08,0xff,0xb5,0x37,0xa1,0xa3,0x8a,0x37,0x04,0x46, 0xd2,0x93,0x31,0x96,0xf4,0xe4,0x0d,0x9f,0xbd,0x3e,0x7f,0x9e,0x4d,0xaf,0x08, 0xe2,0xe8,0x03,0x94,0x73,0xc4,0xdc,0x06,0x87,0xbb,0x6d,0xae,0x66,0x2d,0x18, 0x1f,0xd8,0x47,0x06,0x5c,0xcf,0x8a,0xb5,0x00,0x51,0x57,0x9b,0xea,0x1e,0xd8, 0xdb,0x8e,0x3c,0x1f,0xd3,0x2f,0xba,0x1f,0x5f,0x3d,0x15,0xc1,0x3b,0x2c,0x82, 0x42,0xc8,0x8c,0x87,0x79,0x5b,0x38,0x86,0x3a,0xeb,0xfd,0x81,0xa9,0xba,0xf7, 0x26,0x5b,0x93,0xc5,0x3e,0x03,0x30,0x4b,0x00,0x5c,0xb6,0x23,0x3e,0xea,0x94, 0xc3,0xb4,0x71,0xc7,0x6e,0x64,0x3b,0xf8,0x92,0x65,0xad,0x60,0x6c,0xd4,0x7b, 0xa9,0x67,0x26,0x04,0xa8,0x0a,0xb2,0x06,0xeb,0xe0,0x7d,0x90,0xdd,0xdd,0xf5, 0xcf,0xb4,0x11,0x7c,0xab,0xc1,0xa3,0x84,0xbe,0x27,0x77,0xc7,0xde,0x20,0x57, 0x66,0x47,0xa7,0x35,0xfe,0x0d,0x6a,0x1c,0x52,0xb8,0x58,0xbf,0x26,0x33,0x81, 0x5e,0xb7,0xa9,0xc0,0xee,0x58,0x11,0x74,0x86,0x19,0x08,0x89,0x1c,0x37,0x0d, 0x52,0x47,0x70,0x75,0x8b,0xa8,0x8b,0x30,0x11,0x71,0x36,0x62,0xf0,0x73,0x41, 0xee,0x34,0x9d,0x0a,0x2b,0x67,0x4e,0x6a,0xa3,0xe2,0x99,0x92,0x1b,0xf5,0x32, 0x73,0x63 }; static unsigned char dh2048_g[] = { 0x02, }; DH *dh; unsigned long err; if ((dh = DH_new()) == NULL) { while (err = ERR_get_error()) { Warn1("DH_new(): %s", ERR_error_string(err, NULL)); } Error("DH_new() failed"); } else { dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL); dh->g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL); if ((dh->p == NULL) || (dh->g == NULL)) { while (err = ERR_get_error()) { Warn1("BN_bin2bn(): %s", ERR_error_string(err, NULL)); } Error("BN_bin2bn() failed"); } else { if (sycSSL_CTX_set_tmp_dh(*ctx, dh) <= 0) { while (err = ERR_get_error()) { Warn3("SSL_CTX_set_tmp_dh(%p, %p): %s", *ctx, dh, ERR_error_string(err, NULL)); } Error2("SSL_CTX_set_tmp_dh(%p, %p) failed", *ctx, dh); } /*! OPENSSL_free(dh->p,g)? doc does not tell so */ } DH_free(dh); } } #if defined(EC_KEY) /* not on Openindiana 5.11 */ { /* see http://openssl.6102.n7.nabble.com/Problem-with-cipher-suite-ECDHE-ECDSA-AES256-SHA384-td42229.html */ int nid; EC_KEY *ecdh; #if 0 nid = OBJ_sn2nid(ECDHE_CURVE); if (nid == NID_undef) { Error("openssl: failed to set ECDHE parameters"); return -1; } #endif nid = NID_X9_62_prime256v1; ecdh = EC_KEY_new_by_curve_name(nid); if (NULL == ecdh) { Error("openssl: failed to set ECDHE parameters"); return -1; } SSL_CTX_set_tmp_ecdh(*ctx, ecdh); } #endif /* !defined(EC_KEY) */ #if OPENSSL_VERSION_NUMBER >= 0x00908000L if (opt_compress) { int result; result = openssl_setup_compression(*ctx, opt_compress); if (result != STAT_OK) { return result; } } #endif if (opt_cafile != NULL || opt_capath != NULL) { if (sycSSL_CTX_load_verify_locations(*ctx, opt_cafile, opt_capath) != 1) { int result; if ((result = openssl_SSL_ERROR_SSL(E_ERROR, "SSL_CTX_load_verify_locations")) != STAT_OK) { /*! free ctx */ return STAT_RETRYLATER; } } #ifdef HAVE_SSL_CTX_set_default_verify_paths } else { SSL_CTX_set_default_verify_paths(*ctx); #endif } if (opt_cert) { BIO *bio; DH *dh; if (sycSSL_CTX_use_certificate_chain_file(*ctx, opt_cert) <= 0) { /*! trace functions */ /*0 ERR_print_errors_fp(stderr);*/ if (ERR_peek_error() == 0) Error2("SSL_CTX_use_certificate_file(%p, \"%s\", SSL_FILETYPE_PEM) failed", *ctx, opt_cert); while (err = ERR_get_error()) { Error1("SSL_CTX_use_certificate_file(): %s", ERR_error_string(err, NULL)); } return STAT_RETRYLATER; } if (sycSSL_CTX_use_PrivateKey_file(*ctx, opt_key?opt_key:opt_cert, SSL_FILETYPE_PEM) <= 0) { /*ERR_print_errors_fp(stderr);*/ openssl_SSL_ERROR_SSL(E_ERROR/*!*/, "SSL_CTX_use_PrivateKey_file"); return STAT_RETRYLATER; } if (opt_dhparam == NULL) { opt_dhparam = (char *)opt_cert; } if ((bio = sycBIO_new_file(opt_dhparam, "r")) == NULL) { Warn2("BIO_new_file(\"%s\", \"r\"): %s", opt_dhparam, strerror(errno)); } else { if ((dh = sycPEM_read_bio_DHparams(bio, NULL, NULL, NULL)) == NULL) { Info1("PEM_read_bio_DHparams(%p, NULL, NULL, NULL): error", bio); } else { BIO_free(bio); if (sycSSL_CTX_set_tmp_dh(*ctx, dh) <= 0) { while (err = ERR_get_error()) { Warn3("SSL_CTX_set_tmp_dh(%p, %p): %s", *ctx, dh, ERR_error_string(err, NULL)); } Error2("SSL_CTX_set_tmp_dh(%p, %p): error", *ctx, dh); } } } } /* set pre ssl-connect options */ /* SSL_CIPHERS */ if (ci_str != NULL) { if (sycSSL_CTX_set_cipher_list(*ctx, ci_str) <= 0) { if (ERR_peek_error() == 0) Error1("SSL_set_cipher_list(, \"%s\") failed", ci_str); while (err = ERR_get_error()) { Error2("SSL_set_cipher_list(, \"%s\"): %s", ci_str, ERR_error_string(err, NULL)); } /*Error("SSL_new()");*/ return STAT_RETRYLATER; } } if (*opt_ver) { sycSSL_CTX_set_verify(*ctx, SSL_VERIFY_PEER| SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); } else { sycSSL_CTX_set_verify(*ctx, SSL_VERIFY_NONE, NULL); } return STAT_OK; } /* analyses an OpenSSL error condition, prints the appropriate messages with severity 'level' and returns one of STAT_OK, STAT_RETRYLATER, or STAT_NORETRY */ static int openssl_SSL_ERROR_SSL(int level, const char *funcname) { unsigned long e; char buf[120]; /* this value demanded by "man ERR_error_string" */ int stat = STAT_OK; while (e = ERR_get_error()) { Debug1("ERR_get_error(): %lx", e); if (e == ((ERR_LIB_RAND<<24)| (RAND_F_SSLEAY_RAND_BYTES<<12)| (RAND_R_PRNG_NOT_SEEDED)) /*0x24064064*/) { Error("too few entropy; use options \"egd\" or \"pseudo\""); stat = STAT_NORETRY; } else { Msg2(level, "%s(): %s", funcname, ERR_error_string(e, buf)); stat = level==E_ERROR ? STAT_NORETRY : STAT_RETRYLATER; } } return stat; } static const char *openssl_verify_messages[] = { /* 0 */ "ok", /* 1 */ NULL, /* 2 */ "unable to get issuer certificate", /* 3 */ "unable to get certificate CRL", /* 4 */ "unable to decrypt certificate's signature", /* 5 */ "unable to decrypt CRL's signature", /* 6 */ "unable to decode issuer public key", /* 7 */ "certificate signature failure", /* 8 */ "CRL signature failure", /* 9 */ "certificate is not yet valid", /* 10 */ "certificate has expired", /* 11 */ "CRL is not yet valid", /* 12 */ "CRL has expired", /* 13 */ "format error in certificate's notBefore field", /* 14 */ "format error in certificate's notAfter field", /* 15 */ "format error in CRL's lastUpdate field", /* 16 */ "format error in CRL's nextUpdate field", /* 17 */ "out of memory", /* 18 */ "self signed certificate", /* 19 */ "self signed certificate in certificate chain", /* 20 */ "unable to get local issuer certificate", /* 21 */ "unable to verify the first certificate", /* 22 */ "certificate chain too long", /* 23 */ "certificate revoked", /* 24 */ "invalid CA certificate", /* 25 */ "path length constraint exceeded", /* 26 */ "unsupported certificate purpose", /* 27 */ "certificate not trusted", /* 28 */ "certificate rejected", /* 29 */ "subject issuer mismatch", /* 30 */ "authority and subject key identifier mismatch", /* 31 */ "authority and issuer serial number mismatch", /* 32 */ "key usage does not include certificate signing", /* 33 */ NULL, /* 34 */ NULL, /* 35 */ NULL, /* 36 */ NULL, /* 37 */ NULL, /* 38 */ NULL, /* 39 */ NULL, /* 40 */ NULL, /* 41 */ NULL, /* 42 */ NULL, /* 43 */ NULL, /* 44 */ NULL, /* 45 */ NULL, /* 46 */ NULL, /* 47 */ NULL, /* 48 */ NULL, /* 49 */ NULL, /* 50 */ "application verification failure", } ; /* delete all environment variables whose name begins with SOCAT_OPENSSL_ resp. _OPENSSL_ */ static int openssl_delete_cert_info(void) { # define XIO_ENVNAMELEN 256 const char *progname; char envprefix[XIO_ENVNAMELEN]; char envname[XIO_ENVNAMELEN]; size_t i, l; const char **entry; progname = diag_get_string('p'); envprefix[0] = '\0'; strncat(envprefix, progname, XIO_ENVNAMELEN-1); l = strlen(envprefix); for (i = 0; i < l; ++i) envprefix[i] = toupper(envprefix[i]); strncat(envprefix+l, "_OPENSSL_", XIO_ENVNAMELEN-l-1); #if HAVE_VAR_ENVIRON entry = (const char **)environ; while (*entry != NULL) { if (!strncmp(*entry, envprefix, strlen(envprefix))) { const char *eq = strchr(*entry, '='); if (eq == NULL) eq = *entry + strlen(*entry); envname[0] = '\0'; strncat(envname, *entry, eq-*entry); Unsetenv(envname); } else { ++entry; } } #endif /* HAVE_VAR_ENVIRON */ return 0; } /* read in the "name" information (from field "issuer" or "subject") and create environment variable with complete info, eg: SOCAT_OPENSSL_X509_SUBJECT */ static int openssl_setenv_cert_name(const char *field, X509_NAME *name) { BIO *bio = BIO_new(BIO_s_mem()); char *buf = NULL, *str; size_t len; X509_NAME_print_ex(bio, name, 0, XN_FLAG_ONELINE&~ASN1_STRFLGS_ESC_MSB); /* rc not documented */ len = BIO_get_mem_data (bio, &buf); if ((str = Malloc(len+1)) == NULL) { BIO_free(bio); return -1; } memcpy(str, buf, len); str[len] = '\0'; Info2("SSL peer cert %s: \"%s\"", field, buf); xiosetenv2("OPENSSL_X509", field, str, 1, NULL); free(str); BIO_free(bio); return 0; } /* read in the "name" information (from field "issuer" or "subject") and create environment variables with the fields, eg: SOCAT_OPENSSL_X509_COMMONNAME */ static int openssl_setenv_cert_fields(const char *field, X509_NAME *name) { int n, i; n = X509_NAME_entry_count(name); /* extract fields of cert name */ for (i = 0; i < n; ++i) { X509_NAME_ENTRY *entry; ASN1_OBJECT *obj; ASN1_STRING *data; unsigned char *text; int nid; entry = X509_NAME_get_entry(name, i); obj = X509_NAME_ENTRY_get_object(entry); data = X509_NAME_ENTRY_get_data(entry); nid = OBJ_obj2nid(obj); text = ASN1_STRING_data(data); Debug3("SSL peer cert %s entry: %s=\"%s\"", (field[0]?field:"subject"), OBJ_nid2ln(nid), text); if (field != NULL && field[0] != '\0') { xiosetenv3("OPENSSL_X509", field, OBJ_nid2ln(nid), (const char *)text, 2, " // "); } else { xiosetenv2("OPENSSL_X509", OBJ_nid2ln(nid), (const char *)text, 2, " // "); } } return 0; } /* compares the peername used/provided by the client to cn as extracted from the peer certificate. supports wildcard cn like *.domain which matches domain and host.domain returns true on match */ static bool openssl_check_name(const char *cn, const char *peername) { const char *dotp; if (peername == NULL) { Info1("commonName \"%s\": no peername", cn); return false; } else if (peername[0] == '\0') { Info1("commonName \"%s\": matched by empty peername", cn); return true; } if (! (cn[0] == '*' && cn[1] == '.')) { /* normal server name - this is simple */ Debug1("commonName \"%s\" has no wildcard", cn); if (strcmp(cn, peername) == 0) { Debug2("commonName \"%s\" matches peername \"%s\"", cn, peername); return true; } else { Info2("commonName \"%s\" does not match peername \"%s\"", cn, peername); return false; } } /* wildcard cert */ Debug1("commonName \"%s\" is a wildcard name", cn); /* case: just the base domain */ if (strcmp(cn+2, peername) == 0) { Debug2("wildcard commonName \"%s\" matches base domain \"%s\"", cn, peername); return true; } /* case: subdomain; only one level! */ dotp = strchr(peername, '.'); if (dotp == NULL) { Info2("peername \"%s\" is not a subdomain, thus is not matched by wildcard commonName \"%s\"", peername, cn); return false; } if (strcmp(cn+1, dotp) != 0) { Info2("commonName \"%s\" does not match subdomain peername \"%s\"", cn, peername); return false; } Debug2("commonName \"%s\" matches subdomain peername \"%s\"", cn, peername); return true; } /* retrieves the commonName field and compares it to the peername returns true on match, false otherwise */ static bool openssl_check_peername(X509_NAME *name, const char *peername) { int ind = -1; X509_NAME_ENTRY *entry; ASN1_STRING *data; unsigned char *text; ind = X509_NAME_get_index_by_NID(name, NID_commonName, -1); if (ind < 0) { Info("no COMMONNAME field in peer certificate"); return false; } entry = X509_NAME_get_entry(name, ind); data = X509_NAME_ENTRY_get_data(entry); text = ASN1_STRING_data(data); return openssl_check_name((const char *)text, peername); } /* retrieves certificate provided by peer, sets env vars containing certificates field values, and checks peername if provided by calling function */ /* parts of this code were copied from Gene Spaffords C/C++ Secure Programming at Etutorials.org: http://etutorials.org/Programming/secure+programming/Chapter+10.+Public+Key+Infrastructure/10.8+Adding+Hostname+Checking+to+Certificate+Verification/ The code examples in this tutorial do not seem to have explicit license restrictions. */ static int openssl_handle_peer_certificate(struct single *xfd, const char *peername, bool opt_ver, int level) { X509 *peer_cert; X509_NAME *subjectname, *issuername; /*ASN1_TIME not_before, not_after;*/ int extcount, i, ok = 0; int status; if ((peer_cert = SSL_get_peer_certificate(xfd->para.openssl.ssl)) == NULL) { if (opt_ver) { Msg(level, "no peer certificate"); status = STAT_RETRYLATER; } else { Notice("no peer certificate and no check"); status = STAT_OK; } return status; } /* 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) { const char *message = NULL; if (verify_result >= 0 && (size_t)verify_result < sizeof(openssl_verify_messages)/sizeof(char*)) { message = openssl_verify_messages[verify_result]; } if (message) { Msg1(level, "%s", message); } else { Msg1(level, "rejected peer certificate with error %ld", verify_result); } status = STAT_RETRYLATER; X509_free(peer_cert); return STAT_RETRYLATER; } Info("peer certificate is trusted"); } /* set env vars from cert's subject and issuer values */ if ((subjectname = X509_get_subject_name(peer_cert)) != NULL) { openssl_setenv_cert_name("subject", subjectname); openssl_setenv_cert_fields("", subjectname); /*! I'd like to provide dates too; see http://markmail.org/message/yi4vspp7aeu3xwtu#query:+page:1+mid:jhnl4wklif3pgzqf+state:results */ } if ((issuername = X509_get_issuer_name(peer_cert)) != NULL) { openssl_setenv_cert_name("issuer", issuername); } /* check peername against cert's subjectAltName DNS entries */ /* this code is based on example from Gerhard Gappmeier in http://openssl.6102.n7.nabble.com/How-to-extract-subjectAltName-td17236.html */ if ((extcount = X509_get_ext_count(peer_cert)) > 0) { for (i = 0; !ok && i < extcount; ++i) { const char *extstr; X509_EXTENSION *ext; const X509V3_EXT_METHOD *meth; ext = X509_get_ext(peer_cert, i); extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); if (!strcasecmp(extstr, "subjectAltName")) { void *names; if (!(meth = X509V3_EXT_get(ext))) break; names = X509_get_ext_d2i(peer_cert, NID_subject_alt_name, NULL, NULL); if (names) { int numalts; int i; /* get amount of alternatives, RFC2459 claims there MUST be at least one, but we don't depend on it... */ numalts = sk_GENERAL_NAME_num ( names ); /* loop through all alternatives */ for ( i=0; ( itype ) { case GEN_DNS: ASN1_STRING_to_UTF8(&pBuffer, pName->d.ia5); xiosetenv("OPENSSL_X509V3_SUBJECTALTNAME_DNS", (char *)pBuffer, 2, " // "); if (peername != NULL && openssl_check_name((char *)pBuffer, /*const char*/peername)) { ok = 1; } OPENSSL_free(pBuffer); break; default: continue; } } } } } } if (!opt_ver) { Notice("option openssl-verify disabled, no check of certificate"); X509_free(peer_cert); return STAT_OK; } if (peername == NULL || peername[0] == '\0') { Notice("trusting certificate, no check of commonName"); X509_free(peer_cert); return STAT_OK; } if (ok) { Notice("trusting certificate, commonName matches"); X509_free(peer_cert); return STAT_OK; } /* here: all envs set; opt_ver, cert verified, no subjAltName match -> check subject CN */ if (!openssl_check_peername(/*X509_NAME*/subjectname, /*const char*/peername)) { Error("certificate is valid but its commonName does not match hostname"); status = STAT_NORETRY; } else { Notice("trusting certificate, commonName matches"); status = STAT_OK; } X509_free(peer_cert); return status; } static int xioSSL_set_fd(struct single *xfd, int level) { unsigned long err; /* assign a network connection to the SSL object */ if (sycSSL_set_fd(xfd->para.openssl.ssl, xfd->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)); } return STAT_RETRYLATER; } return STAT_OK; } /* ... 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, 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 (ERR_peek_error() == 0) Msg(level, "SSL_connect() failed");*/ errint = SSL_get_error(xfd->para.openssl.ssl, ret); switch (errint) { case SSL_ERROR_NONE: /* this is not an error, but I dare not continue for security reasons*/ Msg(level, "ok"); status = STAT_RETRYLATER; case SSL_ERROR_ZERO_RETURN: Msg(level, "connection closed (wrong version number?)"); status = STAT_RETRYLATER; break; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_CONNECT: case SSL_ERROR_WANT_X509_LOOKUP: Msg(level, "nonblocking operation did not complete"); status = STAT_RETRYLATER; break; /*!*/ case SSL_ERROR_SYSCALL: if (ERR_peek_error() == 0) { if (ret == 0) { Msg(level, "SSL_connect(): socket closed by peer"); } else if (ret == -1) { Msg1(level, "SSL_connect(): %s", strerror(errno)); } } else { Msg(level, "I/O error"); /*!*/ while (err = ERR_get_error()) { ERR_error_string_n(err, error_string, sizeof(error_string)); Msg4(level, "SSL_connect(): %s / %s / %s / %s", error_string, ERR_lib_error_string(err), ERR_func_error_string(err), ERR_reason_error_string(err)); } } status = STAT_RETRYLATER; 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) { return STAT_RETRYLATER; } break; default: Msg(level, "unknown error"); status = STAT_RETRYLATER; break; } return status; } return STAT_OK; } /* on result < 0: errno is set (at least to EIO) */ ssize_t xioread_openssl(struct single *pipe, void *buff, size_t bufsiz) { unsigned long err; char error_string[120]; int _errno = EIO; /* if we have no better idea about nature of error */ int errint, ret; ret = sycSSL_read(pipe->para.openssl.ssl, buff, bufsiz); if (ret < 0) { errint = SSL_get_error(pipe->para.openssl.ssl, ret); switch (errint) { case SSL_ERROR_NONE: /* this is not an error, but I dare not continue for security reasons*/ Error("ok"); break; case SSL_ERROR_ZERO_RETURN: Error("connection closed by peer"); break; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_CONNECT: case SSL_ERROR_WANT_X509_LOOKUP: Info("nonblocking operation did not complete"); errno = EAGAIN; return -1; case SSL_ERROR_SYSCALL: if (ERR_peek_error() == 0) { if (ret == 0) { Error("SSL_read(): socket closed by peer"); } else if (ret == -1) { _errno = errno; Error1("SSL_read(): %s", strerror(errno)); } } else { Error("I/O error"); /*!*/ while (err = ERR_get_error()) { ERR_error_string_n(err, error_string, sizeof(error_string)); Error4("SSL_read(): %s / %s / %s / %s", error_string, ERR_lib_error_string(err), ERR_func_error_string(err), ERR_reason_error_string(err)); } } break; case SSL_ERROR_SSL: openssl_SSL_ERROR_SSL(E_ERROR, "SSL_connect"); break; default: Error("unknown error"); break; } errno = _errno; return -1; } return ret; } ssize_t xiopending_openssl(struct single *pipe) { int bytes = sycSSL_pending(pipe->para.openssl.ssl); return bytes; } /* on result < 0: errno is set (at least to EIO) */ ssize_t xiowrite_openssl(struct single *pipe, const void *buff, size_t bufsiz) { unsigned long err; char error_string[120]; int _errno = EIO; /* if we have no better idea about nature of error */ int errint, ret; ret = sycSSL_write(pipe->para.openssl.ssl, buff, bufsiz); if (ret < 0) { errint = SSL_get_error(pipe->para.openssl.ssl, ret); switch (errint) { case SSL_ERROR_NONE: /* this is not an error, but I dare not continue for security reasons*/ Error("ok"); case SSL_ERROR_ZERO_RETURN: Error("connection closed by peer"); break; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_CONNECT: case SSL_ERROR_WANT_X509_LOOKUP: Error("nonblocking operation did not complete"); break; /*!*/ case SSL_ERROR_SYSCALL: if (ERR_peek_error() == 0) { if (ret == 0) { Error("SSL_write(): socket closed by peer"); } else if (ret == -1) { _errno = errno; Error1("SSL_write(): %s", strerror(errno)); } } else { Error("I/O error"); /*!*/ while (err = ERR_get_error()) { ERR_error_string_n(err, error_string, sizeof(error_string)); Error4("SSL_write(): %s / %s / %s / %s", error_string, ERR_lib_error_string(err), ERR_func_error_string(err), ERR_reason_error_string(err)); } } break; case SSL_ERROR_SSL: openssl_SSL_ERROR_SSL(E_ERROR, "SSL_connect"); break; default: Error("unknown error"); break; } errno = _errno; return -1; } return ret; } #endif /* WITH_OPENSSL */ socat-1.7.3.1/xiodiag.c0000644000201000020100000000117311453022152014345 0ustar gerhardgerhard/* source: xiodiag.c */ /* Copyright Gerhard Rieger 2001, 2003 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains source for some diagnostics */ #include "xiosysincludes.h" #include "xioopen.h" #include "xiodiag.h" const char *ddirection[] = { "reading", "writing", "reading and writing" } ; /* compliant with S_ macros (sys/stat.h) */ const char *filetypenames[] = { "undef", "named pipe", "character device", "undef", "block device", "undef", "directory", "undef", "regular file", "undef", "symbolic link", "undef", "local socket", "undef", "undef", "\"MT\"?"} ; socat-1.7.3.1/CHANGES0000644000201000020100000014025412652637420013570 0ustar gerhardgerhard ####################### V 1.7.3.1: security: Socat security advisory 8 A stack overflow in vulnerability was found that can be triggered when command line arguments (complete address specifications, host names, file names) are longer than 512 bytes. Successful exploitation might allow an attacker to execute arbitrary code with the privileges of the socat process. This vulnerability can only be exploited when an attacker is able to inject data into socat's command line. A vulnerable scenario would be a CGI script that reads data from clients and uses (parts of) this data as hostname for a Socat invocation. Test: NESTEDOVFL Credits to Takumi Akiyama for finding and reporting this issue. Socat security advisory 7 MSVR-1499 In the OpenSSL address implementation the hard coded 1024 bit DH p parameter was not prime. The effective cryptographic strength of a key exchange using these parameters was weaker than the one one could get by using a prime p. Moreover, since there is no indication of how these parameters were chosen, the existence of a trapdoor that makes possible for an eavesdropper to recover the shared secret from a key exchange that uses them cannot be ruled out. Futhermore, 1024bit is not considered sufficiently secure. Fix: generated a new 2048bit prime. Thanks to Santiago Zanella-Beguelin and Microsoft Vulnerability Research (MSVR) for finding and reporting this issue. ####################### V 1.7.3.0: security: Socat security advisory 6 CVE-2015-1379: Possible DoS with fork Fixed problems with signal handling caused by use of not async signal safe functions in signal handlers that could freeze socat, allowing denial of service attacks. Many changes in signal handling and the diagnostic messages system were applied to make the code async signal safe but still provide detailled logging from signal handlers: Coded function vsnprintf_r() as async signal safe incomplete substitute of libc vsnprintf() Coded function snprinterr() to replace %m in strings with a system error message Instead of gettimeofday() use clock_gettime() when available Pass Diagnostic messages from signal handler per unix socket to the main program flow Use sigaction() instead of signal() for better control Turn off nested signal handler invocations Thanks to Peter Lobsinger for reporting and explaining this issue. Red Hat issue 1019975: add TLS host name checks OpenSSL client checks if the server certificates names in extensions/subjectAltName/DNS or in subject/commonName match the name used to connect or the value of the openssl-commonname option. Test: OPENSSL_CN_CLIENT_SECURITY OpenSSL server checks if the client certificates names in extensions/subjectAltNames/DNS or subject/commonName match the value of the openssl-commonname option when it is used. Test: OPENSSL_CN_SERVER_SECURITY Red Hat issue 1019964: socat now uses the system certificate store with OPENSSL when neither options cafile nor capath are used Red Hat issue 1019972: needs to specify OpenSSL cipher suites Default cipherlist is now "HIGH:-NULL:-PSK:-aNULL" instead of empty to prevent downgrade attacks new features: OpenSSL addresses set couple of environment variables from values in peer certificate, e.g.: SOCAT_OPENSSL_X509_SUBJECT, SOCAT_OPENSSL_X509_ISSUER, SOCAT_OPENSSL_X509_COMMONNAME, SOCAT_OPENSSL_X509V3_SUBJECTALTNAME_DNS Tests: ENV_OPENSSL_{CLIENT,SERVER}_X509_* Added support for methods TLSv1, TLSv1.1, TLSv1.2, and DTLS1 Tests: OPENSSL_METHOD_* Enabled OpenSSL server side use of ECDHE ciphers. Feature suggested by Andrey Arapov. Added a new option termios-rawer for ptys. Thanks to Christian Vogelgsang for pointing me to this requirement corrections: Bind with ABSTRACT commands used non-abstract namespace (Linux). Test: ABSTRACT_BIND Thanks to Denis Shatov for reporting this bug. Fixed return value of nestlex() Option ignoreeof on the right address hung. Test: IGNOREEOF_REV Thanks to Franz Fasching for reporting this bug. Address SYSTEM, when terminating, shut down its parent addresses, e.g. an SSL connection which the parent assumed to still be active. Test: SYSTEM_SHUTDOWN Passive (listening or receiving) addresses with empty port field bound to a random port instead of terminating with error. Test: TCP4_NOPORT configure with some combination of disable options produced config files that failed to compile due to missing IPPROTO_TCP. Thanks to Thierry Fournier for report and patch. fixed a few minor bugs with OpenSSL in configure and with messages Socat did not work in FIPS mode because 1024 instead of 512 bit DH prime is required. Thanks to Zhigang Wang for reporting and sending a patch. Christophe Leroy provided a patch that fixes memory leaks reported by valgrind Help for filan -L was bad, is now corrected to: "follow symbolic links instead of showing their properties" Address options fdin and fdout were silently ignored when not applicable due to -u or -U option. Now these combinations are caught as errors. Test: FDOUT_ERROR Issue reported by Hendrik. Added option termios-cfmakeraw that calls cfmakeraw() and is preferred over option raw which is now obsolote. On SysV systems this call is simulated by appropriate setting. Thanks to Youfu Zhang for reporting issue with option raw. porting: Socat included instead of POSIX Thanks to John Spencer for reporting this issue. Version 1.7.2.4 changed the check for gcc in configure.ac; this broke cross compiling. The particular check gets reverted. Thanks to Ross Burton and Danomi Manchego for reporting this issue. Debian Bug#764251: Set the build timestamp to a deterministic time: support external BUILD_DATE env var to allow to build reproducable binaries Joachim Fenkes provided an new adapted spec file. Type bool and macros Min and Max are defined by socat which led to compile errors when they were already provided by build framework. Thanks to Liyu Liu for providing a patch. David Arnstein contributed a patch for NetBSD 5.1 including stdbool.h support and appropriate files in Config/ Lauri Tirkkonen contributed a patch regarding netinet/if_ether.h on Illumos Changes for Openindiana: define _XPG4_2, __EXTENSIONS__, _POSIX_PTHREAD_SEMANTICS; and minor changes Red Hat issue 1182005: socat 1.7.2.4 build failure missing linux/errqueue.h Socat failed to compile on on PPC due to new requirements for including and a weakness in the conditional code. Thanks to Michel Normand for reporting this issue. doc: In the man page the PTY example was badly formatted. Thanks to J.F.Sebastian for sending a patch. Added missing CVE ids to security issues in CHANGES testing: Do not distribute testcert.conf with socat source but generate it (and new testcert6.conf) during test.sh run. ####################### V 1.7.2.4: corrections: LISTEN based addresses applied some address options, e.g. so-keepalive, to the listening file descriptor instead of the connected file descriptor Thanks to Ulises Alonso for reporting this bug make failed after configure with non gcc compiler due to missing include. Thanks to Horacio Mijail for reporting this problem configure checked for --disable-rawsocket but printed --disable-genericsocket in the help text. Thanks to Ben Gardiner for reporting and patching this bug In xioshutdown() a wrong branch was chosen after RECVFROM type addresses. Probably no impact. Thanks to David Binderman for reproting this issue. procan could not cleanly format ulimit values longer than 16 decimal digits. Thanks to Frank Dana for providing a patch that increases field width to 24 digits. OPENSSL-CONNECT with bind option failed on some systems, eg.FreeBSD, with "Invalid argument" Thanks to Emile den Tex for reporting this bug. Changed some variable definitions to make gcc -O2 aliasing checker happy Thanks to Ilya Gordeev for reporting these warnings On big endian platforms with type long >32bit the range option applied a bad base address. Thanks to hejia hejia for reporting and fixing this bug. Red Hat issue 1022070: missing length check in xiolog_ancillary_socket() Red Hat issue 1022063: out-of-range shifts on net mask bits Red Hat issue 1022062: strcpy misuse in xiosetsockaddrenv_ip4() Red Hat issue 1022048: strncpy hardening: corrected suspicious strncpy() uses Red Hat issue 1021958: fixed a bug with faulty buffer/data length calculation in xio-ascii.c:_xiodump() Red Hat issue 1021972: fixed a missing NUL termination in return string of sysutils.c:sockaddr_info() for the AF_UNIX case fixed some typos and minor issues, including: Red Hat issue 1021967: formatting error in manual page UNIX-LISTEN with fork option did not remove the socket file system entry when exiting. Other file system based passive address types had similar issues or failed to apply options umask, user e.a. Thanks to Lorenzo Monti for pointing me to this issue porting: Red Hat issue 1020203: configure checks fail with some compilers. Use case: clang Performed changes for Fedora release 19 Adapted, improved test.sh script Red Hat issue 1021429: getgroupent fails with large number of groups; use getgrouplist() when available instead of sequence of calls to getgrent() Red Hat issue 1021948: snprintf API change; Implemented xio_snprintf() function as wrapper that tries to emulate C99 behaviour on old glibc systems, and adapted all affected calls appropriately Mike Frysinger provided a patch that supports long long for time_t, socklen_t and a few other libc types. Artem Mygaiev extended Cedril Priscals Android build script with pty code The check for fips.h required stddef.h Thanks to Matt Hilt for reporting this issue and sending a patch Check for linux/errqueue.h failed on some systems due to lack of linux/types.h inclusion. Thanks to Michael Vastola for sending a patch. autoconf now prefers configure.ac over configure.in Thanks to Michael Vastola for sending a patch. type of struct cmsghdr.cmsg is system dependend, determine it with configure; some more print format corrections docu: libwrap always logs to syslog added actual text version of GPLv2 ####################### V 1.7.2.3: security: Socat security advisory 5 CVE-2014-0019: socats PROXY-CONNECT address was vulnerable to a buffer overflow with data from command line (see socat-secadv5.txt) Credits to Florian Weimer of the Red Hat Product Security Team ####################### V 1.7.2.2: security: Socat security advisory 4 CVE-2013-3571: after refusing a client connection due to bad source address or source port socat shutdown() the socket but did not close() it, resulting in a file descriptor leak in the listening process, visible with lsof and possibly resulting in EMFILE Too many open files. This issue could be misused for a denial of service attack. Full credits to Catalin Mitrofan for finding and reporting this issue. ####################### V 1.7.2.1: security: Socat security advisory 3 CVE-2012-0219: fixed a possible heap buffer overflow in the readline address. This bug could be exploited when all of the following conditions were met: 1) one of the addresses is READLINE without the noprompt and without the prompt options. 2) the other (almost arbitrary address) reads malicious data (which is then transferred by socat to READLINE). Workaround: when using the READLINE address apply option prompt or noprompt. Full credits to Johan Thillemann for finding and reporting this issue. ####################### V 1.7.2.0: corrections: when UNIX-LISTEN was applied to an existing file it failed as expected but removed the file. Thanks to Bjoern Bosselmann for reporting this problem fixed a bug where socat might crash when connecting to a unix domain socket using address GOPEN. Thanks to Martin Forssen for bug report and patch. UDP-LISTEN would alway set SO_REUSEADDR even without fork option and when user set it to 0. Thanks to Michal Svoboda for reporting this bug. UNIX-CONNECT did not support half-close. Thanks to Greg Hughes who pointed me to that bug TCP-CONNECT with option nonblock reported successful connect even when it was still pending address option ioctl-intp failed with "unimplemented type 26". Thanks to Jeremy W. Sherman for reporting and fixing that bug socat option -x did not print packet direction, timestamp etc; thanks to Anthony Sharobaiko for sending a patch address PTY does not take any parameters but did not report an error when some were given Marcus Meissner provided a patch that fixes invalid output and possible process crash when socat prints info about an unnamed unix domain socket Michal Soltys reported the following problem and provided an initial patch: when socat was interrupted, e.g. by SIGSTOP, and resumed during data transfer only parts of the data might have been written. Option o-nonblock in combination with large transfer block sizes may result in partial writes and/or EAGAIN errors that were not handled properly but resulted in data loss or process termination. Fixed a bug that could freeze socat when during assembly of a log message a signal was handled that also printed a log message. socat development had been aware that localtime() is not thread safe but had only expected broken messages, not corrupted stack (glibc 2.11.1, Ubuntu 10.4) an internal store for child pids was susceptible to pid reuse which could lead to sporadic data loss when both fork option and exec address were used. Thanks to Tetsuya Sodo for reporting this problem and sending a patch OpenSSL server failed with "no shared cipher" when using cipher aNULL. Fixed by providing temporary DH parameters. Thanks to Philip Rowlands for drawing my attention to this issue. UDP-LISTEN slept 1s after accepting a connection. This is not required. Thanks to Peter Valdemar Morch for reporting this issue fixed a bug that could lead to error or socat crash after a client connection with option retry had been established fixed configure.in bug on net/if.h check that caused IF_NAMESIZE to be undefined improved dev_t print format definition porting: Cedril Priscal ported socat to Android (using Googles cross compiler). The port includes the socat_buildscript_for_android.sh script added check for component ipi_spec_dst in struct in_pktinfo so compilation does not fail on Cygwin (thanks to Peter Wagemans for reporting this problem) build failed on RHEL6 due to presence of fips.h; configure now checks for fipsld too. Thanks to Andreas Gruenbacher for reporting this problem check for netinet6/in6.h only when IPv6 is available and enabled don't fail to compile when the following defines are missing: IPV6_PKTINFO IPV6_RTHDR IPV6_DSTOPTS IPV6_HOPOPTS IPV6_HOPLIMIT Thanks to Jerry Jacobs for reporting this problem (Mac OS X Lion 10.7) check if define __APPLE_USE_RFC_2292 helps to enable IPV6_* (MacOSX Lion 7.1); thanks to Jerry Jacobs to reporting this problem and proposing a solution fixed compiler warnings on Mac OS X 64bit. Thanks to Guy Harris for providing the patch. corrections for OpenEmbedded, especially termios SHIFT values and ISPEED/OSPEED. Thanks to John Faith for providing the patch minor corrections to docu and test.sh resulting from local compilation on Openmoko SHR fixed sa_family_t compile error on DragonFly. Thanks to Tony Young for reporting this issue and sending a patch. Ubuntu Oneiric: OpenSSL no longer provides SSLv2 functions; libutil.sh is now bsd/libutil.h; compiler warns on vars that is only written to new features: added option max-children that limits the number of concurrent child processes. Thanks to Sam Liddicott for providing the patch. Till Maas added support for tun/tap addresses without IP address added an option openssl-compress that allows to disable the compression feature of newer OpenSSL versions. Thanks to Michael Hanselmann for providing this contribution (sponsored by Google Inc.) docu: minor corrections in docu (thanks to Paggas) client process -> child process ####################### V 1.7.1.3: security: Socat security advisory 2 CVE-2010-2799: fixed a stack overflow vulnerability that occurred when command line arguments (whole addresses, host names, file names) were longer than 512 bytes. Note that this could only be exploited when an attacker was able to inject data into socat's command line. Full credits to Felix Gröbert, Google Security Team, for finding and reporting this issue ####################### V 1.7.1.2: corrections: user-late and group-late, when applied to a pty, affected the system device /dev/ptmx instead of the pty (thanks to Matthew Cloke for pointing me to this bug) socats openssl addresses failed with "nonblocking operation did not complete" when the peer performed a renegotiation. Thanks to Benjamin Delpy for reporting this bug. info message during socks connect showed bad port number on little endian systems due to wrong byte order (thanks to Peter M. Galbavy for bug report and patch) Debian bug 531078: socat execs children with SIGCHLD ignored; corrected to default. Thanks to Martin Dorey for reporting this bug. porting: building socat on systems that predefined the CFLAGS environment to contain -Wall failed (esp.RedHat). Thanks to Paul Wouters for reporting this problem and to Simon Matter for providing the patch support for Solaris 8 and Sun Studio support (thanks to Sebastian Kayser for providing the patches) on some 64bit systems a compiler warning "cast from pointer to integer of different size" was issued on some option definitions added struct sockaddr_ll to union sockaddr_union to avoid "strict aliasing" warnings (problem reported by Paul Wouters) docu: minor corrections in docu ####################### V 1.7.1.1: corrections: corrected the "fixed possible SIGSEGV" fix because SIGSEGV still might occur under those conditions. Thanks to Toni Mattila for first reporting this problem. ftruncate64 cut its argument to 32 bits on systems with 32 bit long type socat crashed on systems without setenv() (esp. SunOS up to Solaris 9); thanks to Todd Stansell for reporting this bug with unidirectional EXEC and SYSTEM a close() operation was performed on a random number which could result in hanging e.a. fixed a compile problem caused by size_t/socklen_t mismatch on 64bit systems docu mentioned option so-bindtodev but correct name is so-bindtodevice. Thanks to Jim Zimmerman for reporting. docu changes: added environment variables example to doc/socat-multicast.html ####################### V 1.7.1.0: new features: address options shut-none, shut-down, and shut-close allow to control socat's half close behaviour with address option shut-null socat sends an empty packet to the peer to indicate EOF option null-eof changes the behaviour of sockets that receive an empty packet to see EOF instead of ignoring it introduced option names substuser-early and su-e, currently equivalent to option substuser (thanks to Mike Perry for providing the patch) corrections: fixed some typos and improved some comments ####################### V 1.7.0.1: corrections: fixed possible SIGSEGV in listening addresses when a new connection was reset by peer before the socket addresses could be retrieved. Thanks to Mike Perry for sending a patch. fixed a bug, introduced with version 1.7.0.0, that let client connections with option connect-timeout fail when the connections succeeded. Thanks to Bruno De Fraine for reporting this bug. option end-close "did not apply" to addresses PTY, SOCKET-CONNECT, and most UNIX-* and ABSTRACT-* half close of EXEC and SYSTEM addresses did not work for pipes and sometimes socketpair help displayed for some option a wrong type under some circumstances shutdown was called multiple times for the same fd ####################### V 1.7.0.0: new features: new address types SCTP-CONNECT and SCTP-LISTEN implement SCTP stream mode for IPv4 and IPv6; new address options sctp-maxseg and sctp-nodelay (suggested by David A. Madore; thanks to Jonathan Brannan for providing an initial patch) new address "INTERFACE" for transparent network interface handling (suggested by Stuart Nicholson) added generic socket addresses: SOCKET-CONNECT, SOCKET-LISTEN, SOCKET-SENDTO, SOCKET-RECVFROM, SOCKET-RECV, SOCKET-DATAGRAM allow protocol independent socket handling; all parameters are explicitely specified as numbers or hex data added address options ioctl-void, ioctl-int, ioctl-intp, ioctl-string, ioctl-bin for generic ioctl() calls. added address options setsockopt-int, setsockopt-bin, and setsockopt-string for generic setsockopt() calls option so-type now only affects the socket() and socketpair() calls, not the name resolution. so-type and so-prototype can now be applied to all socket based addresses. new address option "escape" allows to break a socat instance even when raw terminal mode prevents ^C etc. (feature suggested by Guido Trotter) socat sets environment variables SOCAT_VERSION, SOCAT_PID, SOCAT_PPID for use in executed scripts socat sets environment variables SOCAT_SOCKADDR, SOCAT_SOCKPORT, SOCAT_PEERADDR, SOCAT_PEERPORT in LISTEN type addresses (feature suggested by Ed Sawicki) socat receives all ancillary messages with each received packet on datagram related addresses. The messages are logged in raw form with debug level, and broken down with info level. note: each type of ancillary message must be enabled by appropriate address options. socat provides the contents of ancillary messages received on RECVFROM addresses in appropriate environment variables: SOCAT_TIMESTAMP, SOCAT_IP_DSTADDR, SOCAT_IP_IF, SOCAT_IP_LOCADDR, SOCAT_IP_OPTIONS, SOCAT_IP_TOS, SOCAT_IP_TTL, SOCAT_IPV6_DSTADDR, SOCAT_IPV6_HOPLIMIT, SOCAT_IPV6_TCLASS the following address options were added to enable ancillary messages: so-timestamp, ip-pktinfo (not BSD), ip-recvdstaddr (BSD), ip-recverr, ip-recvif (BSD), ip-recvopts, ip-recvtos, ip-recvttl, ipv6-recvdstopts, ipv6-recverr, ipv6-recvhoplimit, ipv6-recvhopopts, ipv6-recvpathmtu, ipv6-recvpktinfo, ipv6-recvrthdr, ipv6-recvtclass new address options ipv6-tclass and ipv6-unicast-hops set the related socket options. STREAMS (UNIX System V STREAMS) can be configured with the new address options i-pop-all and i-push (thanks to Michal Rysavy for providing a patch) corrections: some raw IP and UNIX datagram modes failed on BSD systems when UDP-LISTEN continued to listen after packet dropped by, e.g., range option, the old listen socket would not be closed but a new one created. open sockets could accumulate. there was a bug in ip*-recv with bind option: it did not bind, and with the first received packet an error occurred: socket_init(): unknown address family 0 test: RAWIP4RECVBIND RECVFROM addresses with FORK option hung after processing the first packet. test: UDP4RECVFROM_FORK corrected a few mistakes that caused compiler warnings on 64bit hosts (thanks to Jonathan Brannan e.a. for providing a patch) EXEC and SYSTEM with stderr injected socat messages into the data stream. test: EXECSTDERRLOG when the EXEC address got a string with consecutive spaces it created additional empty arguments (thanks to Olivier Hervieu for reporting this bug). test: EXECSPACES in ignoreeof polling mode socat also blocked data transfer in the other direction during the 1s wait intervalls (thanks to Jorgen Cederlof for reporting this bug) corrected alphabetical order of options (proxy-auth) some minor corrections improved test.sh script: more stable timing, corrections for BSD replaced the select() calls by poll() to cleanly fix the problems with many file descriptors already open socat option -lf did not log to file but to stderr socat did not compile on Solaris when configured without termios feature (thanks to Pavan Gadi for reporting this bug) porting: socat compiles and runs on AIX with gcc (thanks to Andi Mather for his help) socat compiles and runs on Cygwin (thanks to Jan Just Keijser for his help) socat compiles and runs on HP-UX with gcc (thanks to Michal Rysavy for his help) socat compiles and runs on MacOS X (thanks to Camillo Lugaresi for his help) further changes: filan -s prefixes output with FD number if more than one FD Makefile now supports datarootdir (thanks to Camillo Lugaresi for providing the patch) cleanup in xio-unix.c ####################### V 1.6.0.1: new features: new make target "gitclean" docu source doc/socat.yo released corrections: exec:...,pty did not kill child process under some circumstances; fixed by correcting typo in xio-progcall.c (thanks to Ralph Forsythe for reporting this problem) service name resolution failed due to byte order mistake (thanks to James Sainsbury for reporting this problem) socat would hang when invoked with many file descriptors already opened fix: replaced FOPEN_MAX with FD_SETSIZE thanks to Daniel Lucq for reporting this problem. fixed bugs where sub processes would become zombies because the master process did not catch SIGCHLD. this affected addresses UDP-LISTEN, UDP-CONNECT, TCP-CONNECT, OPENSSL, PROXY, UNIX-CONNECT, UNIX-CLIENT, ABSTRACT-CONNECT, ABSTRACT-CLIENT, SOCKSA, SOCKS4A (thanks to Fernanda G Weiden for reporting this problem) fixed a bug where sub processes would become zombies because the master process caught SIGCHLD but did not wait(). this affected addresses UDP-RECVFROM, IP-RECVFROM, UNIX-RECVFROM, ABSTRACT-RECVFROM (thanks to Evan Borgstrom for reporting this problem) corrected option handling with STDIO; usecase: cool-write configure --disable-pty also disabled option waitlock fixed small bugs on systems with struct ip_mreq without struct ip_mreqn (thanks to Roland Illig for sending a patch) corrected name of option intervall to interval (old form still valid for us German speaking guys) corrected some print statements and variable names make uninstall did not uninstall procan fixed lots of weaknesses in test.sh corrected some bugs and typos in doc/socat.yo, EXAMPLES, C comments further changes: procan -c prints C defines important for socat added test OPENSSLEOF for OpenSSL half close ####################### V 1.6.0.0: new features: new addresses IP-DATAGRAM and UDP-DATAGRAM allow versatile broadcast and multicast modes new option ip-add-membership for control of multicast group membership new address TUN for generation of Linux TUN/TAP pseudo network interfaces (suggested by Mat Caughron); associated options tun-device, tun-name, tun-type; iff-up, iff-promisc, iff-noarp, iff-no-pi etc. new addresses ABSTRACT-CONNECT, ABSTRACT-LISTEN, ABSTRACT-SENDTO, ABSTRACT-RECV, and ABSTRACT-RECVFROM for abstract UNIX domain addresses on Linux (requested by Zeeshan Ali); option unix-tightsocklen controls socklen parameter on system calls. option end-close for control of connection closing allows FD sharing by sub processes range option supports form address:mask with IPv4 changed behaviour of SSL-LISTEN to require and verify client certificate per default options f-setlkw-rd, f-setlkw-wr, f-setlk-rd, f-setlk-wr allow finer grained locking on regular files uninstall target in Makefile (lack reported by Zeeshan Ali) corrections: fixed bug where only first tcpwrap option was applied; fixed bug where tcpwrap IPv6 check always failed (thanks to Rudolf Cejka for reporting and fixing this bug) filan (and socat -D) could hang when a socket was involved corrected PTYs on HP-UX (and maybe others) using STREAMS (inspired by Roberto Mackun) correct bind with udp6-listen (thanks to Jan Horak for reporting this bug) corrected filan.c peekbuff[0] which did not compile with Sun Studio Pro (thanks to Leo Zhadanovsky for reporting this problem) corrected problem with read data buffered in OpenSSL layer (thanks to Jon Nelson for reporting this bug) corrected problem with option readbytes when input stream stayed idle after so many bytes fixed a bug where a datagram receiver with option fork could fork two sub processes per packet further changes: moved documentation to new doc/ subdir new documents (kind of mini tutorials) are provided in doc/ ####################### V 1.5.0.0: new features: new datagram modes for udp, rawip, unix domain sockets socat option -T specifies inactivity timeout rewrote lexical analysis to allow nested socat calls addresses tcp, udp, tcp-l, udp-l, and rawip now support IPv4 and IPv6 socat options -4, -6 and environment variables SOCAT_DEFAULT_LISTEN_IP, SOCAT_PREFERRED_RESOLVE_IP for control of protocol selection addresses ssl, ssl-l, socks, proxy now support IPv4 and IPv6 option protocol-family (pf), esp. for openssl-listen range option supports IPv6 - syntax: range=[::1/128] option ipv6-v6only (ipv6only) new tcp-wrappers options allow-table, deny-table, tcpwrap-etc FIPS version of OpenSSL can be integrated - initial patch provided by David Acker. See README.FIPS support for resolver options res-debug, aaonly, usevc, primary, igntc, recurse, defnames, stayopen, dnsrch options for file attributes on advanced filesystems (ext2, ext3, reiser): secrm, unrm, compr, ext2-sync, immutable, ext2-append, nodump, ext2-noatime, journal-data etc. option cool-write controls severeness of write failure (EPIPE, ECONNRESET) option o-noatime socat option -lh for hostname in log output traffic dumping provides packet headers configure.in became part of distribution socats unpack directory now has full version, e.g. socat-1.5.0.0/ corrected docu of option verify corrections: fixed tcpwrappers integration - initial fix provided by Rudolf Cejka exec with pipes,stderr produced error setuid-early was ignored with many address types some minor corrections ####################### V 1.4.3.1: corrections: PROBLEM: UNIX socket listen accepted only one (or a few) connections. FIX: do not remove listening UNIX socket in child process PROBLEM: SIGSEGV when TCP part of SSL connect failed FIX: check ssl pointer before calling SSL_shutdown In debug mode, show connect client port even when connect fails ####################### V 1.4.3.0: new features: socat options -L, -W for application level locking options "lockfile", "waitlock" for address level locking (Stefan Luethje) option "readbytes" limits read length (Adam Osuchowski) option "retry" for unix-connect, unix-listen, tcp6-listen (Dale Dude) pty symlink, unix listen socket, and named pipe are per default removed after use; option unlink-close overrides this new behaviour and also controls removal of other socat generated files (Stefan Luethje) corrections: option "retry" did not work with tcp-listen EPIPE condition could result in a 100% CPU loop further changes: support systems without SHUT_RD etc. handle more size_t types try to find makedepend options with gcc 3 (richard/OpenMacNews) ####################### V 1.4.2.0: new features: option "connect-timeout" limits wait time for connect operations (requested by Giulio Orsero) option "dhparam" for explicit Diffie-Hellman parameter file corrections: support for OpenSSL DSA certificates (Miika Komu) create install directories before copying files (Miika Komu) when exiting on signal, return status 128+signum instead of 1 on EPIPE and ECONNRESET, only issue a warning (Santiago Garcia Mantinan) -lu could cause a core dump on long messages further changes: modifications to simplify using socats features in applications ####################### V 1.4.1.0: new features: option "wait-slave" blocks open of pty master side until a client connects, "pty-intervall" controls polling option -h as synonym to -? for help (contributed by Christian Lademann) filan prints formatted time stamps and rdev (disable with -r) redirect filan's output, so stdout is not affected (contributed by Luigi Iotti) filan option -L to follow symbolic links filan shows termios control characters corrections: proxy address no longer performs unsolicited retries filan -f no longer needs read permission to analyze a file (but still needs access permission to directory, of course) porting: Option dsusp FreeBSD options noopt, nopush, md5sig OpenBSD options sack-disable, signature-enable HP-UX, Solaris options abort-threshold, conn-abort-threshold HP-UX options b900, b3600, b7200 Tru64/OSF1 options keepinit, paws, sackena, tsoptena further corrections: address pty now uses ptmx as default if openpty is also available ####################### V 1.4.0.3: security: Socat security advisory 1 CVE-2004-1484: fix to a syslog() based format string vulnerability that can lead to remote code execution. See advisory socat-adv-1.txt ####################### V 1.4.0.2: corrections: exec'd write-only addresses get a chance to flush before being killed error handler: print notice on error-exit filan printed wrong file type information ####################### V 1.4.0.1: corrections: socks4a constructed invalid header. Problem found, reported, and fixed by Thomas Themel, by Peter Palfrader, and by rik with nofork, don't forget to apply some process related options (chroot, setsid, setpgid, ...) ####################### V 1.4.0.0: new features: simple openssl server (ssl-l), experimental openssl trust new options "cafile", "capath", "key", "cert", "egd", and "pseudo" for openssl new options "retry", "forever", and "intervall" option "fork" for address TCP improves `gender changer´ options "sigint", "sigquit", and "sighup" control passing of signals to sub process (thanks to David Shea who contributed to this issue) readline takes respect to the prompt issued by the peer address options "prompt" and "noprompt" allow to override readline's new default behaviour readline supports invisible password with option "noecho" socat option -lp allows to set hostname in log output socat option -lu turns on microsecond resolution in log output corrections: before reading available data, check if writing on other channel is possible tcp6, udp6: support hostname specification (not only IP address), and map IP4 names to IP6 addresses openssl client checks server certificate per default support unidirectional communication with exec/system subprocess try to restore original terminal settings when terminating test.sh uses tmp dir /tmp/$USER/$$ instead of /tmp/$$ socks4 failed on platforms where long does not have 32 bits (thanks to Peter Palfrader and Thomas Seyrat) hstrerror substitute wrote wrong messages (HP-UX, Solaris) proxy error message was truncated when answer contained multiple spaces porting: compiles with AIX xlc, HP-UX cc, Tru64 cc (but might not link) ####################### V 1.3.2.2: corrections: PROXY CONNECT failed when the status reply from the proxy server contained more than one consecutive spaces. Problem reported by Alexandre Bezroutchko do not SIGSEGV when proxy address fails to resolve server name udp-listen failed on systems where AF_INET != SOCK_DGRAM (e.g. SunOS). Problem reported by Christoph Schittel test.sh only tests available features added missing IP and TCP options in filan analyzer do not apply stdio address options to both directions when in unidirectional mode on systems lacking /dev/*random and egd, provide (weak) entropy from libc random() porting: changes for HP-UX (VREPRINT, h_NETDB_INTERNAL) compiles on True64, FreeBSD (again), NetBSD, OpenBSD support for long long as st_ino type (Cygwin 1.5) compile on systems where pty can not be featured ####################### V 1.3.2.1: corrections: "final" solution for the ENOCHLD problem corrected "make strip" default gcc debug/opt is "-O" again check for /proc at runtime, even if configure found it src.rpm accidently supported SuSE instead of RedHat ####################### V 1.3.2.0: new features: option "nofork" connects an exec'd script or program directly to the file descriptors of the other address, circumventing the socat transfer engine support for files >2GB, using ftruncate64(), lseek64(), stat64() filan has new "simple" output style (filan -s) porting: options "binary" and "text" for controlling line termination on Cygwin file system access (hint from Yang Wu-Zhou) fix by Yang Wu-Zhou for the Cygwin "No Children" problem improved support for OSR: _SVID3; no IS_SOCK, no F_GETOWN (thanks to John DuBois) minor corrections to avoid warnings with gcc 3 further corrections and minor improvements: configure script is generated with autoconf 2.57 (no longer 2.52) configure passes CFLAGS to Makefile option -??? for complete list of address options and their short forms program name in syslog messages is derived from argv[0] SIGHUP now prints notice instead of error EIO during read of pty now gives Notice instead of Error, and triggers EOF use of hstrerror() for printing resolver error messages setgrent() got required endgrent() ####################### V 1.3.1.0: new features: integration of Wietse Venema's tcpwrapper library (libwrap) with "proxy" address, option "resolve" controls if hostname or IP address is sent in request option "lowport" establishes limited authorization for TCP and UDP connections improvement of .spec file for RPM creation (thanks to Gerd v. Egidy) An accompanying change in the numbering scheme results in an incompatibility with earlier socat RPMs! solved problems and bugs: PROBLEM: socat daemon terminated when the address of a connecting client did not match range option value instead of continue listening SOLVED: in this case, print warning instead of error to keep daemon active PROBLEM: tcp-listen with fork sometimes left excessive number of zombie processes SOLVED: dont assume that each exiting child process generates SIGCHLD when converting CRNL to CR, socat converted to NL further corrections: configure script now disables features that depend on missing files making it more robust in "unsupported" environments server.pem permissions corrected to 600 "make install" now does not strip; use "make strip; make install" if you like strip (suggested by Peter Bray) ####################### V 1.3.0.1: solved problems and bugs: PROBLEM: OPENSSL did not apply tcp, ip, and socket options SOLVED: OPENSSL now correctly handles the options list PROBLEM: CRNL to NL and CRNL to CR conversions failed when CRNL crossed block boundary SOLVED: these conversions now simply strip all CR's or NL's from input stream porting: SunOS ptys now work on x86, too (thanks to Peter Bray) configure looks for freeware libs in /pkgs/lib/ (thanks to Peter Bray) further corrections: added WITH_PROXY value to -V output added compile dependencies of WITH_PTY and WITH_PROXY -?? did not print option group of proxy options corrected syntax for bind option in docu corrected an issue with stdio in unidirectional mode options socksport and proxyport support service names ftp.sh script supports proxy address man page no longer installed with execute permissions (thanks to Peter Bray) fixed a malloc call bug that could cause SIGSEGV or false "out of memory" errors on EXEC and SYSTEM, depending on program name length and libc. ####################### V 1.3.0.0: new features: proxy connect with optional proxy authentication combined hex and text dump mode, credits to Gregory Margo address pty applies options user, group, and perm to device solved problems and bugs: PROBLEM: option reuseport was not applied (BSD, AIX) SOLVED: option reuseport now in phase PASTSOCKET instead of PREBIND, credits to Jean-Baptiste Marchand PROBLEM: ignoreeof with stdio was ignored SOLVED: ignoreeof now works correctly with address stdio PROBLEM: ftp.sh did not use user supplied password SOLVED: ftp.sh now correctly passes password from command line PROBLEM: server.pem had expired SOLVED: new server.pem valid for ten years PROBLEM: socks notice printed wrong port on some platforms SOLVED: socks now uses correct byte-order for port number in notice further corrections: option name o_trunc corrected to o-trunc combined use of -u and -U is now detected and prevented made message system a little more robust against format string attacks ####################### V 1.2.0.0: new features: address pty for putting socat behind a new pseudo terminal that may fake a serial line, modem etc. experimental openssl integration (it does not provide any trust between the peers because is does not check certificates!) options flock-ex, flock-ex-nb, flock-sh, flock-sh-nb to control all locking mechanism provided by flock() options setsid and setpgid now available with all address types option ctty (controlling terminal) now available for all TERMIOS addresses option truncate (a hybrid of open(.., O_TRUNC) and ftruncate()) is replaced by options o-trunc and ftruncate=offset option sourceport now available with TCP and UDP listen addresses to restrict incoming client connections unidirectional mode right-to-left (-U) solved problems and bugs: PROBLEM: addresses without required parameters but an option containing a '/' were incorrectly interpreted as implicit GOPEN address SOLVED: if an address does not have ':' separator but contains '/', check if the slash is before the first ',' before assuming implicit GOPEN. porting: ptys under SunOS work now due to use of stream options further corrections: with -d -d -d -d -D, don't print debug info during file analysis ####################### V 1.1.0.1: new features: .spec file for RPM generation solved problems and bugs: PROBLEM: GOPEN on socket did not apply option unlink-late SOLUTION: GOPEN for socket now applies group NAMED, phase PASTOPEN options PROBLEM: with unidirectional mode, an unnecessary close timeout was applied SOLUTION: in unidirectional mode, terminate without wait time PROBLEM: using GOPEN on a unix domain socket failed for datagram sockets SOLUTION: when connect() fails with EPROTOTYPE, use a datagram socket further corrections: open() flag options had names starting with "o_", now corrected to "o-" in docu, *-listen addresses were called *_listen address unix now called unix-connect because it does not handle unix datagram sockets in test.sh, apply global command line options with all tests ####################### V 1.1.0.0: new features: regular man page and html doc - thanks to kromJx for prototype new address type "readline", utilizing GNU readline and history libs address option "history-file" for readline new option "dash" to "exec" address that allows to start login shells syslog facility can be set per command line option new address option "tcp-quickack", found in Linux 2.4 option -g prevents option group checking filan and procan can print usage procan prints rlimit infos solved problems and bugs: PROBLEM: raw IP socket SIGSEGV'ed when it had been shut down. SOLVED: set eof flag of channel on shutdown. PROBLEM: if channel 2 uses a single non-socket FD in bidirectional mode and has data available while channel 1 reaches EOF, the data is lost. SOLVED: during one loop run, first handle all data transfers and _afterwards_ handle EOF. PROBLEM: despite to option NONBLOCK, the connect() call blocked SOLVED: option NONBLOCK is now applied in phase FD instead of LATE PROBLEM: UNLINK options issued error when file did not exist, terminating socat SOLVED: failure of unlink() is only warning if errno==ENOENT PROBLEM: TCP6-LISTEN required numeric port specification SOLVED: now uses common TCP service resolver PROBLEM: with PIPE, wrong FDs were shown for data transfer loop SOLVED: retrieval of FDs now pays respect to PIPE pecularities PROBLEM: using address EXEC against an address with IGNOREEOF, socat never terminated SOLVED: corrected EOF handling of sigchld porting: MacOS and old AIX versions now have pty flock() now available on Linux (configure check was wrong) named pipe were generated using mknod(), which requires root under BSD now they are generated using mkfifo further corrections: lots of address options that were "forgotten" at runtime are now available option BINDTODEVICE now also called SO-BINDTODEVICE, IF "make install" now installs binaries with ownership 0:0 ####################### V 1.0.4.2: solved problems and bugs: PROBLEM: EOF of one stream caused close of other stream, giving it no chance to go down regularly SOLVED: EOF of one stream now causes shutdown of write part of other stream PROBLEM: sending mail via socks address to qmail showed that crlf option does not work SOLVED: socks address applies PH_LATE options PROBLEM: in debug mode, no info about socat and platform was issued SOLVED: print socat version and uname output in debug mode PROBLEM: invoking socat with -t and no following parameters caused SIGSEGV SOLVED: -t and -b now check next argv entry PROBLEM: when opening of logfile (-lf) failed, no error was reported and no further messages were printed SOLVED: check result of fopen and print error message if it failed new features: address type UDP-LISTEN now supports option fork: it internally applies socket option SO_REUSEADDR so a new UDP socket can bind to port after `accepting´ a connection (child processes might live forever though) (suggestion from Damjan Lango) ####################### V 1.0.4.1: solved problems and bugs: PROB: assert in libc caused an endless recursion SOLVED: no longer catch SIGABRT PROB: socat printed wrong verbose prefix for "right to left" packets SOLVED: new parameter for xiotransfer() passes correct prefix new features: in debug mode, socat prints its command line arguments in verbose mode, escape special characters and replace unprintables with '.'. Patch from Adrian Thurston. ####################### V 1.0.4.0: solved problems and bugs: Debug output for lstat and fstat said "stat" further corrections: FreeBSD now includes libutil.h new features: option setsid with exec/pty option setpgid with exec/pty option ctty with exec/pty TCP V6 connect test gettimeofday in sycls.c (no use yet) porting: before Gethostbyname, invoke inet_aton for MacOSX ####################### V 1.0.3.0: solved problems and bugs: PROB: test 9 of test.sh (echo via file) failed on some platforms, socat exited without error message SOLVED: _xioopen_named_early(): preset statbuf.st_mode with 0 PROB: test 17 hung forever REASON: child death before select loop did not result in EOF SOLVED: check of existence of children before starting select loop PROB: test 17 failed REASON: child dead triggered EOF before last data was read SOLVED: after child death, read last data before setting EOF PROB: filan showed that exec processes incorrectly had fd3 open REASON: inherited open fd3 from main process SOLVED: set CLOEXEC flag on pty fd in main process PROB: help printed "undef" instead of group "FORK" SOLVED: added "FORK" to group name array PROB: fatal messages did not include severity classifier SOLVED: added "F" to severity classifier array PROB: IP6 addresses where printed incorrectly SOLVED: removed type casts to unsigned short * further corrections: socat catches illegal -l modes corrected error message on setsockopt(linger) option tabdly is of type uint correction for UDP over IP6 more cpp conditionals, esp. for IP6 situations better handling of group NAMED options with listening UNIX sockets applyopts2 now includes last given phase corrected option group handling for most address types introduce dropping of unappliable options (dropopts, dropopts2) gopen now accepts socket and unix-socket options exec and system now accept all socket and termios options child process for exec and system addresses with option pty improved descriptions and options for EXAMPLES printf format for file mode changed to "0%03o" with length spec. added va_end() in branch of msg() changed phase of lock options from PASTOPEN to FD support up to four early dying processes structural changes: xiosysincludes now includes sysincludes.h for non xio files new features: option umask CHANGES file TYPE_DOUBLE, u_double OFUNC_OFFSET added getsid(), setsid(), send() to sycls procan prints sid (session id) mail.sh gets -f (from) option new EXAMPLEs for file creation gatherinfo.sh now tells about failures test.sh can check for much more address/option combinations porting: ispeed, ospeed for termios on FreeBSD getpgid() conditional for MacOS 10 added ranlib in Makefile.in for MacOS 10 disable pty option if no pty mechanism is available (MacOS 10) now compiles and runs on MacOS 10 (still some tests fail) setgroups() conditional for cygwin sighandler_t defined conditionally use gcc option -D_GNU_SOURCE socat-1.7.3.1/xio-ip.c0000644000201000020100000005400312460670272014141 0ustar gerhardgerhard/* source: xio-ip.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for IP related functions */ #include "xiosysincludes.h" #if _WITH_IP4 || _WITH_IP6 #include "xioopen.h" #include "xio-ascii.h" #include "xio-socket.h" #include "xio-ip.h" #include "xio-ip6.h" #if WITH_IP4 || WITH_IP6 #ifdef IP_OPTIONS const struct optdesc opt_ip_options = { "ip-options", "ipoptions", OPT_IP_OPTIONS, GROUP_SOCK_IP, PH_PASTSOCKET,TYPE_BIN, OFUNC_SOCKOPT_APPEND, SOL_IP, IP_OPTIONS }; #endif #ifdef IP_PKTINFO const struct optdesc opt_ip_pktinfo = { "ip-pktinfo", "pktinfo", OPT_IP_PKTINFO, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_PKTINFO }; #endif #ifdef IP_RECVTOS const struct optdesc opt_ip_recvtos = { "ip-recvtos", "recvtos", OPT_IP_RECVTOS, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_RECVTOS }; #endif #ifdef IP_RECVTTL /* -Cygwin */ const struct optdesc opt_ip_recvttl = { "ip-recvttl", "recvttl", OPT_IP_RECVTTL, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_RECVTTL }; #endif #ifdef IP_RECVOPTS const struct optdesc opt_ip_recvopts= { "ip-recvopts","recvopts", OPT_IP_RECVOPTS,GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_RECVOPTS }; #endif #ifdef IP_RETOPTS const struct optdesc opt_ip_retopts = { "ip-retopts", "retopts", OPT_IP_RETOPTS, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_RETOPTS }; #endif const struct optdesc opt_ip_tos = { "ip-tos", "tos", OPT_IP_TOS, GROUP_SOCK_IP, PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_TOS }; const struct optdesc opt_ip_ttl = { "ip-ttl", "ttl", OPT_IP_TTL, GROUP_SOCK_IP, PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_TTL }; #ifdef IP_HDRINCL const struct optdesc opt_ip_hdrincl = { "ip-hdrincl", "hdrincl", OPT_IP_HDRINCL, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_HDRINCL }; #endif #ifdef IP_RECVERR const struct optdesc opt_ip_recverr = { "ip-recverr", "recverr", OPT_IP_RECVERR, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_RECVERR }; #endif #ifdef IP_MTU_DISCOVER const struct optdesc opt_ip_mtu_discover={"ip-mtu-discover","mtudiscover",OPT_IP_MTU_DISCOVER,GROUP_SOCK_IP,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_IP,IP_MTU_DISCOVER }; #endif #ifdef IP_MTU const struct optdesc opt_ip_mtu = { "ip-mtu", "mtu", OPT_IP_MTU, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_MTU }; #endif #ifdef IP_FREEBIND const struct optdesc opt_ip_freebind= { "ip-freebind","freebind", OPT_IP_FREEBIND,GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_FREEBIND }; #endif #ifdef IP_ROUTER_ALERT const struct optdesc opt_ip_router_alert={"ip-router-alert","routeralert",OPT_IP_ROUTER_ALERT,GROUP_SOCK_IP,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_IP,IP_ROUTER_ALERT}; #endif /* following: Linux allows int but OpenBSD reqs char/byte */ const struct optdesc opt_ip_multicast_ttl={"ip-multicast-ttl","multicastttl",OPT_IP_MULTICAST_TTL,GROUP_SOCK_IP,PH_PASTSOCKET,TYPE_BYTE,OFUNC_SOCKOPT,SOL_IP,IP_MULTICAST_TTL}; /* following: Linux allows int but OpenBSD reqs char/byte */ const struct optdesc opt_ip_multicast_loop={"ip-multicast-loop","multicastloop",OPT_IP_MULTICAST_LOOP,GROUP_SOCK_IP,PH_PASTSOCKET,TYPE_BYTE,OFUNC_SOCKOPT,SOL_IP,IP_MULTICAST_LOOP}; const struct optdesc opt_ip_multicast_if ={"ip-multicast-if", "multicast-if", OPT_IP_MULTICAST_IF, GROUP_SOCK_IP,PH_PASTSOCKET,TYPE_IP4NAME,OFUNC_SOCKOPT,SOL_IP,IP_MULTICAST_IF}; #ifdef IP_PKTOPTIONS const struct optdesc opt_ip_pktoptions = { "ip-pktoptions", "pktopts", OPT_IP_PKTOPTIONS, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_PKTOPTIONS }; #endif #ifdef IP_ADD_MEMBERSHIP const struct optdesc opt_ip_add_membership = { "ip-add-membership", "membership",OPT_IP_ADD_MEMBERSHIP, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_IP_MREQN, OFUNC_SOCKOPT, SOL_IP, IP_ADD_MEMBERSHIP }; #endif #ifdef IP_RECVDSTADDR const struct optdesc opt_ip_recvdstaddr = { "ip-recvdstaddr", "recvdstaddr",OPT_IP_RECVDSTADDR, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_RECVDSTADDR }; #endif #ifdef IP_RECVIF const struct optdesc opt_ip_recvif = { "ip-recvif", "recvdstaddrif",OPT_IP_RECVIF, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_RECVIF }; #endif #if HAVE_RESOLV_H const struct optdesc opt_res_debug = { "res-debug", NULL, OPT_RES_DEBUG, GROUP_SOCK_IP, PH_INIT, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.socket.ip.res_opts), XIO_SIZEOF(para.socket.ip.res_opts), RES_DEBUG }; const struct optdesc opt_res_aaonly = { "res-aaonly", "aaonly", OPT_RES_AAONLY, GROUP_SOCK_IP, PH_INIT, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.socket.ip.res_opts), XIO_SIZEOF(para.socket.ip.res_opts), RES_AAONLY }; const struct optdesc opt_res_usevc = { "res-usevc", "usevc", OPT_RES_USEVC, GROUP_SOCK_IP, PH_INIT, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.socket.ip.res_opts), XIO_SIZEOF(para.socket.ip.res_opts), RES_USEVC }; const struct optdesc opt_res_primary = { "res-primary", "primary", OPT_RES_PRIMARY, GROUP_SOCK_IP, PH_INIT, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.socket.ip.res_opts), XIO_SIZEOF(para.socket.ip.res_opts), RES_PRIMARY }; const struct optdesc opt_res_igntc = { "res-igntc", "igntc", OPT_RES_IGNTC, GROUP_SOCK_IP, PH_INIT, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.socket.ip.res_opts), XIO_SIZEOF(para.socket.ip.res_opts), RES_IGNTC }; const struct optdesc opt_res_recurse = { "res-recurse", "recurse", OPT_RES_RECURSE, GROUP_SOCK_IP, PH_INIT, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.socket.ip.res_opts), XIO_SIZEOF(para.socket.ip.res_opts), RES_RECURSE }; const struct optdesc opt_res_defnames = { "res-defnames", "defnames", OPT_RES_DEFNAMES, GROUP_SOCK_IP, PH_INIT, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.socket.ip.res_opts), XIO_SIZEOF(para.socket.ip.res_opts), RES_DEFNAMES }; const struct optdesc opt_res_stayopen = { "res-stayopen", "stayopen", OPT_RES_STAYOPEN, GROUP_SOCK_IP, PH_INIT, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.socket.ip.res_opts), XIO_SIZEOF(para.socket.ip.res_opts), RES_STAYOPEN }; const struct optdesc opt_res_dnsrch = { "res-dnsrch", "dnsrch", OPT_RES_DNSRCH, GROUP_SOCK_IP, PH_INIT, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.socket.ip.res_opts), XIO_SIZEOF(para.socket.ip.res_opts), RES_DNSRCH }; #endif /* HAVE_RESOLV_H */ #endif /* WITH_IP4 || WITH_IP6 */ #if HAVE_RESOLV_H int Res_init(void) { int result; Debug("res_init()"); result = res_init(); Debug1("res_init() -> %d", result); return result; } #endif /* HAVE_RESOLV_H */ #if HAVE_RESOLV_H unsigned long res_opts() { return _res.options; } #endif /* HAVE_RESOLV_H */ /* the ultimate(?) socat resolver function node: the address to be resolved; supported forms: 1.2.3.4 (IPv4 address) [::2] (IPv6 address) hostname (hostname resolving to IPv4 or IPv6 address) hostname.domain (fq hostname resolving to IPv4 or IPv6 address) service: the port specification; may be numeric or symbolic family: PF_INET, PF_INET6, or PF_UNSPEC permitting both socktype: SOCK_STREAM, SOCK_DGRAM protocol: IPPROTO_UDP, IPPROTO_TCP sau: an uninitialized storage for the resulting socket address returns: STAT_OK, STAT_RETRYLATER */ int xiogetaddrinfo(const char *node, const char *service, int family, int socktype, int protocol, union sockaddr_union *sau, socklen_t *socklen, unsigned long res_opts0, unsigned long res_opts1) { int port = -1; /* port number in network byte order */ char *numnode = NULL; size_t nodelen; unsigned long save_res_opts = 0; #if HAVE_GETADDRINFO struct addrinfo hints = {0}; struct addrinfo *res = NULL; #else /* HAVE_PROTOTYPE_LIB_getipnodebyname || nothing */ struct hostent *host; #endif int error_num; #if HAVE_RESOLV_H if (res_opts0 | res_opts1) { if (!(_res.options & RES_INIT)) { Res_init(); /*!!! returns -1 on error */ } save_res_opts = _res.options; _res.options &= ~res_opts0; _res.options |= res_opts1; Debug2("changed _res.options from 0x%lx to 0x%lx", save_res_opts, _res.options); } #endif /* HAVE_RESOLV_H */ memset(sau, 0, *socklen); sau->soa.sa_family = family; if (service && service[0]=='\0') { Error("empty port/service"); } /* if service is numeric we don't want to have a lookup (might take long with NIS), so we handle this specially */ if (service && isdigit(service[0]&0xff)) { char *extra; port = htons(strtoul(service, &extra, 0)); if (*extra != '\0') { Warn2("xiogetaddrinfo(, \"%s\", ...): extra trailing data \"%s\"", service, extra); } service = NULL; } /* the resolver functions might handle numeric forms of node names by reverse lookup, that's not what we want. So we detect these and handle them specially */ if (node && isdigit(node[0]&0xff)) { #if HAVE_GETADDRINFO hints.ai_flags |= AI_NUMERICHOST; #endif /* HAVE_GETADDRINFO */ if (family == PF_UNSPEC) { family = PF_INET; #if HAVE_GETADDRINFO } else if (family == PF_INET6) { /* map "explicitely" into IPv6 address space; getipnodebyname() does this with AI_V4MAPPED, but not getaddrinfo() */ if ((numnode = Malloc(strlen(node)+7+1)) == NULL) { #if HAVE_RESOLV_H if (res_opts0 | res_opts1) { _res.options = (_res.options & (~res_opts0&~res_opts1) | save_res_opts& ( res_opts0| res_opts1)); } #endif return STAT_NORETRY; } sprintf(numnode, "::ffff:%s", node); node = numnode; hints.ai_flags |= AI_NUMERICHOST; #endif /* HAVE_GETADDRINFO */ } #if WITH_IP6 } else if (node && node[0] == '[' && node[(nodelen=strlen(node))-1]==']') { if ((numnode = Malloc(nodelen-1)) == NULL) { #if HAVE_RESOLV_H if (res_opts0 | res_opts1) { _res.options = (_res.options & (~res_opts0&~res_opts1) | save_res_opts& ( res_opts0| res_opts1)); } #endif return STAT_NORETRY; } strncpy(numnode, node+1, nodelen-2); /* ok */ numnode[nodelen-2] = '\0'; node = numnode; #if HAVE_GETADDRINFO hints.ai_flags |= AI_NUMERICHOST; #endif /* HAVE_GETADDRINFO */ if (family == PF_UNSPEC) family = PF_INET6; #endif /* WITH_IP6 */ } #if HAVE_GETADDRINFO if (node != NULL || service != NULL) { struct addrinfo *record; if (socktype != SOCK_STREAM && socktype != SOCK_DGRAM) { /* actual socket type value is not supported - fallback to a good one */ socktype = SOCK_DGRAM; } if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP) { /* actual protocol value is not supported - fallback to a good one */ if (socktype == SOCK_DGRAM) { protocol = IPPROTO_UDP; } else { protocol = IPPROTO_TCP; } } hints.ai_flags |= AI_PASSIVE; hints.ai_family = family; hints.ai_socktype = socktype; hints.ai_protocol = protocol; hints.ai_addrlen = 0; hints.ai_addr = NULL; hints.ai_canonname = NULL; hints.ai_next = NULL; if ((error_num = Getaddrinfo(node, service, &hints, &res)) != 0) { Error7("getaddrinfo(\"%s\", \"%s\", {%d,%d,%d,%d}, {}): %s", node, service, hints.ai_flags, hints.ai_family, hints.ai_socktype, hints.ai_protocol, (error_num == EAI_SYSTEM)? strerror(errno):gai_strerror(error_num)); if (res != NULL) freeaddrinfo(res); if (numnode) free(numnode); #if HAVE_RESOLV_H if (res_opts0 | res_opts1) { _res.options = (_res.options & (~res_opts0&~res_opts1) | save_res_opts& ( res_opts0| res_opts1)); } #endif return STAT_RETRYLATER; } service = NULL; /* do not resolve later again */ record = res; if (family == PF_UNSPEC && xioopts.preferred_ip == '0') { /* we just take the first result */ family = res[0].ai_addr->sa_family; } if (family == PF_UNSPEC) { int trypf; trypf = (xioopts.preferred_ip=='6'?PF_INET6:PF_INET); /* we must look for a matching entry */ while (record != NULL) { if (record->ai_family == trypf) { family = trypf; break; /* family and record set accordingly */ } record = record->ai_next; } if (record == NULL) { /* we did not find a "preferred" entry, take the first */ record = res; family = res[0].ai_addr->sa_family; } } switch (family) { #if WITH_IP4 case PF_INET: if (*socklen > record->ai_addrlen) { *socklen = record->ai_addrlen; } memcpy(&sau->ip4, record->ai_addr, *socklen); break; #endif /* WITH_IP4 */ #if WITH_IP6 case PF_INET6: #if _AIX /* older AIX versions pass wrong length, so we correct it */ record->ai_addr->sa_len = sizeof(struct sockaddr_in6); #endif if (*socklen > record->ai_addrlen) { *socklen = record->ai_addrlen; } memcpy(&sau->ip6, record->ai_addr, *socklen); break; #endif /* WITH_IP6 */ default: Error1("address resolved to unknown protocol family %d", record->ai_addr->sa_family); break; } freeaddrinfo(res); } else { switch (family) { #if WITH_IP4 case PF_INET: *socklen = sizeof(sau->ip4); break; #endif /* WITH_IP4 */ #if WITH_IP6 case PF_INET6: *socklen = sizeof(sau->ip6); break; #endif /* WITH_IP6 */ } } #elif HAVE_PROTOTYPE_LIB_getipnodebyname /* !HAVE_GETADDRINFO */ if (node != NULL) { /* first fallback is getipnodebyname() */ if (family == PF_UNSPEC) { #if WITH_IP4 && WITH_IP6 family = xioopts.default_ip=='6'?PF_INET6:PF_INET; #elif WITH_IP6 family = PF_INET6; #else family = PF_INET; #endif } host = Getipnodebyname(node, family, AI_V4MAPPED, &error_num); if (host == NULL) { const static char ai_host_not_found[] = "Host not found"; const static char ai_no_address[] = "No address"; const static char ai_no_recovery[] = "No recovery"; const static char ai_try_again[] = "Try again"; const char *error_msg = "Unknown error"; switch (error_num) { case HOST_NOT_FOUND: error_msg = ai_host_not_found; break; case NO_ADDRESS: error_msg = ai_no_address; case NO_RECOVERY: error_msg = ai_no_recovery; case TRY_AGAIN: error_msg = ai_try_again; } Error2("getipnodebyname(\"%s\", ...): %s", node, error_msg); } else { switch (family) { #if WITH_IP4 case PF_INET: *socklen = sizeof(sau->ip4); sau->soa.sa_family = PF_INET; memcpy(&sau->ip4.sin_addr, host->h_addr_list[0], 4); break; #endif #if WITH_IP6 case PF_INET6: *socklen = sizeof(sau->ip6); sau->soa.sa_family = PF_INET6; memcpy(&sau->ip6.sin6_addr, host->h_addr_list[0], 16); break; #endif } } freehostent(host); } #else /* !HAVE_PROTOTYPE_LIB_getipnodebyname */ if (node != NULL) { /* this is not a typical IP6 resolver function - but Linux "man gethostbyname" says that the only supported address type with this function is AF_INET _at present_, so maybe this fallback will be useful somewhere sometimesin a future even for IP6 */ if (family == PF_UNSPEC) { #if WITH_IP4 && WITH_IP6 family = xioopts.default_ip=='6'?PF_INET6:PF_INET; #elif WITH_IP6 family = PF_INET6; #else family = PF_INET; #endif } /*!!! try gethostbyname2 for IP6 */ if ((host = Gethostbyname(node)) == NULL) { Error2("gethostbyname(\"%s\"): %s", node, h_errno == NETDB_INTERNAL ? strerror(errno) : hstrerror(h_errno)); #if HAVE_RESOLV_H if (res_opts0 | res_opts1) { _res.options = (_res.options & (~res_opts0&~res_opts1) | save_res_opts& ( res_opts0| res_opts1)); } #endif return STAT_RETRYLATER; } if (host->h_addrtype != family) { Error2("xioaddrinfo(): \"%s\" does not resolve to %s", node, family==PF_INET?"IP4":"IP6"); } else { switch (family) { #if WITH_IP4 case PF_INET: *socklen = sizeof(sau->ip4); sau->soa.sa_family = PF_INET; memcpy(&sau->ip4.sin_addr, host->h_addr_list[0], 4); break; #endif /* WITH_IP4 */ #if WITH_IP6 case PF_INET6: *socklen = sizeof(sau->ip6); sau->soa.sa_family = PF_INET6; memcpy(&sau->ip6.sin6_addr, host->h_addr_list[0], 16); break; #endif /* WITH_IP6 */ } } } #endif #if WITH_TCP || WITH_UDP if (service) { port = parseport(service, protocol); } if (port >= 0) { switch (family) { #if WITH_IP4 case PF_INET: sau->ip4.sin_port = port; break; #endif /* WITH_IP4 */ #if WITH_IP6 case PF_INET6: sau->ip6.sin6_port = port; break; #endif /* WITH_IP6 */ } } #endif /* WITH_TCP || WITH_UDP */ if (numnode) free(numnode); #if HAVE_RESOLV_H if (res_opts0 | res_opts1) { _res.options = (_res.options & (~res_opts0&~res_opts1) | save_res_opts& ( res_opts0| res_opts1)); } #endif /* HAVE_RESOLV_H */ return STAT_OK; } #if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) /* converts the ancillary message in *cmsg into a form useable for further processing. knows the specifics of common message types. these are valid for IPv4 and IPv6 returns the number of resulting syntax elements in *num returns a sequence of \0 terminated type strings in *typbuff returns a sequence of \0 terminated name strings in *nambuff returns a sequence of \0 terminated value strings in *valbuff the respective len parameters specify the available space in the buffers returns STAT_OK on success returns STAT_WARNING if a buffer was too short and data truncated. */ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, char *typbuff, int typlen, char *nambuff, int namlen, char *envbuff, int envlen, char *valbuff, int vallen) { const char *cmsgtype, *cmsgname = NULL, *cmsgenvn = NULL, *cmsgfmt = NULL; size_t msglen; char scratch1[16]; /* can hold an IPv4 address in ASCII */ #if WITH_IP4 && defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO char scratch2[16]; char scratch3[16]; #endif int rc = 0; msglen = cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg); envbuff[0] = '\0'; switch (cmsg->cmsg_type) { default: *num = 1; typbuff[0] = '\0'; strncat(typbuff, "IP", typlen-1); snprintf(nambuff, namlen, "type_%u", cmsg->cmsg_type); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #if WITH_IP4 #if defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO case IP_PKTINFO: { struct in_pktinfo *pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg); *num = 3; typbuff[0] = '\0'; strncat(typbuff, "IP_PKTINFO", typlen-1); snprintf(nambuff, namlen, "%s%c%s%c%s", "if", '\0', "locaddr", '\0', "dstaddr"); snprintf(envbuff, envlen, "%s%c%s%c%s", "IP_IF", '\0', "IP_LOCADDR", '\0', "IP_DSTADDR"); snprintf(valbuff, vallen, "%s%c%s%c%s", xiogetifname(pktinfo->ipi_ifindex, scratch1, -1), '\0', #if HAVE_PKTINFO_IPI_SPEC_DST inet4addr_info(ntohl(pktinfo->ipi_spec_dst.s_addr), scratch2, sizeof(scratch2)), #else "", #endif '\0', inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr), scratch3, sizeof(scratch3))); } return STAT_OK; #endif /* defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO */ #endif /* WITH_IP4 */ #if defined(IP_RECVERR) && HAVE_STRUCT_SOCK_EXTENDED_ERR case IP_RECVERR: { struct sock_extended_err *err = (struct sock_extended_err *)CMSG_DATA(cmsg); *num = 6; typbuff[0] = '\0'; strncat(typbuff, "IP_RECVERR", typlen-1); snprintf(nambuff, namlen, "%s%c%s%c%s%c%s%c%s%c%s", "errno", '\0', "origin", '\0', "type", '\0', "code", '\0', "info", '\0', "data"); snprintf(envbuff, envlen, "%s%c%s%c%s%c%s%c%s%c%s", "IP_RECVERR_ERRNO", '\0', "IP_RECVERR_ORIGIN", '\0', "IP_RECVERR_TYPE", '\0', "IP_RECVERR_CODE", '\0', "IP_RECVERR_INFO", '\0', "IP_RECVERR_DATA"); snprintf(valbuff, vallen, "%u%c%u%c%u%c%u%c%u%c%u", err->ee_errno, '\0', err->ee_origin, '\0', err->ee_type, '\0', err->ee_code, '\0', err->ee_info, '\0', err->ee_data); return STAT_OK; } #endif /* defined(IP_RECVERR) && HAVE_STRUCT_SOCK_EXTENDED_ERR */ #ifdef IP_RECVIF case IP_RECVIF: { /* spec in FreeBSD: /usr/include/net/if_dl.h */ struct sockaddr_dl *sadl = (struct sockaddr_dl *)CMSG_DATA(cmsg); *num = 1; typbuff[0] = '\0'; strncat(typbuff, "IP_RECVIF", typlen-1); nambuff[0] = '\0'; strncat(nambuff, "if", namlen-1); envbuff[0] = '\0'; strncat(envbuff, "IP_IF", envlen-1); valbuff[0] = '\0'; strncat(valbuff, xiosubstr(scratch1, sadl->sdl_data, 0, sadl->sdl_nlen), vallen-1); return STAT_OK; } #endif /* defined(IP_RECVIF) */ #if WITH_IP4 #ifdef IP_RECVDSTADDR case IP_RECVDSTADDR: *num = 1; typbuff[0] = '\0'; strncat(typbuff, "IP_RECVDSTADDR", typlen-1); nambuff[0] = '\0'; strncat(nambuff, "dstaddr", namlen-1); envbuff[0] = '\0'; strncat(envbuff, "IP_DSTADDR", envlen-1); inet4addr_info(ntohl(*(uint32_t *)CMSG_DATA(cmsg)), valbuff, vallen); return STAT_OK; #endif #endif /* WITH_IP4 */ case IP_OPTIONS: #ifdef IP_RECVOPTS case IP_RECVOPTS: #endif cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgfmt = NULL; break; case IP_TOS: cmsgtype = "IP_TOS"; cmsgname = "tos"; cmsgfmt = "%u"; break; case IP_TTL: /* Linux */ #ifdef IP_RECVTTL case IP_RECVTTL: /* FreeBSD */ #endif cmsgtype = "IP_TTL"; cmsgname = "ttl"; cmsgfmt = "%u"; break; } /* when we come here we provide a single parameter with type in cmsgtype, name in cmsgname, printf format in cmsgfmt */ *num = 1; if (strlen(cmsgtype) >= typlen) rc = STAT_WARNING; typbuff[0] = '\0'; strncat(typbuff, cmsgtype, typlen-1); if (strlen(cmsgname) >= namlen) rc = STAT_WARNING; nambuff[0] = '\0'; strncat(nambuff, cmsgname, namlen-1); if (cmsgenvn) { if (strlen(cmsgenvn) >= envlen) rc = STAT_WARNING; envbuff[0] = '\0'; strncat(envbuff, cmsgenvn, envlen-1); } else { envbuff[0] = '\0'; } if (cmsgfmt != NULL) { snprintf(valbuff, vallen, cmsgfmt, *(unsigned char *)CMSG_DATA(cmsg)); } else { xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); } return rc; } #endif /* defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) */ #endif /* _WITH_IP4 || _WITH_IP6 */ socat-1.7.3.1/xio-fdnum.c0000644000201000020100000000450311453022152014627 0ustar gerhardgerhard/* source: xio-fdnum.c */ /* Copyright Gerhard Rieger 2001-2006 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of fdnum type */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-fdnum.h" #if WITH_FDNUM static int xioopen_fdnum(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3); const struct addrdesc addr_fd = { "fd", 3, 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(":") }; /* 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, unsigned groups, int dummy1, int dummy2, int dummy3) { char *a1; int rw = (xioflags&XIO_ACCMODE); int numfd; int result; if (argc != 2) { Error3("%s:%s: wrong number of parameters (%d instead of 1)", argv[0], argv[1], argc-1); } numfd = strtoul(argv[1], &a1, 0); if (*a1 != '\0') { Error1("error in FD number \"%s\"", argv[1]); } /* we dont want to see these fds in child processes */ if (Fcntl_l(numfd, F_SETFD, FD_CLOEXEC) < 0) { 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) { return result; } return 0; } #endif /* WITH_FDNUM */ #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) { xfd->fd = numfd; xfd->howtoend = END_NONE; #if WITH_TERMIOS if (Isatty(xfd->fd)) { if (Tcgetattr(xfd->fd, &xfd->savetty) < 0) { Warn2("cannot query current terminal settings on fd %d: %s", xfd->fd, strerror(errno)); } else { xfd->ttyvalid = true; } } #endif /* WITH_TERMIOS */ if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); applyopts2(xfd->fd, opts, PH_INIT, PH_FD); return _xio_openlate(xfd, opts); } #endif /* WITH_FD */ socat-1.7.3.1/xio-file.c0000644000201000020100000001253611453022152014442 0ustar gerhardgerhard/* source: xio-file.c */ /* Copyright Gerhard Rieger 2001-2007 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of open type */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-named.h" #include "xio-file.h" static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); #if WITH_OPEN /****** OPEN addresses ******/ const struct optdesc opt_o_rdonly = { "o-rdonly", "rdonly", OPT_O_RDONLY, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG_PATTERN, O_RDONLY, O_ACCMODE }; const struct optdesc opt_o_wronly = { "o-wronly", "wronly", OPT_O_WRONLY, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG_PATTERN, O_WRONLY, O_ACCMODE }; const struct optdesc opt_o_rdwr = { "o-rdwr", "rdwr", OPT_O_RDWR, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG_PATTERN, O_RDWR, O_ACCMODE }; const struct optdesc opt_o_create = { "o-create", "creat", OPT_O_CREATE, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_CREAT }; const struct optdesc opt_o_excl = { "o-excl", "excl", OPT_O_EXCL, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_EXCL }; const struct optdesc opt_o_noctty = { "o-noctty", "noctty", OPT_O_NOCTTY, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_NOCTTY }; #ifdef O_SYNC const struct optdesc opt_o_sync = { "o-sync", "sync", OPT_O_SYNC, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_SYNC }; #endif #ifdef O_NOFOLLOW const struct optdesc opt_o_nofollow = { "o-nofollow", "nofollow",OPT_O_NOFOLLOW, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_NOFOLLOW }; #endif #ifdef O_DIRECTORY const struct optdesc opt_o_directory = { "o-directory", "directory",OPT_O_DIRECTORY, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_DIRECTORY }; #endif #ifdef O_LARGEFILE const struct optdesc opt_o_largefile = { "o-largefile", "largefile",OPT_O_LARGEFILE, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_LARGEFILE }; #endif #ifdef O_NSHARE const struct optdesc opt_o_nshare = { "o-nshare", "nshare", OPT_O_NSHARE, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_NSHARE }; #endif #ifdef O_RSHARE const struct optdesc opt_o_rshare = { "o-rshare", "rshare", OPT_O_RSHARE, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_RSHARE }; #endif #ifdef O_DEFER const struct optdesc opt_o_defer = { "o-defer", "defer", OPT_O_DEFER, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_DEFER }; #endif #ifdef O_DIRECT const struct optdesc opt_o_direct = { "o-direct", "direct", OPT_O_DIRECT, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_DIRECT }; #endif #ifdef O_DSYNC const struct optdesc opt_o_dsync = { "o-dsync", "dsync", OPT_O_DSYNC, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_DSYNC }; #endif #ifdef O_RSYNC const struct optdesc opt_o_rsync = { "o-rsync", "rsync", OPT_O_RSYNC, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_RSYNC }; #endif #ifdef O_DELAY const struct optdesc opt_o_delay = { "o-delay", "delay", OPT_O_DELAY, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_DELAY }; #endif #ifdef O_PRIV const struct optdesc opt_o_priv = { "o-priv", "priv", OPT_O_PRIV, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_PRIV }; #endif const struct optdesc opt_o_trunc = { "o-trunc", "trunc", OPT_O_TRUNC, GROUP_OPEN, PH_LATE, TYPE_BOOL, OFUNC_FLAG, O_TRUNC }; #endif /* WITH_OPEN */ #if _WITH_FILE /*! inconsistent name FILE vs. OPEN */ const struct addrdesc addr_open = { "open", 3, xioopen_open, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_REG|GROUP_NAMED|GROUP_OPEN|GROUP_FILE|GROUP_TERMIOS, 0, 0, 0 HELP(":") }; /* open for writing: 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 *fd, unsigned groups, int dummy1, int dummy2, int dummy3) { const char *filename = argv[1]; int rw = (xioflags & XIO_ACCMODE); bool exists; bool opt_unlink_close = false; int result; /* remove old file, or set user/permissions on old file; parse options */ if ((result = _xioopen_named_early(argc, argv, fd, groups, &exists, opts)) < 0) { return result; } retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); if (opt_unlink_close) { if ((fd->stream.unlink_close = strdup(filename)) == NULL) { Error1("strdup(\"%s\"): out of memory", filename); } fd->stream.opt_unlink_close = true; } Notice3("opening %s \"%s\" for %s", filetypenames[(result&S_IFMT)>>12], filename, ddirection[rw]); if ((result = _xioopen_open(filename, rw, opts)) < 0) return result; fd->stream.fd = result; #if WITH_TERMIOS if (Isatty(fd->stream.fd)) { if (Tcgetattr(fd->stream.fd, &fd->stream.savetty) < 0) { Warn2("cannot query current terminal settings on fd %d: %s", fd->stream.fd, strerror(errno)); } else { fd->stream.ttyvalid = true; } } #endif /* WITH_TERMIOS */ applyopts_named(filename, opts, PH_FD); applyopts(fd->stream.fd, opts, PH_FD); applyopts_cloexec(fd->stream.fd, opts); applyopts_fchown(fd->stream.fd, opts); if ((result = _xio_openlate(&fd->stream, opts)) < 0) return result; return 0; } #endif /* _WITH_FILE */ socat-1.7.3.1/xio-system.h0000644000201000020100000000045011453022152015044 0ustar gerhardgerhard/* source: xio-system.h */ /* Copyright Gerhard Rieger 2001 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_system_h_included #define __xio_system_h_included 1 extern const struct addrdesc addr_system; #endif /* !defined(__xio_system_h_included) */ socat-1.7.3.1/xio-ip4.h0000644000201000020100000000114411453022152014215 0ustar gerhardgerhard/* source: xio-ip4.h */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ip4_h_included #define __xio_ip4_h_included 1 extern const struct optdesc opt_ip4_add_membership; int xioparsenetwork_ip4(const char *rangename, struct xiorange *range); extern int xiocheckrange_ip4(struct sockaddr_in *pa, struct xiorange *range); extern int xiosetsockaddrenv_ip4(int idx, char *namebuff, size_t namelen, char *valuebuff, size_t valuelen, struct sockaddr_in *sa, int ipproto); #endif /* !defined(__xio_ip4_h_included) */ socat-1.7.3.1/dalan.h0000644000201000020100000000166511453022151014012 0ustar gerhardgerhard/* source: dalan.h */ /* Copyright Gerhard Rieger 2001 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __dalan_h_included #define __dalan_h_included 1 #include "mytypes.h" /* machine properties and command line options */ struct dalan_opts_s { int c_int; /* natural int size / C int size */ int c_short; /* C short size */ int c_long; /* C long size */ int c_char; /* C char size */ int c_float; /* C float size */ int c_double; /* C double size */ int maxalign; /* maximal alignment (double after char) */ int minalign; /* minimal alignment (char after char) */ int byteorder; /* 0: Motorola, network, big endian; 1: Intel, little endian */ } ; extern struct dalan_opts_s dalan_opts; extern void dalan_init(void); extern struct dalan_opts_s *dalan_props(void); extern int dalan(const char *line, char *data, size_t *p, size_t n); #endif /* !defined(__dalan_h_included) */ socat-1.7.3.1/xio-proxy.c0000644000201000020100000004034112455415361014712 0ustar gerhardgerhard/* source: xio-proxy.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of HTTP proxy CONNECT type */ #include "xiosysincludes.h" #if WITH_PROXY #include "xioopen.h" #include "xio-socket.h" #include "xio-ipapp.h" #include "xio-ascii.h" /* for base64 encoding of authentication */ #include "xio-proxy.h" #define PROXYPORT "8080" static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); 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 }; const struct optdesc opt_proxy_resolve = { "proxy-resolve", "resolve", OPT_PROXY_RESOLVE, GROUP_HTTP, PH_LATE, TYPE_BOOL, OFUNC_SPEC }; const struct optdesc opt_proxy_authorization = { "proxy-authorization", "proxyauth", OPT_PROXY_AUTHORIZATION, GROUP_HTTP, PH_LATE, TYPE_STRING, OFUNC_SPEC }; const struct addrdesc addr_proxy_connect = { "proxy", 3, xioopen_proxy_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_HTTP|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":::") }; /*0#define CONNLEN 40*/ /* "CONNECT 123.156.189.123:65432 HTTP/1.0\r\n\0" */ #define CONNLEN 281 /* "CONNECT <255bytes>:65432 HTTP/1.0\r\n\0" */ /* states during receiving answer */ enum { XIOSTATE_HTTP1, /* 0 or more bytes of first line received, no \r */ XIOSTATE_HTTP2, /* first line received including \r */ XIOSTATE_HTTP3, /* received status and \r\n */ XIOSTATE_HTTP4, /* within header */ XIOSTATE_HTTP5, /* within header, \r */ XIOSTATE_HTTP6, /* received status and 1 or more headers, \r\n */ XIOSTATE_HTTP7, /* received status line, ev. headers, \r\n\r */ XIOSTATE_HTTP8, /* complete answer received */ XIOSTATE_ERROR /* error during HTTP headers */ } ; /* get buflen bytes from proxy server; handles EINTR; returns <0 when error occurs */ static ssize_t xioproxy_recvbytes(struct single *xfd, char *buff, size_t buflen, int level) { ssize_t result; do { /* we need at least buflen bytes... */ result = Read(xfd->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)); return result; } if (result == 0) { Msg(level, "proxy_connect: connection closed by proxy"); } return result; } #define BUFLEN 2048 static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int dummy2, int dummy3) { /* we expect the form: host:host:port */ struct single *xfd = &xxfd->stream; struct opt *opts0 = NULL; struct proxyvars struct_proxyvars = { 0 }, *proxyvars = &struct_proxyvars; /* variables to be filled with address option values */ bool dofork = false; /* */ int pf = PF_UNSPEC; union sockaddr_union us_sa, *us = &us_sa; union sockaddr_union them_sa, *them = &them_sa; socklen_t uslen = sizeof(us_sa); socklen_t themlen = sizeof(them_sa); const char *proxyname; char *proxyport = NULL; const char *targetname, *targetport; int ipproto = IPPROTO_TCP; bool needbind = false; bool lowport = false; int socktype = SOCK_STREAM; int level; int result; if (argc != 4) { Error1("%s: 3 parameters required", argv[0]); 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(-1, opts, PH_INIT); retropt_int(opts, OPT_SO_TYPE, &socktype); retropt_bool(opts, OPT_FORK, &dofork); if (retropt_string(opts, OPT_PROXYPORT, &proxyport) < 0) { if ((proxyport = strdup(PROXYPORT)) == NULL) { errno = ENOMEM; return -1; } } result = _xioopen_proxy_prepare(proxyvars, opts, targetname, targetport); if (result != STAT_OK) return result; result = _xioopen_ipapp_prepare(opts, &opts0, proxyname, proxyport, &pf, ipproto, xfd->para.socket.ip.res_opts[1], xfd->para.socket.ip.res_opts[0], them, &themlen, us, &uslen, &needbind, &lowport, socktype); if (result != STAT_OK) return result; Notice4("opening connection to %s:%u via proxy %s:%s", proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport); do { /* loop over failed connect and proxy connect attempts */ #if WITH_RETRY if (xfd->forever || xfd->retry) { level = E_INFO; } else #endif /* WITH_RETRY */ level = E_ERROR; result = _xioopen_connect(xfd, needbind?(struct sockaddr *)us:NULL, sizeof(*us), (struct sockaddr *)them, themlen, opts, pf, socktype, IPPROTO_TCP, lowport, 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); continue; } #endif /* WITH_RETRY */ default: return result; } applyopts(xfd->fd, opts, PH_ALL); if ((result = _xio_openlate(xfd, opts)) < 0) return result; result = _xioopen_proxy_connect(xfd, 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); continue; } #endif /* WITH_RETRY */ default: return result; } if (dofork) { xiosetchilddied(); /* set SIGCHLD handler */ } #if WITH_RETRY if (dofork) { pid_t pid; int level = E_ERROR; if (xfd->forever || xfd->retry) { level = E_WARN; } while ((pid = xio_fork(false, level)) < 0) { if (xfd->forever || --xfd->retry) { Nanosleep(&xfd->intervall, NULL); continue; } return STAT_RETRYLATER; } if (pid == 0) { /* child process */ xfd->forever = false; xfd->retry = 0; break; } /* parent process */ Close(xfd->fd); Nanosleep(&xfd->intervall, NULL); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); continue; } else #endif /* WITH_RETRY */ { break; } } while (true); /* end of complete open loop - drop out on success */ Notice4("successfully connected to %s:%u via proxy %s:%s", proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport); return 0; } int _xioopen_proxy_prepare(struct proxyvars *proxyvars, struct opt *opts, const char *targetname, const char *targetport) { struct hostent *host; retropt_bool(opts, OPT_IGNORECR, &proxyvars->ignorecr); retropt_bool(opts, OPT_PROXY_RESOLVE, &proxyvars->doresolve); retropt_string(opts, OPT_PROXY_AUTHORIZATION, &proxyvars->authstring); if (proxyvars->doresolve) { /* currently we only resolve to IPv4 addresses. This is in accordance to RFC 2396; however once it becomes clear how IPv6 addresses should be represented in CONNECT commands this code might be extended */ host = Gethostbyname(targetname); if (host == NULL) { int level = E_WARN; /* note: cast is req on AIX: */ Msg2(level, "gethostbyname(\"%s\"): %s", targetname, h_errno == NETDB_INTERNAL ? strerror(errno) : (char *)hstrerror(h_errno)/*0 h_messages[h_errno-1]*/); proxyvars->targetaddr = strdup(targetname); } else { #define LEN 16 /* www.xxx.yyy.zzz\0 */ if ((proxyvars->targetaddr = Malloc(LEN)) == NULL) { return STAT_RETRYLATER; } snprintf(proxyvars->targetaddr, LEN, "%u.%u.%u.%u", (unsigned char)host->h_addr_list[0][0], (unsigned char)host->h_addr_list[0][1], (unsigned char)host->h_addr_list[0][2], (unsigned char)host->h_addr_list[0][3]); #undef LEN } } else { proxyvars->targetaddr = strdup(targetname); } proxyvars->targetport = htons(parseport(targetport, IPPROTO_TCP)); return STAT_OK; } int _xioopen_proxy_connect(struct single *xfd, struct proxyvars *proxyvars, int level) { size_t offset; char request[CONNLEN]; /* HTTP connection request line */ int rv; char buff[BUFLEN+1]; /* for receiving HTTP reply headers */ #if CONNLEN > BUFLEN #error not enough buffer space #endif char textbuff[2*BUFLEN+1]; /* just for sanitizing print data */ char *eol = buff; int state; ssize_t sresult; /* generate proxy request header - points to final target */ rv = snprintf(request, CONNLEN, "CONNECT %s:%u HTTP/1.0\r\n", proxyvars->targetaddr, proxyvars->targetport); if (rv >= CONNLEN || rv < 0) { Error("_xioopen_proxy_connect(): PROXY CONNECT buffer too small"); return -1; } /* send proxy CONNECT request (target addr+port) */ * 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) { 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)); } return STAT_RETRYLATER; } if (proxyvars->authstring) { /* send proxy authentication header */ # define XIOAUTHHEAD "Proxy-authorization: Basic " # define XIOAUTHLEN 27 static const char *authhead = XIOAUTHHEAD; # define HEADLEN 256 char *header, *next; /* ...\r\n\0 */ if ((header = Malloc(XIOAUTHLEN+((strlen(proxyvars->authstring)+2)/3)*4+3)) == NULL) { return -1; } strcpy(header, authhead); next = xiob64encodeline(proxyvars->authstring, strlen(proxyvars->authstring), strchr(header, '\0')); *next = '\0'; Info1("sending \"%s\\r\\n\"", header); *next++ = '\r'; *next++ = '\n'; *next++ = '\0'; if (writefull(xfd->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)); } return STAT_RETRYLATER; } free(header); } Info("sending \"\\r\\n\""); if (writefull(xfd->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)); } return STAT_RETRYLATER; } /* request is kept for later error messages */ *strstr(request, " HTTP") = '\0'; /* receive proxy answer; looks like "HTTP/1.0 200 .*\r\nHeaders..\r\n\r\n" */ /* socat version 1 depends on a valid fd for data transfer; address therefore cannot buffer data. So, to prevent reading beyond the end of the answer headers, only single bytes are read. puh. */ state = XIOSTATE_HTTP1; 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); if (sresult <= 0) { state = XIOSTATE_ERROR; break; /* leave read cycles */ } switch (state) { case XIOSTATE_HTTP1: /* 0 or more bytes of first line received, no '\r' yet */ if (*(buff+offset) == '\r') { eol = buff+offset; state = XIOSTATE_HTTP2; break; } if (proxyvars->ignorecr && *(buff+offset) == '\n') { eol = buff+offset; state = XIOSTATE_HTTP3; break; } break; case XIOSTATE_HTTP2: /* first line received including '\r' */ if (*(buff+offset) != '\n') { state = XIOSTATE_HTTP1; break; } state = XIOSTATE_HTTP3; break; case XIOSTATE_HTTP3: /* received status (first line) and "\r\n" */ if (*(buff+offset) == '\r') { state = XIOSTATE_HTTP7; break; } if (proxyvars->ignorecr && *(buff+offset) == '\n') { state = XIOSTATE_HTTP8; break; } state = XIOSTATE_HTTP4; break; case XIOSTATE_HTTP4: /* within header */ if (*(buff+offset) == '\r') { eol = buff+offset; state = XIOSTATE_HTTP5; break; } if (proxyvars->ignorecr && *(buff+offset) == '\n') { eol = buff+offset; state = XIOSTATE_HTTP6; break; } break; case XIOSTATE_HTTP5: /* within header, '\r' received */ if (*(buff+offset) != '\n') { state = XIOSTATE_HTTP4; break; } state = XIOSTATE_HTTP6; break; case XIOSTATE_HTTP6: /* received status (first line) and 1 or more headers, "\r\n" */ if (*(buff+offset) == '\r') { state = XIOSTATE_HTTP7; break; } if (proxyvars->ignorecr && *(buff+offset) == '\n') { state = XIOSTATE_HTTP8; break; } state = XIOSTATE_HTTP4; break; case XIOSTATE_HTTP7: /* received status (first line), 0 or more headers, "\r\n\r" */ if (*(buff+offset) == '\n') { state = XIOSTATE_HTTP8; break; } if (*(buff+offset) == '\r') { if (proxyvars->ignorecr) { break; /* ignore it, keep waiting for '\n' */ } else { state = XIOSTATE_HTTP5; } break; } state = XIOSTATE_HTTP4; break; } ++offset; /* end of status line reached */ if (state == XIOSTATE_HTTP3) { char *ptr; /* set a terminating null - on or after CRLF? */ *(buff+offset) = '\0'; * xiosanitize(buff, Min(offset, (sizeof(textbuff)-1)>>1), textbuff) = '\0'; Info1("proxy_connect: received answer \"%s\"", textbuff); *eol = '\0'; * xiosanitize(buff, Min(strlen(buff), (sizeof(textbuff)-1)>>1), textbuff) = '\0'; if (strncmp(buff, "HTTP/1.0 ", 9) && strncmp(buff, "HTTP/1.1 ", 9)) { /* invalid answer */ Msg1(level, "proxy: invalid answer \"%s\"", textbuff); return STAT_RETRYLATER; } ptr = buff+9; /* skip multiple spaces */ while (*ptr == ' ') ++ptr; /* HTTP answer */ if (strncmp(ptr, "200", 3)) { /* not ok */ /* CERN: "HTTP/1.0 200 Connection established" "HTTP/1.0 400 Invalid request "CONNECT 10.244.9.3:8080 HTTP/1.0" (unknown method)" "HTTP/1.0 403 Forbidden - by rule" "HTTP/1.0 407 Proxy Authentication Required" Proxy-Authenticate: Basic realm="Squid proxy-caching web server" > 50 72 6f 78 79 2d 61 75 74 68 6f 72 69 7a 61 74 Proxy-authorizat > 69 6f 6e 3a 20 42 61 73 69 63 20 61 57 4e 6f 63 ion: Basic aWNoc > 32 56 73 59 6e 4e 30 4f 6e 4e 30 63 6d 56 75 5a 2VsYnN0OnN0cmVuZ > 32 64 6c 61 47 56 70 62 51 3d 3d 0d 0a 2dlaGVpbQ==.. b64encode("username:password") "HTTP/1.0 500 Can't connect to host" */ /* Squid: "HTTP/1.0 400 Bad Request" "HTTP/1.0 403 Forbidden" "HTTP/1.0 503 Service Unavailable" interesting header: "X-Squid-Error: ERR_CONNECT_FAIL 111" */ /* Apache: "HTTP/1.0 400 Bad Request" "HTTP/1.1 405 Method Not Allowed" */ /* WTE: "HTTP/1.1 200 Connection established" "HTTP/1.1 404 Host not found or not responding, errno: 79" "HTTP/1.1 404 Host not found or not responding, errno: 32" "HTTP/1.1 404 Host not found or not responding, errno: 13" */ /* IIS: "HTTP/1.1 404 Object Not Found" */ ptr += 3; while (*ptr == ' ') ++ptr; Msg2(level, "%s: %s", request, ptr); return STAT_RETRYLATER; } /* ok!! */ /* "HTTP/1.0 200 Connection established" */ /*Info1("proxy: \"%s\"", textbuff+13);*/ offset = 0; } else if (state == XIOSTATE_HTTP6) { /* end of a header line reached */ char *endp; /* set a terminating null */ *(buff+offset) = '\0'; endp = xiosanitize(buff, Min(offset, (sizeof(textbuff)-1)>>1), textbuff); *endp = '\0'; Info1("proxy_connect: received header \"%s\"", textbuff); offset = 0; } } while (state != XIOSTATE_HTTP8 && offset < BUFLEN); if (state == XIOSTATE_ERROR) { return STAT_RETRYLATER; } if (offset >= BUFLEN) { Msg1(level, "proxy answer exceeds %d bytes, aborting", BUFLEN); return STAT_NORETRY; } return STAT_OK; } #endif /* WITH_PROXY */ socat-1.7.3.1/xio-readline.h0000644000201000020100000000120511453022152015302 0ustar gerhardgerhard/* source: xio-readline.h */ /* Copyright Gerhard Rieger 2002, 2003 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_readline_h_included #define __xio_readline_h_included 1 extern const struct addrdesc addr_readline; extern const struct optdesc opt_history_file; extern const struct optdesc opt_prompt; extern const struct optdesc opt_noprompt; extern const struct optdesc opt_noecho; extern ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz);extern void xioscan_readline(struct single *pipe, const void *buff, size_t bytes); #endif /* !defined(__xio_readline_h_included) */ socat-1.7.3.1/xio-gopen.h0000644000201000020100000000044311453022152014632 0ustar gerhardgerhard/* source: xio-gopen.h */ /* Copyright Gerhard Rieger 2001 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_gopen_h_included #define __xio_gopen_h_included 1 extern const struct addrdesc addr_gopen; #endif /* !defined(__xio_gopen_h_included) */ socat-1.7.3.1/xio-ext2.c0000644000201000020100000001047611453022152014406 0ustar gerhardgerhard/* source: xio-ext2.c */ /* Copyright Gerhard Rieger 2005-2006 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for handling Linux ext2fs options they can also be set with chattr(1) and viewed with lsattr(1) */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-ext2.h" #if WITH_EXT2 /****** FD options ******/ #ifdef EXT2_SECRM_FL /* secure deletion, chattr 's' */ const struct optdesc opt_ext2_secrm = { "ext2-secrm", "secrm", OPT_EXT2_SECRM, GROUP_REG, PH_FD, TYPE_BOOL, OFUNC_IOCTL_MASK_LONG, EXT2_IOC_GETFLAGS, EXT2_IOC_SETFLAGS, EXT2_SECRM_FL }; #endif /* EXT2_SECRM_FL */ #ifdef EXT2_UNRM_FL /* undelete, chattr 'u' */ const struct optdesc opt_ext2_unrm = { "ext2-unrm", "unrm", OPT_EXT2_UNRM, GROUP_REG, PH_FD, TYPE_BOOL, OFUNC_IOCTL_MASK_LONG, EXT2_IOC_GETFLAGS, EXT2_IOC_SETFLAGS, EXT2_UNRM_FL }; #endif /* EXT2_UNRM_FL */ #ifdef EXT2_COMPR_FL /* compress file, chattr 'c' */ const struct optdesc opt_ext2_compr = { "ext2-compr", "compr", OPT_EXT2_COMPR, GROUP_REG, PH_FD, TYPE_BOOL, OFUNC_IOCTL_MASK_LONG, EXT2_IOC_GETFLAGS, EXT2_IOC_SETFLAGS, EXT2_COMPR_FL }; #endif /* EXT2_COMPR_FL */ #ifdef EXT2_SYNC_FL /* synchronous update, chattr 'S' */ const struct optdesc opt_ext2_sync = { "ext2-sync", "sync", OPT_EXT2_SYNC, GROUP_REG, PH_FD, TYPE_BOOL, OFUNC_IOCTL_MASK_LONG, EXT2_IOC_GETFLAGS, EXT2_IOC_SETFLAGS, EXT2_SYNC_FL }; #endif /* EXT2_SYNC_FL */ #ifdef EXT2_IMMUTABLE_FL /* immutable file, chattr 'i' */ const struct optdesc opt_ext2_immutable = { "ext2-immutable", "immutable", OPT_EXT2_IMMUTABLE, GROUP_REG, PH_FD, TYPE_BOOL, OFUNC_IOCTL_MASK_LONG, EXT2_IOC_GETFLAGS, EXT2_IOC_SETFLAGS, EXT2_IMMUTABLE_FL }; #endif /* EXT2_IMMUTABLE_FL */ #ifdef EXT2_APPEND_FL /* writes to file may only append, chattr 'a' */ const struct optdesc opt_ext2_append = { "ext2-append", "append", OPT_EXT2_APPEND, GROUP_REG, PH_FD, TYPE_BOOL, OFUNC_IOCTL_MASK_LONG, EXT2_IOC_GETFLAGS, EXT2_IOC_SETFLAGS, EXT2_APPEND_FL }; #endif /* EXT2_APPEND_FL */ #ifdef EXT2_NODUMP_FL /* do not dump file, chattr 'd' */ const struct optdesc opt_ext2_nodump = { "ext2-nodump", "nodump", OPT_EXT2_NODUMP, GROUP_REG, PH_FD, TYPE_BOOL, OFUNC_IOCTL_MASK_LONG, EXT2_IOC_GETFLAGS, EXT2_IOC_SETFLAGS, EXT2_NODUMP_FL }; #endif /* EXT2_NODUMP_FL */ #ifdef EXT2_NOATIME_FL /* do not update atime, chattr 'A' */ const struct optdesc opt_ext2_noatime = { "ext2-noatime", "noatime", OPT_EXT2_NOATIME, GROUP_REG, PH_FD, TYPE_BOOL, OFUNC_IOCTL_MASK_LONG, EXT2_IOC_GETFLAGS, EXT2_IOC_SETFLAGS, EXT2_NOATIME_FL }; #endif /* EXT2_NOATIME_FL */ /* EXT2_DIRTY_FL ??? */ /* EXT2_COMPRBLK_FL one ore more compress clusters */ /* EXT2_NOCOMPR_FL access raw compressed data */ /* EXT2_ECOMPR_FL compression error */ /* EXT2_BTREE_FL btree format dir */ /* EXT2_INDEX_FL hash indexed directory */ /* EXT2_IMAGIC ??? */ #ifdef EXT2_JOURNAL_DATA_FL /* file data should be journaled, chattr 'j' */ const struct optdesc opt_ext2_journal_data = { "ext2-journal-data", "journal-data", OPT_EXT2_JOURNAL_DATA, GROUP_REG, PH_FD, TYPE_BOOL, OFUNC_IOCTL_MASK_LONG, EXT2_IOC_GETFLAGS, EXT2_IOC_SETFLAGS, EXT2_JOURNAL_DATA_FL }; #endif /* EXT2_JOURNAL_DATA_FL */ #ifdef EXT2_NOTAIL_FL /* file tail should not be merged, chattr 't' */ const struct optdesc opt_ext2_notail = { "ext2-notail", "notail", OPT_EXT2_NOTAIL, GROUP_REG, PH_FD, TYPE_BOOL, OFUNC_IOCTL_MASK_LONG, EXT2_IOC_GETFLAGS, EXT2_IOC_SETFLAGS, EXT2_NOTAIL_FL }; #endif /* EXT2_NOTAIL_FL */ #ifdef EXT2_DIRSYNC_FL /* synchronous directory modifications, chattr 'D' */ const struct optdesc opt_ext2_dirsync = { "ext2-dirsync", "dirsync", OPT_EXT2_DIRSYNC, GROUP_REG, PH_FD, TYPE_BOOL, OFUNC_IOCTL_MASK_LONG, EXT2_IOC_GETFLAGS, EXT2_IOC_SETFLAGS, EXT2_DIRSYNC_FL }; #endif /* EXT2_DIRSYNC_FL */ #ifdef EXT2_TOPDIR_FL /* top of directory hierarchies, chattr 'T' */ const struct optdesc opt_ext2_topdir = { "ext2-topdir", "topdir", OPT_EXT2_TOPDIR, GROUP_REG, PH_FD, TYPE_BOOL, OFUNC_IOCTL_MASK_LONG, EXT2_IOC_GETFLAGS, EXT2_IOC_SETFLAGS, EXT2_TOPDIR_FL }; #endif /* EXT2_TOPDIR_FL */ /* EXTENTS inode uses extents */ #endif /* WITH_EXT2 */ socat-1.7.3.1/mytypes.h0000644000201000020100000000076112460670272014455 0ustar gerhardgerhard/* source: mytypes.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __mytypes_h_included #define __mytypes_h_included 1 /* some types and macros I miss in C89 */ #ifndef HAVE_TYPE_BOOL # undef bool typedef enum { false, true } bool; #endif #ifndef Min #define Min(x,y) ((x)<=(y)?(x):(y)) #endif #ifndef Max #define Max(x,y) ((x)>=(y)?(x):(y)) #endif #define SOCKADDR_MAX UNIX_PATH_MAX #endif /* __mytypes_h_included */ socat-1.7.3.1/xio-ipapp.c0000644000201000020100000002024112460670272014637 0ustar gerhardgerhard/* source: xio-ipapp.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for TCP and UDP related options */ #include "xiosysincludes.h" #if WITH_TCP || WITH_UDP #include "xioopen.h" #include "xio-socket.h" #include "xio-ip.h" #include "xio-listen.h" #include "xio-ip6.h" #include "xio-ipapp.h" const struct optdesc opt_sourceport = { "sourceport", "sp", OPT_SOURCEPORT, GROUP_IPAPP, PH_LATE,TYPE_2BYTE, OFUNC_SPEC }; /*const struct optdesc opt_port = { "port", NULL, OPT_PORT, GROUP_IPAPP, PH_BIND, TYPE_USHORT, OFUNC_SPEC };*/ const struct optdesc opt_lowport = { "lowport", NULL, OPT_LOWPORT, GROUP_IPAPP, PH_LATE, TYPE_BOOL, OFUNC_SPEC }; #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, unsigned groups, int socktype, int ipproto, int pf) { struct single *xfd = &xxfd->stream; struct opt *opts0 = NULL; const char *hostname = argv[1], *portname = argv[2]; bool dofork = false; union sockaddr_union us_sa, *us = &us_sa; union sockaddr_union them_sa, *them = &them_sa; socklen_t uslen = sizeof(us_sa); socklen_t themlen = sizeof(them_sa); bool needbind = false; bool lowport = false; int level; int result; if (argc != 3) { Error2("%s: wrong number of parameters (%d instead of 2)", argv[0], argc-1); } xfd->howtoend = END_SHUTDOWN; if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); retropt_bool(opts, OPT_FORK, &dofork); if (_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto, xfd->para.socket.ip.res_opts[1], xfd->para.socket.ip.res_opts[0], them, &themlen, us, &uslen, &needbind, &lowport, socktype) != STAT_OK) { return STAT_NORETRY; } if (dofork) { xiosetchilddied(); /* set SIGCHLD handler */ } if (xioopts.logopt == 'm') { Info("starting connect loop, switching to syslog"); diag_set('y', xioopts.syslogfac); xioopts.logopt = 'y'; } else { Info("starting connect loop"); } do { /* loop over retries and forks */ #if WITH_RETRY if (xfd->forever || xfd->retry) { level = E_INFO; } else #endif /* WITH_RETRY */ level = E_ERROR; result = _xioopen_connect(xfd, needbind?(struct sockaddr *)us:NULL, uslen, (struct sockaddr *)them, themlen, opts, pf, socktype, ipproto, lowport, level); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: if (xfd->forever || xfd->retry) { --xfd->retry; if (result == STAT_RETRYLATER) { Nanosleep(&xfd->intervall, NULL); } dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL); continue; } return STAT_NORETRY; #endif /* WITH_RETRY */ default: free(opts0);free(opts); return result; } #if WITH_RETRY if (dofork) { pid_t pid; int level = E_ERROR; if (xfd->forever || xfd->retry) { level = E_WARN; /* most users won't expect a problem here, so Notice is too weak */ } while ((pid = xio_fork(false, level)) < 0) { if (xfd->forever || --xfd->retry) { Nanosleep(&xfd->intervall, NULL); continue; } free(opts0); return STAT_RETRYLATER; } if (pid == 0) { /* child process */ xfd->forever = false; xfd->retry = 0; break; } /* parent process */ Close(xfd->fd); /* with and without retry */ Nanosleep(&xfd->intervall, NULL); dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL); continue; /* with next socket() bind() connect() */ } else #endif /* WITH_RETRY */ { break; } } while (true); /* only "active" process breaks (master without fork, or child) */ if ((result = _xio_openlate(xfd, opts)) < 0) { free(opts0);free(opts); return result; } free(opts0);free(opts); return 0; } /* returns STAT_OK on success or some other value on failure applies and consumes the following options: PH_EARLY OPT_PROTOCOL_FAMILY, OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT */ int _xioopen_ipapp_prepare(struct opt *opts, struct opt **opts0, const char *hostname, const char *portname, int *pf, int protocol, unsigned long res_opts0, unsigned long res_opts1, union sockaddr_union *them, socklen_t *themlen, union sockaddr_union *us, socklen_t *uslen, bool *needbind, bool *lowport, int socktype) { uint16_t port; char infobuff[256]; int result; retropt_socket_pf(opts, pf); if ((result = xiogetaddrinfo(hostname, portname, *pf, socktype, protocol, (union sockaddr_union *)them, themlen, res_opts0, res_opts1 )) != STAT_OK) { return STAT_NORETRY; /*! STAT_RETRYLATER? */ } if (*pf == PF_UNSPEC) { *pf = them->soa.sa_family; } applyopts(-1, opts, PH_EARLY); /* 3 means: IP address AND port accepted */ if (retropt_bind(opts, *pf, socktype, protocol, (struct sockaddr *)us, uslen, 3, res_opts0, res_opts1) != STAT_NOACTION) { *needbind = true; } else { switch (*pf) { #if WITH_IP4 case PF_INET: socket_in_init(&us->ip4); *uslen = sizeof(us->ip4); break; #endif /* WITH_IP4 */ #if WITH_IP6 case PF_INET6: socket_in6_init(&us->ip6); *uslen = sizeof(us->ip6); break; #endif /* WITH_IP6 */ } } if (retropt_2bytes(opts, OPT_SOURCEPORT, &port) >= 0) { switch (*pf) { #if WITH_IP4 case PF_INET: us->ip4.sin_port = htons(port); break; #endif /* WITH_IP4 */ #if WITH_IP6 case PF_INET6: us->ip6.sin6_port = htons(port); break; #endif /* WITH_IP6 */ default: Error("unsupported protocol family"); } *needbind = true; } retropt_bool(opts, OPT_LOWPORT, lowport); *opts0 = copyopts(opts, GROUP_ALL); Notice1("opening connection to %s", sockaddr_info((struct sockaddr *)them, *themlen, infobuff, sizeof(infobuff))); return STAT_OK; } #endif /* WITH_IP4 */ #if WITH_TCP && WITH_LISTEN /* applies and consumes the following options: OPT_PROTOCOL_FAMILY, OPT_BIND */ int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0, const char *portname, int *pf, int ipproto, unsigned long res_opts0, unsigned long res_opts1, union sockaddr_union *us, socklen_t *uslen, int socktype) { char *bindname = NULL; int result; retropt_socket_pf(opts, pf); retropt_string(opts, OPT_BIND, &bindname); if ((result = xiogetaddrinfo(bindname, portname, *pf, socktype, ipproto, (union sockaddr_union *)us, uslen, res_opts0, res_opts1)) != STAT_OK) { /*! STAT_RETRY? */ return result; } *opts0 = copyopts(opts, GROUP_ALL); return STAT_OK; } /* 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 *fd, unsigned groups, int socktype, int ipproto, int pf) { struct opt *opts0 = NULL; 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); } if (pf == PF_UNSPEC) { #if WITH_IP4 && WITH_IP6 pf = xioopts.default_ip=='6'?PF_INET6:PF_INET; #elif WITH_IP6 pf = PF_INET6; #else pf = PF_INET; #endif } fd->stream.howtoend = END_SHUTDOWN; if (applyopts_single(&fd->stream, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); applyopts(-1, opts, PH_EARLY); if (_xioopen_ipapp_listen_prepare(opts, &opts0, argv[1], &pf, ipproto, fd->stream.para.socket.ip.res_opts[1], fd->stream.para.socket.ip.res_opts[0], us, &uslen, socktype) != STAT_OK) { return STAT_NORETRY; } if ((result = xioopen_listen(&fd->stream, xioflags, (struct sockaddr *)us, uslen, opts, opts0, pf, socktype, ipproto)) != 0) return result; return 0; } #endif /* WITH_IP4 && WITH_TCP && WITH_LISTEN */ #endif /* WITH_TCP || WITH_UDP */ socat-1.7.3.1/xio-process.c0000644000201000020100000000665312455415361015217 0ustar gerhardgerhard/* source: xio-process.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file handles process related addresses options */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-process.h" /****** process related options ******/ const struct optdesc opt_setgid_early= { "setgid-early",NULL, OPT_SETGID_EARLY,GROUP_PROCESS, PH_EARLY, TYPE_GIDT, OFUNC_SPEC }; const struct optdesc opt_setgid = { "setgid", NULL, OPT_SETGID, GROUP_PROCESS, PH_LATE2, TYPE_GIDT, OFUNC_SPEC }; const struct optdesc opt_setuid_early= { "setuid-early",NULL, OPT_SETUID_EARLY,GROUP_PROCESS, PH_EARLY, TYPE_UIDT, OFUNC_SPEC }; const struct optdesc opt_setuid = { "setuid", NULL, OPT_SETUID, GROUP_PROCESS, PH_LATE2, TYPE_UIDT, OFUNC_SPEC }; const struct optdesc opt_substuser_early = { "substuser-early", "su-e", OPT_SUBSTUSER_EARLY, GROUP_PROCESS, PH_EARLY, TYPE_UIDT, OFUNC_SPEC }; const struct optdesc opt_substuser = { "substuser", "su", OPT_SUBSTUSER, GROUP_PROCESS, PH_LATE2, TYPE_UIDT, OFUNC_SPEC }; #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT) const struct optdesc opt_substuser_delayed = { "substuser-delayed", "su-d", OPT_SUBSTUSER_DELAYED, GROUP_PROCESS, PH_INIT, TYPE_UIDT, OFUNC_SPEC }; #endif const struct optdesc opt_chroot_early = { "chroot-early", NULL, OPT_CHROOT_EARLY, GROUP_PROCESS, PH_EARLY, TYPE_STRING, OFUNC_SPEC }; const struct optdesc opt_chroot = { "chroot", NULL, OPT_CHROOT, GROUP_PROCESS, PH_LATE, TYPE_STRING, OFUNC_SPEC }; const struct optdesc opt_setsid = { "setsid", "sid", OPT_SETSID, GROUP_PROCESS, PH_LATE, TYPE_BOOL, OFUNC_SPEC }; const struct optdesc opt_setpgid = { "setpgid", "pgid",OPT_SETPGID, GROUP_FORK, PH_LATE, TYPE_INT, OFUNC_SPEC }; /* for option substuser-delayed, save info for later application */ bool delayeduser = false; uid_t delayeduser_uid; /* numeric user id to switch to */ gid_t delayeduser_gid; /* numeric group id to switch to */ gid_t delayeduser_gids[NGROUPS]; /* num.supplementary group ids */ int delayeduser_ngids; /* number of suppl. gids */ char *delayeduser_name; /* name of user to switch to */ char *delayeduser_dir; /* home directory of user to switch to */ char *delayeduser_shell; /* login shell of user to switch to */ int _xioopen_setdelayeduser(void) { if (delayeduser) { #if HAVE_SETGROUPS if ((Setgroups(delayeduser_ngids, delayeduser_gids)) != 0) { Error3("setgroups(%d, %p): %s", delayeduser_ngids, delayeduser_gids, strerror(errno)); } #endif /* HAVE_SETGROUPS */ if (Setgid(delayeduser_gid) < 0) { Error2("setgid("F_gid"): %s", delayeduser_gid, strerror(errno)); } if (Setuid(delayeduser_uid) < 0) { Error2("setuid("F_uid"): %s", delayeduser_uid, strerror(errno)); } #if 1 if (setenv("USER", delayeduser_name, 1) < 0) Error1("setenv(\"USER\", \"%s\", 1): insufficient space", delayeduser_name); if (setenv("LOGNAME", delayeduser_name, 1) < 0) Error1("setenv(\"LOGNAME\", \"%s\", 1): insufficient space", delayeduser_name); if (setenv("HOME", delayeduser_dir, 1) < 0) Error1("setenv(\"HOME\", \"%s\", 1): insufficient space", delayeduser_dir); if (setenv("SHELL", delayeduser_shell, 1) < 0) Error1("setenv(\"SHELL\", \"%s\", 1): insufficient space", delayeduser_shell); #endif delayeduser = false; } return 0; } socat-1.7.3.1/socat_buildscript_for_android.sh0000755000201000020100000000677312455415361021225 0ustar gerhardgerhard#!/bin/sh # Customize these parameters according to your environment ANDROID_NDK="${HOME}/bin/android-ndk-r6b" # Check for parameters if [ ! -d "${ANDROID_NDK}" ]; then echo "Android NDK not found in ${ANDROID_NDK}, please edit $0 to fix it." exit 1 fi if [ ! -e "${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh" ]; then echo "Your Android NDK is not compatible (make-standalone-toolchain.sh not found)." echo "Android NDK r6b is known to work." exit 1 fi # Extract the Android toolchain from NDK ANDROID_PLATFORM="android-3" ROOT="`pwd`" OUT="${ROOT}/out" ${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \ --ndk-dir="${ANDROID_NDK}" \ --platform="${ANDROID_PLATFORM}" \ --install-dir="${OUT}/toolchain" \ || exit 1 # Remove resolv.h because it is quite unusable as is rm ${OUT}/toolchain/sysroot/usr/include/resolv.h # Create configure script cd ${ROOT} autoconf || exit 1 # Create config.h and Makefile cd ${OUT} ${ROOT}/configure \ --host \ --disable-openssl \ --disable-unix \ CC="${OUT}/toolchain/bin/arm-linux-androideabi-gcc" \ || exit 1 # Replace misconfigured values in config.h and enable PTY functions mv config.h config.old cat config.old \ | sed 's/CRDLY_SHIFT.*/CRDLY_SHIFT 9/' \ | sed 's/TABDLY_SHIFT.*/TABDLY_SHIFT 11/' \ | sed 's/CSIZE_SHIFT.*/CSIZE_SHIFT 4/' \ | sed 's/\/\* #undef HAVE_OPENPTY \*\//#define HAVE_OPENPTY 1/' \ | sed 's/\/\* #undef HAVE_GRANTPT \*\//#define HAVE_GRANTPT 1/' \ > config.h # Enable openpty() in Makefile mv Makefile Makefile.old cat Makefile.old | sed 's/error.c/error.c openpty.c/' > Makefile # Provide openpty.c cat >openpty.c <, 1998. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include #include #include #include #include #include #include #include #include #define _PATH_DEVPTMX "/dev/ptmx" int openpty (int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp) { char buf[PATH_MAX]; int master, slave; master = open(_PATH_DEVPTMX, O_RDWR); if (master == -1) return -1; if (grantpt(master)) goto fail; if (unlockpt(master)) goto fail; if (ptsname_r(master, buf, sizeof buf)) goto fail; slave = open(buf, O_RDWR | O_NOCTTY); if (slave == -1) goto fail; /* XXX Should we ignore errors here? */ if (termp) tcsetattr(slave, TCSAFLUSH, termp); if (winp) ioctl(slave, TIOCSWINSZ, winp); *amaster = master; *aslave = slave; if (name != NULL) strcpy(name, buf); return 0; fail: close(master); return -1; } EOF # Compile make socat || exit 1 # Done echo "Build finished, socat has been generated successfuly in out/socat" socat-1.7.3.1/xio-proxy.h0000644000201000020100000000157711453022152014714 0ustar gerhardgerhard/* source: xio-proxy.h */ /* Copyright Gerhard Rieger 2002-2006 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_proxy_h_included #define __xio_proxy_h_included 1 struct proxyvars { bool ignorecr; bool doresolve; char *authstring; char *targetaddr; /* name/address of host, in malloced string */ uint16_t targetport; } ; extern const struct optdesc opt_proxyport; extern const struct optdesc opt_ignorecr; extern const struct optdesc opt_proxy_resolve; extern const struct optdesc opt_proxy_authorization; extern const struct addrdesc addr_proxy_connect; int _xioopen_proxy_prepare(struct proxyvars *proxyvars, struct opt *opts, const char *targetname, const char *targetport); int _xioopen_proxy_connect(struct single *xfd, struct proxyvars *proxyvars, int level); #endif /* !defined(__xio_proxy_h_included) */ socat-1.7.3.1/xiohelp.h0000644000201000020100000000053011453022152014372 0ustar gerhardgerhard/* source: xiohelp.h */ /* Copyright Gerhard Rieger 2001 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xiohelp_h_included #define __xiohelp_h_included 1 extern int xioopenhelp(FILE *of, int level /* 0..only addresses, 1..and options */ ); #endif /* !defined(__xiohelp_h_included) */ socat-1.7.3.1/ftp.sh0000755000201000020100000001014011453022152013677 0ustar gerhardgerhard#! /bin/sh # source: ftp.sh # Copyright Gerhard Rieger 2001-2006 # Published under the GNU General Public License V.2, see file COPYING # example how to write a shell script that communicates with stdio on the front # end and with a socat address on the back end # usage: # ftp.sh [opts] server directory/ # show directory contents on stdout # ftp.sh [opts] server file # print file contents to stdout # opts: # -socks socksserver # use given socks server, port 1080 # -proxy proxyserver # use given proxy server, port 8080 # # must be http proxy that accepts CONNECT # # method to ports 21 and >=1024 # -user username # default: "ftp" # -passwd password # default: "anonymous@domain.org" # -t # shell script trace+debug # -d # debug on control connection (use up to 4 times) # -D # debug on data connection (use up to 4 times) # -b # block size for data connection # -v # verbose # -l* # socat logging options # example: # ftp.sh -v -d -d -D -D -D -b 65536 -proxy proxy ftp.ftp.org /README >README user="ftp" passwd="anonymous@domain.org" #method="socks4:socks" # socks4 is address spec, socks is socks server name method=tcp addropts= # socat options SO1= SO2= while :; do case "$1" in -socks|-socks4) shift; case "$1" in *:*) method="socks4:${1%%:*}"; addropts="socksport=${1#*:}" ;; *) method="socks4:$1" ;; esac ;; -socks4a) shift; case "$1" in *:*) method="socks4a:${1%%:*}"; addropts="socksport=${1#*:}" ;; *) method="socks4a:$1" ;; esac ;; -proxy) shift; case "$1" in *:*) method="proxy:${1%%:*}"; addropts="proxyport=${1#*:}" ;; *) method="proxy:$1" ;; esac ;; -user) shift; user="$1" ;; -passwd) shift; passwd="$1" ;; -t) set -vx ;; -d) SO1="$SO1 -d" ;; -D) SO2="$SO2 -d" ;; -b) SO2="$SO2 -b $2"; shift ;; -v) SO1="$SO1 -v" ;; -l*) SO1="$SO1 $1"; SO2="$SO2 $1" ;; -*) echo "unknown option \"$1\"" >&2; exit 1;; *) break ;; esac shift done export SO2 server="$1" dir="$2" echo "addr=$method:$server:21,$addropts"; exit ### this is the central part to establish communication with socat ### ### copy these lines to make new communication shell scripts TMPDIR=$(if [ -x /bin/mktemp ]; then /bin/mktemp -d /tmp/$USER/FTPSH.XXXXXX else (umask 077; d=/tmp/$USER/FTPSH.$$; mkdir $d; echo $d) fi) TO="$TMPDIR/to"; FROM="$TMPDIR/from" socat $SO1 fifo:$TO,nonblock,ignoreeof!!fifo:$FROM $method:$server:21,$addropts & S1=$! while ! [ -p "$TO" -a -p "$FROM" ]; do sleep 1; done exec 4>$TMPDIR/to 3<$TMPDIR/from trap "S1=" 17 #trap "echo cleaning up...>&2; rm -r $TMPDIR; [ -n "$S1" ] && kill $S1" 0 3 trap "rm -r $TMPDIR" 0 3 ### here the central part ends # this function waits for a complete server message, checks if its status # is in the permitted range (terminates session if not), and returns. ftp_chat () { local cmd="$1" local errlevel="$2"; [ -z "$errlevel" ] && errlevel=300 if [ -n "$cmd" ]; then echo "$cmd" >&4; fi while read status message <&3; ( case "$status" in [0-9][0-9][0-9]-*) exit 0;; [0-9][0-9][0-9]*) exit 1;; *) exit 1;; esac ) do :; done #echo "got \"$status $message\"" >&2 if [ -z "$status" ]; then echo ftp data connection failed >&2; exit; fi if [ "$status" -ge "$errlevel" ]; then echo $message >&2 echo "QUIT" >&4; exit 1 fi set +vx } # wait for server greeting ftp_chat ftp_chat "USER $user" 400 ftp_chat "PASS $passwd" #ftp_chat "CWD $dir" case "$dir" in */) ftp_chat "TYPE A" ;; *) ftp_chat "TYPE I" ;; esac echo "PASV" >&4; read status message <&3 info=$(expr "$message" : '.*[^0-9]\([0-9]*,[0-9]*,[0-9]*,[0-9]*,[0-9]*,[0-9]*\).*') echo $info |tr ',' ' ' |(read i1 i2 i3 i4 p1 p2 addr=$i1.$i2.$i3.$i4 port=$(echo "256*$p1+$p2" |bc) #echo $addr:$port trap : 20 # open data connection and transfer data socat -u $SO2 $method:$server:$port,$addropts - ) & S2=$! case "$dir" in */) ftp_chat "NLST $dir" ;; #*/) ftp_chat "LIST $dir" ;; *) ftp_chat "RETR $dir" ;; esac case "$status" in [45]*) kill $S2;; esac #echo "waiting for process $S2 to terminate" >&2 wait $S2 ftp_chat ftp_chat "QUIT" #echo "waiting for process $S1 to terminate" >&2 wait $S1 exit socat-1.7.3.1/procan.c0000644000201000020100000001243012455415361014214 0ustar gerhardgerhard/* source: procan.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* the subroutine procan makes a "PROCess ANalysis". It gathers information about the process environment it is running in without modifying its state (almost). */ #include "xiosysincludes.h" #include "mytypes.h" #include "compat.h" #include "error.h" #include "sycls.h" #include "sysutils.h" #include "filan.h" #include #include "procan.h" /* dirty workaround so we dont get an error on AIX when getting linked with libwrap */ int allow_severity, deny_severity; int procan(FILE *outfile) { /*filan(0, outfile);*/ /* controlling terminal */ fprintf(outfile, "process id = "F_pid"\n", Getpid()); fprintf(outfile, "process parent id = "F_pid"\n", Getppid()); { int fd; if ((fd = Open("/dev/tty", O_NOCTTY, 0)) < 0) { fprintf(outfile, "controlling terminal: -\n"); } else { #if 1 fprintf(outfile, "controlling terminal: \"%s\"\n", Ttyname(fd)); #else char procpath[PATH_MAX], devpath[PATH_MAX+1]; int devlen; sprintf(procpath, "/proc/"F_pid"/fd/%d", Getpid(), 0 /*! fd*/); if ((devlen = Readlink(procpath, devpath, sizeof(devpath))) < 0) { ; } else { devpath[devlen] = '\0'; fprintf(outfile, "controlling terminal: \"%s\"\n", devpath); } #endif } } fprintf(outfile, "process group id = "F_pid"\n", Getpgrp()); #if HAVE_GETSID fprintf(outfile, "process session id = "F_pid"\n", Getsid(0)); #endif fprintf(outfile, "process group id if fg process / stdin = "F_pid"\n", Tcgetpgrp(0)); fprintf(outfile, "process group id if fg process / stdout = "F_pid"\n", Tcgetpgrp(1)); fprintf(outfile, "process group id if fg process / stderr = "F_pid"\n", Tcgetpgrp(2)); { int fd; if ((fd = Open("/dev/tty", O_RDWR, 0600)) >= 0) { fprintf(outfile, "process has a controlling terminal\n"); Close(fd); } else { fprintf(outfile, "process does not have a controlling terminal\n"); } } /* process owner, groups */ fprintf(outfile, "user id = "F_uid"\n", Getuid()); fprintf(outfile, "effective user id = "F_uid"\n", Geteuid()); fprintf(outfile, "group id = "F_gid"\n", Getgid()); fprintf(outfile, "effective group id = "F_gid"\n", Getegid()); { struct rlimit rlim; fprintf(outfile, "\nRESOURCE LIMITS\n"); fprintf(outfile, "resource current maximum\n"); if (getrlimit(RLIMIT_CPU, &rlim) < 0) { Warn2("getrlimit(RLIMIT_CPU, %p): %s", &rlim, strerror(errno)); } else { fprintf(outfile, "cpu time (seconds) %24"F_rlim_max"%24"F_rlim_max"\n", rlim.rlim_cur, rlim.rlim_max); } if (getrlimit(RLIMIT_FSIZE, &rlim) < 0) { Warn2("getrlimit(RLIMIT_FSIZE, %p): %s", &rlim, strerror(errno)); } else { fprintf(outfile, "file size (blocks) %24"F_rlim_max"%24"F_rlim_max"\n", rlim.rlim_cur, rlim.rlim_max); } if (getrlimit(RLIMIT_DATA, &rlim) < 0) { Warn2("getrlimit(RLIMIT_DATA, %p): %s", &rlim, strerror(errno)); } else { fprintf(outfile, "data seg size (kbytes) %24"F_rlim_max"%24"F_rlim_max"\n", rlim.rlim_cur, rlim.rlim_max); } if (getrlimit(RLIMIT_STACK, &rlim) < 0) { Warn2("getrlimit(RLIMIT_STACK, %p): %s", &rlim, strerror(errno)); } else { fprintf(outfile, "stack size (blocks) %24"F_rlim_max"%24"F_rlim_max"\n", rlim.rlim_cur, rlim.rlim_max); } if (getrlimit(RLIMIT_CORE, &rlim) < 0) { Warn2("getrlimit(RLIMIT_CORE, %p): %s", &rlim, strerror(errno)); } else { fprintf(outfile, "core file size (blocks) %24"F_rlim_max"%24"F_rlim_max"\n", rlim.rlim_cur, rlim.rlim_max); } #ifdef RLIMIT_RSS /* Linux, AIX; not Cygwin */ if (getrlimit(RLIMIT_RSS, &rlim) < 0) { Warn2("getrlimit(RLIMIT_RSS, %p): %s", &rlim, strerror(errno)); } else { fprintf(outfile, "max resident set size %24"F_rlim_max"%24"F_rlim_max"\n", rlim.rlim_cur, rlim.rlim_max); } #endif #ifdef RLIMIT_NPROC /* Linux, not AIX, Cygwin */ if (getrlimit(RLIMIT_NPROC, &rlim) < 0) { Warn2("getrlimit(RLIMIT_NPROC, %p): %s", &rlim, strerror(errno)); } else { fprintf(outfile, "max user processes %24"F_rlim_max"%24"F_rlim_max"\n", rlim.rlim_cur, rlim.rlim_max); } #endif #ifdef RLIMIT_NOFILE /* not AIX 4.1 */ if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { Warn2("getrlimit(RLIMIT_NOFILE, %p): %s", &rlim, strerror(errno)); } else { fprintf(outfile, "open files %24"F_rlim_max"%24"F_rlim_max"\n", rlim.rlim_cur, rlim.rlim_max); } #endif #ifdef RLIMIT_MEMLOCK /* Linux, not AIX, Cygwin */ if (getrlimit(RLIMIT_MEMLOCK, &rlim) < 0) { Warn2("getrlimit(RLIMIT_MEMLOCK, %p): %s", &rlim, strerror(errno)); } else { fprintf(outfile, "max locked-in-memory\n address space %24"F_rlim_max"%24"F_rlim_max"\n", rlim.rlim_cur, rlim.rlim_max); } #endif #ifdef RLIMIT_AS if (getrlimit(RLIMIT_AS, &rlim) < 0) { Warn2("getrlimit(RLIMIT_AS, %p): %s", &rlim, strerror(errno)); } else { fprintf(outfile, "virtual memory (kbytes) %24"F_rlim_max"%24"F_rlim_max"\n", rlim.rlim_cur, rlim.rlim_max); } #endif } /* file descriptors */ /* what was this for?? */ /*Sleep(1);*/ return 0; } socat-1.7.3.1/xio-rawip.h0000644000201000020100000000151511453022152014645 0ustar gerhardgerhard/* source: xio-rawip.h */ /* Copyright Gerhard Rieger 2001-2007 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_rawip_h_included #define __xio_rawip_h_included 1 extern const struct addrdesc addr_rawip_sendto; extern const struct addrdesc addr_rawip_datagram; extern const struct addrdesc addr_rawip_recvfrom; extern const struct addrdesc addr_rawip_recv; extern const struct addrdesc addr_rawip4_sendto; extern const struct addrdesc addr_rawip4_datagram; extern const struct addrdesc addr_rawip4_recvfrom; extern const struct addrdesc addr_rawip4_recv; extern const struct addrdesc addr_rawip6_sendto; extern const struct addrdesc addr_rawip6_datagram; extern const struct addrdesc addr_rawip6_recvfrom; extern const struct addrdesc addr_rawip6_recv; #endif /* !defined(__xio_rawip_h_included) */ socat-1.7.3.1/filan.h0000644000201000020100000000222011453022152014011 0ustar gerhardgerhard/* source: filan.h */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __filan_h_included #define __filan_h_included 1 struct sockaddr; /* prevent gcc from spitting silly warning */ struct sockaddr_un; /* prevent gcc from spitting silly warning */ struct sockaddr_in; /* prevent gcc from spitting silly warning */ struct sockaddr_in6; /* prevent gcc from spitting silly warning */ extern bool filan_followsymlinks; extern bool filan_rawoutput; extern int filan_file(const char *filename, FILE *outfile); extern int filan_fd(int fd, FILE *outfile); extern int filan_stat( #if HAVE_STAT64 struct stat64 *buf #else struct stat *buf #endif /* !HAVE_STAT64 */ , int statfd, int dynfd, FILE *outfile); extern int cdevan(int fd, FILE *outfile); #if _WITH_SOCKET extern int isasocket(int fd); extern int sockan(int fd, FILE *outfile); extern int ipan(int fd, FILE *outfile); extern int ip6an(int fd, FILE *outfile); #endif /* _WITH_SOCKET */ extern int fdname(const char *file, int fd, FILE *outfile, const char *numform); #endif /* !defined(__filan_h_included) */ socat-1.7.3.1/xio-system.c0000644000201000020100000000374512460670272015064 0ustar gerhardgerhard/* source: xio-system.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of system type */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-progcall.h" #include "xio-system.h" #if WITH_SYSTEM static int xioopen_system(int arg, const char *argv[], struct opt *opts, int xioflags, /* XIO_RDONLY etc. */ xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3 ); const struct addrdesc addr_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 *fd, unsigned groups, int dummy1, int dummy2, int dummy3 ) { int status; char *path = NULL; int duptostderr; int result; const char *string = argv[1]; status = _xioopen_foxec(xioflags, &fd->stream, groups, &opts, &duptostderr); if (status < 0) return status; if (status == 0) { /* child */ int numleft; /* do not shutdown connections that belong our parent */ sock[0] = NULL; sock[1] = NULL; if (setopt_path(opts, &path) < 0) { /* this could be dangerous, so let us abort this child... */ Exit(1); } if ((numleft = leftopts(opts)) > 0) { Error1("%d option(s) could not be used", numleft); showleft(opts); return STAT_NORETRY; } /* only now redirect stderr */ if (duptostderr >= 0) { diag_dup(); Dup2(duptostderr, 2); } Info1("executing shell command \"%s\"", string); result = System(string); if (result != 0) { Warn2("system(\"%s\") returned with status %d", string, result); Warn1("system(): %s", strerror(errno)); } Exit(0); /* this child process */ } /* parent */ return 0; } #endif /* WITH_SYSTEM */ socat-1.7.3.1/vsnprintf_r.c0000644000201000020100000003751012460670272015312 0ustar gerhardgerhard/* vsnprintf_r.c */ /* Copyright Gerhard Rieger */ /* a reduced but async-signal-safe and thread-safe version of vsnprintf */ #include "config.h" #include /* ptrdiff_t */ #include /* isdigit() */ #include #include #include #if HAVE_SYSLOG_H #include #endif #include #include /* time_t, strftime() */ #include /* gettimeofday() */ #include #include #if HAVE_UNISTD_H #include #endif #include "vsnprintf_r.h" /* helper functions for vsnprintf_r(): e.g. convert an unsigned long to decimal string. in: field (must be long enough for all digits and \0 n: length of field in bytes ulo: the value returns: the pointer to the result string (need not be ==field) */ /* this function converts an unsigned long number to decimal ASCII it is async signal safe and thread safe it returns NULL if n==0 it returns NULL if field is too short to hold the result it returns a pointer to the result string (somewhere within field) it terminates result with \0 */ static char *_diag_ulong_to_dec(char *field, size_t n, unsigned long ulo) { char *np = field+n; /* point to the end */ if (n == 0) return NULL; *--np = '\0'; /* \0 in last char of string */ /* this is not optimal - uses much CPU, but simple to implement */ /* calculate the result from right to left */ do { if (np==field) return NULL; *--np = '0'+(ulo%10); } while (ulo/=10); return np; } /* this function converts an unsigned long number to decimal ASCII and pads it with space or '0' when size and leading0 are set appropriately it is async signal safe and thread safe it returns NULL if n==0 it returns NULL if field is too short to hold the result it returns a pointer to the result string (somewhere within field) it reduces size to n-1 if it is greater or equal it terminates result with \0 */ static char *diag_ulong_to_dec(char *field, size_t n, unsigned long ulo, int leading0, int size) { char *np; char c; int i; if (n == 0) return NULL; np = _diag_ulong_to_dec(field, n, ulo); if (np == NULL) return np; if (size) { if (size >= n) size = n-1; if (leading0) { c = '0'; } else { c = ' '; } i = size - strlen(np); while (--i >= 0) { *--np = c; } } return np; } /* this function converts a signed long number to decimal ASCII and pads it with space or '0' when size and leading0 are set appropriately it is async signal safe and thread safe it returns NULL if n==0 it returns NULL if field is too short to hold the result it returns a pointer to the result string (somewhere within field) it reduces size to n-1 if it is greater or equal it terminates result with \0 */ /* like diag_ulong_to_dec but signed; fields need also space for '-' */ static char *diag_long_to_dec(char *field, size_t n, long lo, int leading0, int size) { char *np; int minus; unsigned long ulo; int i; if ((minus = (lo < 0))) { ulo = (~lo)+1; } else { ulo = lo; } np = _diag_ulong_to_dec(field, n, ulo); if (np == NULL) return np; if (size) { if (size >= n) size = n-1; i = size - strlen(np); if (leading0) { if (minus) --i; while (--i >= 0) { *--np = '0'; } if (minus) *--np = '-'; } else { if (minus) { *--np = '-'; --i; } while (--i >= 0) { *--np = ' '; } } } else { if (minus) *--np = '-'; } return np; } /* this function converts an unsigned long number to hexadecimal ASCII it is async signal safe and thread safe it returns NULL if n==0 it returns NULL if field is too short to hold the result it returns a pointer to the result string (somewhere within field) it terminates result with \0 */ static char *diag_ulong_to_hex(char *field, size_t n, unsigned long ulo, int leading0, size_t size) { char *np = field+n; /* point to the end */ int i; char c; if (n == 0) return NULL; *--np = '\0'; /* \0 in last char of string */ /* calculate the result from right to left */ do { if (np==field) return NULL; i = (ulo&0x0f); *--np = (i<10?'0':('a'-10))+i; } while (ulo>>=4); if (size) { if (size >= n) size = n-1; if (leading0) { c = '0'; } else { c = ' '; } i = size - strlen(np); while (--i >= 0) { *--np = c; } } return np; } /* this function converts an unsigned long number to octal ASCII it is async signal safe and thread safe it returns NULL if n==0 it returns NULL if field is too short to hold the result it returns a pointer to the result string (somewhere within field) it terminates result with \0 */ static char *diag_ulong_to_oct(char *field, size_t n, unsigned long ulo, int leading0, size_t size) { char *np = field+n; /* point to the end */ int i; char c; if (n == 0) return NULL; *--np = '\0'; /* \0 in last char of string */ /* calculate the result from right to left */ do { if (np==field) return NULL; i = (ulo&0x07); *--np = '0'+i; } while (ulo>>=3); if (size) { if (size >= n) size = n-1; if (leading0) { c = '0'; } else { c = ' '; } i = size - strlen(np); while (--i >= 0) { *--np = c; } } return np; } #if HAVE_TYPE_LONGLONG /* this function converts an unsigned long long number to decimal ASCII it is async signal safe and thread safe it returns NULL if n==0 it returns NULL if field is too short to hold the result it returns a pointer to the result string (somewhere within field) it terminates result with \0 */ static char *_diag_ulonglong_to_dec(char *field, size_t n, unsigned long long ull) { char *np = field+n; /* point to the end */ if (n == 0) return NULL; *--np = '\0'; /* \0 in last char of string */ /* this is not optimal - uses much CPU, but simple to implement */ /* calculate the result from right to left */ do { if (np==field) return NULL; *--np = '0'+(ull%10); } while (ull/=10); return np; } /* this function converts an unsigned long long number to decimal ASCII and pads it with space or '0' when size and leading0 are set appropriately it is async signal safe and thread safe it returns NULL if n==0 it returns NULL if field is too short to hold the result it returns a pointer to the result string (somewhere within field) it reduces size to n-1 if it is greater or equal it terminates result with \0 */ static char *diag_ulonglong_to_dec(char *field, size_t n, unsigned long long ull, int leading0, int size) { char *np; char c; int i; if (n == 0) return NULL; np = _diag_ulonglong_to_dec(field, n, ull); if (size) { if (size >= n) size = n-1; if (leading0) { c = '0'; } else { c = ' '; } i = size - strlen(np); while (i-- > 0) { *--np = c; } } return np; } /* this function converts a signed long long number to decimal ASCII and pads it with space or '0' when size and leading0 are set appropriately it is async signal safe and thread safe it returns NULL if n==0 it returns NULL if field is too short to hold the result it returns a pointer to the result string (somewhere within field) it reduces size to n-1 if it is greater or equal it terminates result with \0 */ /* like diag_ulonglong_to_dec but signed; fields need also space for '-' */ static char *diag_longlong_to_dec(char *field, size_t n, long long ll, int leading0, int size) { char *np; int minus; unsigned long ull; int i; if ((minus = (ll < 0))) { ull = (~ll)+1; } else { ull = ll; } np = _diag_ulonglong_to_dec(field, n, ull); if (np == NULL) return np; if (size) { if (size >= n) size = n-1; i = size - strlen(np); if (leading0) { if (minus) --i; while (--i >= 0) { *--np = '0'; } if (minus) *--np = '-'; } else { if (minus) { *--np = '-'; --i; } while (--i >= 0) { *--np = ' '; } } } return np; } /* this function converts an unsigned long long number to hexadecimal ASCII it is async signal safe and thread safe it returns NULL if n==0 it returns NULL if field is too short to hold the result it returns a pointer to the result string (somewhere within field) it terminates result with \0 */ static char *diag_ulonglong_to_hex(char *field, size_t n, unsigned long long ull, int leading0, size_t size) { char *np = field+n; /* point to the end */ unsigned int i; char c; if (n == 0) return NULL; *--np = '\0'; /* \0 in last char of string */ /* calculate the result from right to left */ do { if (np==field) return NULL; i = (ull&0x0f); *--np = (i<10?'0':('a'-10))+i; } while (ull>>=4); if (size) { if (size >= n) size = n-1; if (leading0) { c = '0'; } else { c = ' '; } i = size - strlen(np); while (--i >= 0) { *--np = c; } } return np; } /* this function converts an unsigned long long number to octal ASCII it is async signal safe and thread safe it returns NULL if n==0 it returns NULL if field is too short to hold the result it returns a pointer to the result string (somewhere within field) it terminates result with \0 */ static char *diag_ulonglong_to_oct(char *field, size_t n, unsigned long long ull, int leading0, size_t size) { char *np = field+n; /* point to the end */ int i; char c; if (n == 0) return NULL; *--np = '\0'; /* \0 in last char of string */ /* calculate the result from right to left */ do { if (np==field) return NULL; i = (ull&0x07); *--np = '0'+i; } while (ull>>=3); if (size) { if (size >= n) size = n-1; if (leading0) { c = '0'; } else { c = ' '; } i = size - strlen(np); while (--i >= 0) { *--np = c; } } return np; } #endif /* HAVE_TYPE_LONGLONG */ /* this function is designed as a variant of vsnprintf(3) but async signal safe and thread safe it currently only implements a subset of the format directives returns <0 if an error occurred (no scenario know yet) returns >=size if output is truncated (conforming to C99 standard) */ int vsnprintf_r(char *str, size_t size, const char *format, va_list ap) { size_t i = 0; char c; int full = 0; /* indicate if output buffer full */ --size; /* without trailing \0 */ while (c = *format++) { if (c == '\\') { } else if (c == '%') { #if HAVE_TYPE_LONGLONG # define num_buff_len ((sizeof(unsigned long long)*8+2)/3+1) /* hold up to u long long in octal w/ \0 */ #else # define num_buff_len ((sizeof(unsigned long)*8+2)/3+1)]; /* hold up to u long in octal w/ \0 */ #endif char lengthmod = '\0'; /* 'h' 'l' 'L' 'z' */ int leading0 = 0; /* or 1 */ size_t fsize = 0; /* size of field */ const char *st; /* string */ long lo; unsigned long ulo; #if HAVE_TYPE_LONGLONG long long ll; unsigned long long ull; #endif char field[num_buff_len]; /* result of number conversion */ char *np; /* num pointer */ c = *format++; if (c == '\0') { break; } /* flag characters */ switch (c) { case '0': leading0 = 1; c = *format++; break; /* not handled: '#' '-' ' ' '+' '\'' */ } if (c == '\0') { break; } /* field width */ switch (c) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': do { fsize = 10*fsize+(c-'0'); c = *format++; } while (c && isdigit(c)); break; } if (c == '\0') { break; } /* precision - not handles */ /* length modifier */ switch (c) { /* not handled: 'q' 'j' 't' */ /* handled: 'h' 'hh'->'H' 'z' 'Z'->'z' 'l' 'll'->'L' 'L' */ case 'Z': c = 'z'; /* fall through */ #if HAVE_TYPE_LONGLONG case 'L': #endif case 'z': lengthmod = c; c = *format++; break; case 'h': lengthmod = c; if ((c = *format++) == 'h') { lengthmod = 'H'; c = *format++; } break; case 'l': lengthmod = c; if ((c = *format++) == 'l') { lengthmod = 'L'; c = *format++; } break; } if (c == '\0') { break; } /* conversion specifier */ switch (c) { case 'c': c = va_arg(ap, int); /* fall through */ case '%': *str++ = c; if (++i == size) { full = 1; } break; case 's': st = va_arg(ap, const char *); /* no modifier handled! */ while (c = *st++) { *str++ = c; if (++i == size) { full = 1; break; } } break; case 'd': #if HAVE_TYPE_LONGLONG if (lengthmod == 'L') { ll = va_arg(ap, long long); np = diag_longlong_to_dec(field, num_buff_len, ll, leading0, fsize); while (c = *np++) { *str++ = c; if (++i == size) { full = 1; break; } } } else #endif { switch (lengthmod) { case 'l': lo = va_arg(ap, long); break; case 'z': lo = va_arg(ap, ptrdiff_t); break; default: lo = va_arg(ap, int); break; } np = diag_long_to_dec(field, num_buff_len, lo, leading0, fsize); while (c = *np++) { *str++ = c; if (++i == size) { full = 1; break; } } } break; case 'u': #if HAVE_TYPE_LONGLONG if (lengthmod == 'L') { ull = va_arg(ap, unsigned long long); np = diag_ulonglong_to_dec(field, num_buff_len, ull, leading0, fsize); while (c = *np++) { *str++ = c; if (++i == size) { full = 1; break; } } } else #endif { switch (lengthmod) { case 'l': ulo = va_arg(ap, unsigned long); break; case 'z': ulo = va_arg(ap, size_t); break; default: ulo = va_arg(ap, unsigned int); break; } np = diag_ulong_to_dec(field, num_buff_len, ulo, leading0, fsize); while (c = *np++) { *str++ = c; if (++i == size) { full = 1; break; } } } break; case 'p': ulo = va_arg(ap, size_t); np = diag_ulong_to_hex(field, num_buff_len, ulo, leading0, fsize); *str++ = '0'; if (++i == size) { full = 1; break; } *str++ = 'x'; if (++i == size) { full = 1; break; } while (c = *np++) { *str++ = c; if (++i == size) { full = 1; break; } } break; case 'x': #if HAVE_TYPE_LONGLONG if (lengthmod == 'L') { ull = va_arg(ap, unsigned long long); np = diag_ulonglong_to_hex(field, num_buff_len, ull, leading0, fsize); while (c = *np++) { *str++ = c; if (++i == size) { full = 1; break; } } } else #endif { switch (lengthmod) { case 'l': ulo = va_arg(ap, unsigned long); break; case 'z': ulo = va_arg(ap, size_t); break; default: ulo = va_arg(ap, unsigned int); break; } np = diag_ulong_to_hex(field, num_buff_len, ulo, leading0, fsize); while (c = *np++) { *str++ = c; if (++i == size) { full = 1; break; } } } break; case 'o': #if HAVE_TYPE_LONGLONG if (lengthmod == 'L') { ull = va_arg(ap, unsigned long long); np = diag_ulonglong_to_oct(field, num_buff_len, ull, leading0, fsize); while (c = *np++) { *str++ = c; if (++i == size) break; } } else #endif { switch (lengthmod) { case 'l': ulo = va_arg(ap, unsigned long); break; case 'z': ulo = va_arg(ap, size_t); break; default: ulo = va_arg(ap, unsigned int); break; } np = diag_ulong_to_oct(field, num_buff_len, ulo, leading0, fsize); while (c = *np++) { *str++ = c; if (++i == size) { full = 1; break; } } } break; default: *str++ = c; if (++i == size) { full = 1; break; } } if (full) break; } else { *str++ = c; if (++i == size) break; } } *str = '\0'; return i; } int snprintf_r(char *str, size_t size, const char *format, ...) { int result; va_list ap; va_start(ap, format); result = vsnprintf_r(str, size, format, ap); va_end(ap); return result; } socat-1.7.3.1/xio-unix.h0000644000201000020100000000254311453022152014510 0ustar gerhardgerhard/* source: xio-unix.h */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_unix_h_included #define __xio_unix_h_included 1 extern const struct addrdesc xioaddr_unix_connect; extern const struct addrdesc xioaddr_unix_listen; extern const struct addrdesc xioaddr_unix_sendto; extern const struct addrdesc xioaddr_unix_recvfrom; extern const struct addrdesc xioaddr_unix_recv; extern const struct addrdesc xioaddr_unix_client; extern const struct addrdesc xioaddr_abstract_connect; extern const struct addrdesc xioaddr_abstract_listen; extern const struct addrdesc xioaddr_abstract_sendto; extern const struct addrdesc xioaddr_abstract_recvfrom; extern const struct addrdesc xioaddr_abstract_recv; extern const struct addrdesc xioaddr_abstract_client; extern const struct optdesc xioopt_unix_tightsocklen; extern socklen_t xiosetunix(int pf, struct sockaddr_un *saun, const char *path, bool abstract, bool tight); extern int xiosetsockaddrenv_unix(int idx, char *namebuff, size_t namelen, char *valuebuff, size_t valuelen, struct sockaddr_un *sa, socklen_t salen, int ipproto); extern int _xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups, int abstract, struct opt *opts, const char *name); #endif /* !defined(__xio_unix_h_included) */ socat-1.7.3.1/hostan.c0000644000201000020100000000763712460670272014243 0ustar gerhardgerhard/* source: hostan.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* the subroutine hostan makes a "HOST ANalysis". It gathers information about the host environment it is running in without modifying its state (almost). */ #include "xiosysincludes.h" #include "mytypes.h" #include "compat.h" #include "error.h" #include "sycls.h" #include "sysutils.h" #include "filan.h" #include "hostan.h" #include "error.h" static int iffan(FILE *outfile); int hostan(FILE *outfile) { fprintf(outfile, "\nC TYPE SIZES\n"); fprintf(outfile, "sizeof(char) = %u\n", (unsigned int)sizeof(char)); fprintf(outfile, "sizeof(short) = %u\n", (unsigned int)sizeof(short)); fprintf(outfile, "sizeof(int) = %u\n", (unsigned int)sizeof(int)); fprintf(outfile, "sizeof(long) = %u\n", (unsigned int)sizeof(long)); #if HAVE_TYPE_LONGLONG fprintf(outfile, "sizeof(long long) = %u\n", (unsigned int)sizeof(long long)); #endif fprintf(outfile, "sizeof(size_t) = %u\n", (unsigned int)sizeof(size_t)); #include /* select(); OpenBSD: struct timespec */ fprintf(outfile, "sizeof(struct timespec) = %u\n", (unsigned int)sizeof(struct timespec)); fprintf(outfile, "sizeof(struct diag_dgram) = %u\n", (unsigned int)sizeof(struct diag_dgram)); fprintf(outfile, "((struct diag_dgram *)0)->op-((struct diag_dgram *)0) = %u\n", (unsigned int)((char *)(&((struct diag_dgram *)0)->op)-(char *)((struct diag_dgram *)0))); fprintf(outfile, "((struct diag_dgram *)0)->now-((struct diag_dgram *)0) = %u\n", (unsigned int)((char *)(&((struct diag_dgram *)0)->now)-(char *)((struct diag_dgram *)0))); fprintf(outfile, "((struct diag_dgram *)0)->exitcode-((struct diag_dgram *)0) = %u\n", (unsigned int)((char *)(&((struct diag_dgram *)0)->exitcode)-(char *)((struct diag_dgram *)0))); fprintf(outfile, "((struct diag_dgram *)0)->text-((struct diag_dgram *)0) = %u\n", (unsigned int)((((struct diag_dgram *)0)->text)-(char *)((struct diag_dgram *)0))); #if _WITH_SOCKET && (_WITH_IP4 || _WITH_IP6) fprintf(outfile, "\nIP INTERFACES\n"); iffan(outfile); #endif return 0; } #if _WITH_SOCKET && (_WITH_IP4 || _WITH_IP6) static int iffan(FILE *outfile) { /* Linux: man 7 netdevice */ /* FreeBSD, NetBSD: man 4 networking */ /* Solaris: man 7 if_tcp */ /* currently we support Linux and a little FreeBSD */ #ifdef SIOCGIFCONF /* not Solaris */ #define IFBUFSIZ 32*sizeof(struct ifreq) /*1024*/ int s; unsigned char buff[IFBUFSIZ]; struct ifconf ic; int i; if ((s = Socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { Error1("socket(PF_INET, SOCK_DGRAM, IPPROTO_IP): %s", strerror(errno)); return -1; } for (i=0; i < IFBUFSIZ; ++i) { buff[i] = 255; } ic.ifc_len = sizeof(buff); ic.ifc_ifcu.ifcu_buf = (caddr_t)buff; if (Ioctl(s, SIOCGIFCONF, &ic) < 0) { Error3("ioctl(%d, SIOCGIFCONF, %p): %s", s, &ic, strerror(errno)); return -1; } for (i = 0; i < ic.ifc_len; i += sizeof(struct ifreq)) { struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i); #if 0 || defined(SIOCGIFINDEX) /* not NetBSD, OpenBSD */ struct ifreq ifr; #endif #if 0 || defined(SIOCGIFINDEX) /* not NetBSD, OpenBSD */ strcpy(ifr.ifr_name, ifp->ifr_name); if (Ioctl(s, SIOCGIFINDEX, &ifr) < 0) { Error3("ioctl(%d, SIOCGIFINDEX, {\"%s\"}): %s", s, ifr.ifr_name, strerror(errno)); return 1; } #if HAVE_STRUCT_IFREQ_IFR_INDEX fprintf(outfile, "%2d: %s\n", ifr.ifr_index, ifp->ifr_name); #elif HAVE_STRUCT_IFREQ_IFR_IFINDEX fprintf(outfile, "%2d: %s\n", ifr.ifr_ifindex, ifp->ifr_name); #endif /* HAVE_STRUCT_IFREQ_IFR_INDEX */ #else /* !defined(SIOCGIFINDEX) */ fprintf(outfile, "%2d: %s\n", i/(int)sizeof(struct ifreq), ifp->ifr_name); #endif /* defined(SIOCGIFINDEX) */ } Close(s); #endif /* defined(SIOCGIFCONF) */ return 0; } #endif /* _WITH_SOCKET */ socat-1.7.3.1/sycls.c0000644000201000020100000012666012460670272014102 0ustar gerhardgerhard/* source: sycls.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* explicit system call and C library trace function, for those who miss strace */ #include "config.h" #include "xioconfig.h" /* what features are enabled */ #if WITH_SYCLS #include "sysincludes.h" #include "mytypes.h" #include "compat.h" #include "errno.h" #include "error.h" #include "filan.h" #include "utils.h" #include "sysutils.h" #include "sycls.h" mode_t Umask(mode_t mask) { mode_t result; int _errno; Debug1("umask("F_mode")", mask); result = umask(mask); _errno = errno; Debug1("umask() -> "F_mode, result); errno = _errno; return result; } int Open(const char *pathname, int flags, mode_t mode) { int result, _errno; if (!diag_in_handler) diag_flush(); Debug3("open(\"%s\", 0%o, 0%03o)", pathname, flags, mode); result = open(pathname, flags, mode); _errno = errno; if (!diag_in_handler) diag_flush(); Info4("open(\"%s\", 0%o, 0%03o) -> %d", pathname, flags, mode, result); errno = _errno; return result; } int Creat(const char *pathname, mode_t mode) { int result, _errno; Debug2("creat(\"%s\", 0%03o)", pathname, mode); result = creat(pathname, mode); _errno = errno; Info3("creat(\"%s\", 0%03o) -> %d", pathname, mode, result); errno = _errno; return result; } off_t Lseek(int fildes, off_t offset, int whence) { int _errno; off_t result; Debug3("lseek(%d, "F_off", %d)", fildes, offset, whence); result = lseek(fildes, offset, whence); _errno = errno; Debug1("lseek() -> "F_off, result); errno = _errno; return result; } #if HAVE_LSEEK64 off64_t Lseek64(int fildes, off64_t offset, int whence) { int _errno; off64_t result; Debug3("lseek64(%d, "F_off64", %d)", fildes, offset, whence); result = lseek64(fildes, offset, whence); _errno = errno; Debug1("lseek64() -> "F_off64, result); errno = _errno; return result; } #endif /* HAVE_LSEEK64 */ pid_t Getpid(void) { pid_t result; int _errno; Debug("getpid()"); result = getpid(); _errno = errno; Debug1("getpid() -> "F_pid, result); errno = _errno; return result; } pid_t Getppid(void) { pid_t result; int _errno; Debug("getppid()"); result = getppid(); _errno = errno; Debug1("getppid() -> "F_pid, result); errno = _errno; return result; } pid_t Getpgrp(void) { pid_t result; int _errno; Debug("getpgrp()"); result = getpgrp(); _errno = errno; Debug1("getpgrp() -> "F_pid, result); errno = _errno; return result; } #if 0 /* does not compile for FreeBSD */ /* setpgrp() is not BSD compatible, needs setpgid(..., ...) instead */ int Setpgrp(void) { int result, _errno; Debug("setpgrp()"); result = setpgrp(); _errno = errno; Debug1("setpgrp() -> %d", result); errno = _errno; return result; } #endif #if HAVE_GETPGID int Getpgid(pid_t pid) { pid_t result; int _errno; Debug1("getpgid("F_pid")", pid); result = getpgid(pid); _errno = errno; Debug1("getpgid() -> "F_pid, result); errno = _errno; return result; } #endif int Setpgid(pid_t pid, pid_t pgid) { int result, _errno; Debug2("setpgid("F_pid", "F_pid")", pid, pgid); result = setpgid(pid, pgid); _errno = errno; Debug1("setpgid() -> %d", result); errno = _errno; return result; } pid_t Tcgetpgrp(int fd) { int result, _errno; Debug1("tcgetpgrp(%d)", fd); result = tcgetpgrp(fd); _errno = errno; Debug1("tcgetpgrp() -> %d", result); errno = _errno; return result; } int Tcsetpgrp(int fd, pid_t pgrpid) { int result, _errno; Debug2("tcsetpgrp(%d, "F_pid")", fd, pgrpid); result = tcsetpgrp(fd, pgrpid); _errno = errno; Debug1("tcsetpgrp() -> %d", result); errno = _errno; return result; } #if HAVE_GETSID pid_t Getsid(pid_t pid) { int result, _errno; Debug1("getsid("F_pid")", pid); result = getsid(pid); _errno = errno; Debug1("getsid() -> "F_pid, result); errno = _errno; return result; } #endif pid_t Setsid(void) { int result, _errno; Debug("setsid()"); result = setsid(); _errno = errno; Debug1("setsid() -> "F_pid, result); errno = _errno; return result; } uid_t Getuid(void) { uid_t result; int _errno; Debug("getuid()"); result = getuid(); _errno = errno; Debug1("getuid() -> "F_uid, result); errno = _errno; return result; } uid_t Geteuid(void) { uid_t result; int _errno; Debug("geteuid()"); result = geteuid(); _errno = errno; Debug1("geteuid() -> "F_uid, result); errno = _errno; return result; } int Setuid(uid_t uid) { int result, _errno; Debug1("setuid("F_uid")", uid); result = setuid(uid); _errno = errno; Debug1("setuid() -> %d", result); errno = _errno; return result; } gid_t Getgid(void) { gid_t result; int _errno; Debug("getgid()"); result = getgid(); _errno = errno; Debug1("getgid() -> "F_gid, result); errno = _errno; return result; } gid_t Getegid(void) { gid_t result; int _errno; Debug("getegid()"); result = getegid(); _errno = errno; Debug1("getegid() -> "F_gid, result); errno = _errno; return result; } int Setgid(gid_t gid) { int result, _errno; Debug1("setgid("F_gid")", gid); result = setgid(gid); _errno = errno; Debug1("setgid() -> %d", result); errno = _errno; return result; } int Initgroups(const char *user, gid_t group) { int result, _errno; Debug2("initgroups(\"%s\", "F_gid")", user, group); result = initgroups(user, group); _errno = errno; Debug1("initgroups() -> %d", result); errno = _errno; return result; } int Getgroups(int size, gid_t list[]) { int result, _errno; Debug2("getgroups(%d, "F_gid",...)", size, list[0]); result = getgroups(size, list); _errno = errno; Debug1("getgroups() -> %d", result); errno = _errno; return result; } #if HAVE_SETGROUPS int Setgroups(size_t size, const gid_t *list) { int result, _errno; switch (size) { case 0: Debug1("setgroups("F_Zu", [])", size); break;; case 1: Debug2("setgroups("F_Zu", ["F_gid"])", size, list[0]); break;; case 2: Debug3("setgroups("F_Zu", ["F_gid","F_gid"])", size, list[0], list[1]); break;; default: Debug3("setgroups("F_Zu", ["F_gid","F_gid",...])", size, list[0], list[1]); break;; } result = setgroups(size, list); _errno = errno; Debug1("setgroups() -> %d", result); errno = _errno; return result; } #endif #if HAVE_GETGROUPLIST int Getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups) { int n = *ngroups, result; Debug4("getgrouplist(\"%s\", "F_gid", %p, [%d])", user, group, groups, n); result = getgrouplist(user, group, groups, ngroups); switch (Min(n,*ngroups)) { case 0: Debug2("getgrouplist(,, [], [%d]) -> %d", *ngroups, result); break; case 1: Debug3("getgrouplist(,, ["F_gid"], [%d]) -> %d", groups[0], *ngroups, result); break; case 2: Debug4("getgrouplist(,, ["F_gid","F_gid"], [%d]) -> %d", groups[0], groups[1], *ngroups, result); break; default: Debug4("getgrouplist(,, ["F_gid","F_gid",...], [%d]) -> %d", groups[0], groups[1], *ngroups, result); break; } return result; } #endif int Chdir(const char *path) { int result, _errno; Debug1("chdir(\"%s\")", path); result = chdir(path); _errno = errno; Debug1("chdir() -> %d", result); errno = _errno; return result; } int Chroot(const char *path) { int result, _errno; Debug1("chroot(\"%s\")", path); result = chroot(path); _errno = errno; Debug1("chroot() -> %d", result); errno = _errno; return result; } int Gettimeofday(struct timeval *tv, struct timezone *tz) { int result, _errno; #if WITH_MSGLEVEL <= E_DEBUG if (tz) { Debug3("gettimeofday(%p, {%d,%d})", tv, tz->tz_minuteswest, tz->tz_dsttime); } else { Debug1("gettimeofday(%p, NULL)", tv); } #endif /* WITH_MSGLEVEL <= E_DEBUG */ result = gettimeofday(tv, tz); _errno = errno; #if WITH_MSGLEVEL <= E_DEBUG if (tz) { Debug5("gettimeofday({%ld,%ld}, {%d,%d}) -> %d", tv->tv_sec, tv->tv_usec, tz->tz_minuteswest, tz->tz_dsttime, result); } else { Debug3("gettimeofday({%ld,%ld},) -> %d", tv->tv_sec, tv->tv_usec, result); } #endif /* WITH_MSGLEVEL <= E_DEBUG */ errno = _errno; return result; } int Mknod(const char *pathname, mode_t mode, dev_t dev) { int result, _errno; Debug3("mknod(\"%s\", 0%o, "F_dev")", pathname, mode, dev); result = mknod(pathname, mode, dev); _errno = errno; Debug1("mknod() -> %d", result); errno = _errno; return result; } int Mkfifo(const char *pathname, mode_t mode) { int result, _errno; Debug2("mkfifo(\"%s\", 0%o)", pathname, mode); result = mkfifo(pathname, mode); _errno = errno; Debug1("mkfifo() -> %d", result); errno = _errno; return result; } static void prtstat(const char *func, struct stat *buf, int result) { char txt[256], *t = txt; t += sprintf(t, "%s(, {"F_dev","F_st_ino","F_mode","F_st_nlink","F_uid","F_gid, func, buf->st_dev, buf->st_ino, buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid); #if HAVE_ST_RDEV t += sprintf(t, ","F_dev, buf->st_rdev); #endif t += sprintf(t, ","F_st_size, buf->st_size); #if HAVE_ST_BLKSIZE t += sprintf(t, ","F_st_blksize, buf->st_blksize); #endif #if HAVE_ST_BLOCKS t += sprintf(t, ","F_st_blocks, buf->st_blocks); #endif sprintf(t, ",...}) -> %d", result); Debug(txt); } #if defined(HAVE_STAT64) || defined(HAVE_FSTAT64) || defined(HAVE_LSTAT64) static void prtstat64(const char *func, struct stat64 *buf, int result) { char txt[256], *t = txt; if (result < 0) { sprintf(t, "%s(, {}) -> %d", func, result); } else { t += sprintf(t, "%s(, {"F_dev","F_st64_ino","F_mode","F_st_nlink","F_uid","F_gid, func, buf->st_dev, buf->st_ino, buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid); #if HAVE_ST_RDEV t += sprintf(t, ","F_dev, buf->st_rdev); #endif t += sprintf(t, ","F_st64_size, buf->st_size); #if HAVE_ST_BLKSIZE t += sprintf(t, ","F_st_blksize, buf->st_blksize); #endif #if HAVE_ST_BLOCKS t += sprintf(t, ","F_st64_blocks, buf->st_blocks); #endif sprintf(t, ",...}) -> %d", result); } Debug(txt); } #endif /* defined(HAVE_STAT64) || defined(HAVE_FSTAT64) || defined(HAVE_LSTAT64) */ int Stat(const char *file_name, struct stat *buf) { int result, _errno; Debug2("stat(%s, %p)", file_name, buf); result = stat(file_name, buf); _errno = errno; prtstat("stat", buf, result); errno = _errno; return result; } #if HAVE_STAT64 int Stat64(const char *file_name, struct stat64 *buf) { int result, _errno; Debug2("stat64(%s, %p)", file_name, buf); result = stat64(file_name, buf); _errno = errno; prtstat64("stat64", buf, result); errno = _errno; return result; } #endif /* HAVE_STAT64 */ int Fstat(int filedes, struct stat *buf) { int result, _errno; Debug2("fstat(%d, %p)", filedes, buf); result = fstat(filedes, buf); _errno = errno; prtstat("fstat", buf, result); errno = _errno; return result; } #if HAVE_FSTAT64 int Fstat64(int filedes, struct stat64 *buf) { int result, _errno; Debug2("fstat64(%d, %p)", filedes, buf); result = fstat64(filedes, buf); _errno = errno; prtstat64("fstat64", buf, result); errno = _errno; return result; } #endif /* HAVE_FSTAT64 */ int Lstat(const char *file_name, struct stat *buf) { int result, _errno; Debug2("lstat(%s, %p)", file_name, buf); result = lstat(file_name, buf); _errno = errno; prtstat("lstat", buf, result); errno = _errno; return result; } #if HAVE_LSTAT64 int Lstat64(const char *file_name, struct stat64 *buf) { int result, _errno; Debug2("lstat64(%s, %p)", file_name, buf); result = lstat64(file_name, buf); _errno = errno; prtstat64("lstat64", buf, result); errno = _errno; return result; } #endif /* HAVE_LSTAT64 */ int Dup(int oldfd) { int newfd, _errno; Debug1("dup(%d)", oldfd); newfd = dup(oldfd); _errno = errno; Info2("dup(%d) -> %d", oldfd, newfd); errno = _errno; return newfd; } int Dup2(int oldfd, int newfd) { int result, _errno; Debug2("dup2(%d, %d)", oldfd, newfd); result = dup2(oldfd, newfd); _errno = errno; Info3("dup2(%d, %d) -> %d", oldfd, newfd, result); errno = _errno; return result; } int Pipe(int filedes[2]) { int result, _errno; Debug1("pipe(%p)", filedes); result = pipe(filedes); _errno = errno; Info3("pipe({%d,%d}) -> %d", filedes[0], filedes[1], result); errno = _errno; return result; } ssize_t Read(int fd, void *buf, size_t count) { ssize_t result; int _errno; if (!diag_in_handler) diag_flush(); Debug3("read(%d, %p, "F_Zu")", fd, buf, count); result = read(fd, buf, count); _errno = errno; if (!diag_in_handler) diag_flush(); Debug1("read -> "F_Zd, result); errno = _errno; return result; } ssize_t Write(int fd, const void *buf, size_t count) { ssize_t result; int _errno; if (!diag_in_handler) diag_flush(); Debug3("write(%d, %p, "F_Zu")", fd, buf, count); result = write(fd, buf, count); _errno = errno; if (!diag_in_handler) diag_flush(); Debug1("write -> "F_Zd, result); errno = _errno; return result; } int Fcntl(int fd, int cmd) { int result, _errno; if (!diag_in_handler) diag_flush(); Debug2("fcntl(%d, %d)", fd, cmd); result = fcntl(fd, cmd); if (!diag_in_handler) diag_flush(); _errno = errno; Debug1("fcntl() -> %d", result); errno = _errno; return result; } int Fcntl_l(int fd, int cmd, long arg) { int result, _errno; if (!diag_in_handler) diag_flush(); Debug3("fcntl(%d, %d, %ld)", fd, cmd, arg); result = fcntl(fd, cmd, arg); _errno = errno; if (!diag_in_handler) diag_flush(); Debug1("fcntl() -> %d", result); errno = _errno; return result; } int Fcntl_lock(int fd, int cmd, struct flock *l) { int result, _errno; if (!diag_in_handler) diag_flush(); Debug7("fcntl(%d, %d, {type=%hd,whence=%hd,start="F_off",len="F_off",pid="F_pid"})", fd, cmd, l->l_type, l->l_whence, l->l_start, l->l_len, l->l_pid); result = fcntl(fd, cmd, l); _errno = errno; if (!diag_in_handler) diag_flush(); Debug1("fcntl() -> %d", result); errno = _errno; return result; } int Ftruncate(int fd, off_t length) { int retval, _errno; Debug2("ftruncate(%d, "F_off")", fd, length); retval = ftruncate(fd, length); _errno = errno; Debug1("ftruncate() -> %d", retval); errno = _errno; return retval; } #if HAVE_FTRUNCATE64 int Ftruncate64(int fd, off64_t length) { int retval, _errno; Debug2("ftruncate64(%d, "F_off64")", fd, length); retval = ftruncate64(fd, length); _errno = errno; Debug1("ftruncate64() -> %d", retval); errno = _errno; return retval; } #endif /* HAVE_FTRUNCATE64 */ #if HAVE_FLOCK int Flock(int fd, int operation) { int retval, _errno; if (!diag_in_handler) diag_flush(); Debug2("flock(%d, %d)", fd, operation); retval = flock(fd, operation); _errno = errno; if (!diag_in_handler) diag_flush(); Debug1("flock() -> %d", retval); errno = _errno; return retval; } #endif /* HAVE_FLOCK */ int Ioctl(int d, int request, void *argp) { int retval, _errno; if (!diag_in_handler) diag_flush(); if (argp > (void *)0x10000) { /* fuzzy...*/ Debug4("ioctl(%d, 0x%x, %p{%lu})", d, request, argp, *(unsigned long *)argp); } else { Debug3("ioctl(%d, 0x%x, 0x%p)", d, request, argp); } retval = ioctl(d, request, argp); _errno = errno; if (!diag_in_handler) diag_flush(); Debug1("ioctl() -> %d", retval); errno = _errno; return retval; } int Ioctl_int(int d, int request, int arg) { int retval, _errno; Debug3("ioctl(%d, 0x%x, %d)", d, request, arg); retval = ioctl(d, request, arg); _errno = errno; Debug1("ioctl() -> %d", retval); errno = _errno; return retval; } int Close(int fd) { int retval, _errno; Info1("close(%d)", fd); retval = close(fd); _errno = errno; Debug1("close() -> %d", retval); errno = _errno; return retval; } int Fchown(int fd, uid_t owner, gid_t group) { int retval, _errno; Debug3("fchown(%d, "F_uid", "F_gid")", fd, owner, group); retval = fchown(fd, owner, group); _errno = errno; Debug1("fchown() -> %d", retval); errno = _errno; return retval; } int Fchmod(int fd, mode_t mode) { int retval, _errno; Debug2("fchmod(%d, 0%o)", fd, mode); retval = fchmod(fd, mode); _errno = errno; Debug1("fchmod() -> %d", retval); errno = _errno; return retval; } int Unlink(const char *pathname) { int retval, _errno; Debug1("unlink(\"%s\")", pathname); retval = unlink(pathname); _errno = errno; Debug1("unlink() -> %d", retval); errno = _errno; return retval; } int Symlink(const char *oldpath, const char *newpath) { int retval, _errno; Debug2("symlink(\"%s\", \"%s\")", oldpath, newpath); retval = symlink(oldpath, newpath); _errno = errno; Debug1("symlink() -> %d", retval); errno = _errno; return retval; } int Readlink(const char *path, char *buf, size_t bufsiz) { int retval, _errno; Debug3("readlink(\"%s\", %p, "F_Zu")", path, buf, bufsiz); retval = readlink(path, buf, bufsiz); _errno = errno; Debug1("readlink() -> %d", retval); errno = _errno; return retval; } int Chown(const char *path, uid_t owner, gid_t group) { int retval, _errno; Debug3("chown(\"%s\", "F_uid", "F_gid")", path, owner, group); retval = chown(path, owner, group); _errno = errno; Debug1("chown() -> %d", retval); errno = _errno; return retval; } int Chmod(const char *path, mode_t mode) { int retval, _errno; Debug2("chmod(\"%s\", 0%o)", path, mode); retval = chmod(path, mode); _errno = errno; Debug1("chmod() -> %d", retval); errno = _errno; return retval; } #if HAVE_POLL /* we only show the first struct pollfd; hope this is enough for most cases. */ int Poll(struct pollfd *ufds, unsigned int nfds, int timeout) { int _errno, result; if (!diag_in_handler) diag_flush(); if (nfds == 4) { Debug10("poll({%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}, %u, %d)", ufds[0].fd, ufds[0].events, ufds[1].fd, ufds[1].events, ufds[2].fd, ufds[2].events, ufds[3].fd, ufds[3].events, nfds, timeout); } else { Debug4("poll({%d,0x%02hx,}, , %u, %d)", ufds[0].fd, ufds[0].events, nfds, timeout); } result = poll(ufds, nfds, timeout); _errno = errno; if (!diag_in_handler) diag_flush(); if (nfds == 4) { Debug5("poll(, {,,0x%02hx}{,,0x%02hx}{,,0x%02hx}{,,0x%02hx}) -> %d", ufds[0].revents, ufds[1].revents, ufds[2].revents, ufds[3].revents, result); } else { Debug2("poll(, {,,0x%02hx}) -> %d", ufds[0].revents, result); } errno = _errno; return result; } #endif /* HAVE_POLL */ /* we only show the first word of the fd_set's; hope this is enough for most cases. */ int Select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { int result, _errno; if (!diag_in_handler) diag_flush(); #if HAVE_FDS_BITS Debug7("select(%d, &0x%lx, &0x%lx, &0x%lx, %s%lu."F_tv_usec")", n, readfds?readfds->fds_bits[0]:0, writefds?writefds->fds_bits[0]:0, exceptfds?exceptfds->fds_bits[0]:0, timeout?"&":"NULL/", timeout?timeout->tv_sec:0, timeout?timeout->tv_usec:0); #else Debug7("select(%d, &0x%lx, &0x%lx, &0x%lx, %s%lu.%06u)", n, readfds?readfds->__fds_bits[0]:0, writefds?writefds->__fds_bits[0]:0, exceptfds?exceptfds->__fds_bits[0]:0, timeout?"&":"NULL/", timeout?timeout->tv_sec:0, timeout?timeout->tv_usec:0); #endif result = select(n, readfds, writefds, exceptfds, timeout); _errno = errno; if (!diag_in_handler) diag_flush(); #if HAVE_FDS_BITS Debug7("select -> (, 0x%lx, 0x%lx, 0x%lx, %s%lu."F_tv_usec"), %d", readfds?readfds->fds_bits[0]:0, writefds?writefds->fds_bits[0]:0, exceptfds?exceptfds->fds_bits[0]:0, timeout?"&":"NULL/", timeout?timeout->tv_sec:0, timeout?timeout->tv_usec:0, result); #else Debug7("select -> (, 0x%lx, 0x%lx, 0x%lx, %s%lu.%06u), %d", readfds?readfds->__fds_bits[0]:0, writefds?writefds->__fds_bits[0]:0, exceptfds?exceptfds->__fds_bits[0]:0, timeout?"&":"NULL/", timeout?timeout->tv_sec:0, timeout?timeout->tv_usec:0, result); #endif errno = _errno; return result; } pid_t Fork(void) { pid_t pid; int _errno; Debug("fork()"); pid = fork(); _errno = errno; Debug1("fork() -> %d", pid); /* attention: called twice! */ errno = _errno; return pid; } pid_t Waitpid(pid_t pid, int *status, int options) { int _errno; pid_t retval; if (!diag_in_handler) diag_flush(); Debug3("waitpid("F_pid", %p, %d)", pid, status, options); retval = waitpid(pid, status, options); _errno = errno; if (!diag_in_handler) diag_flush(); Debug2("waitpid(, {%d}, ) -> "F_pid, *status, retval); errno = _errno; return retval; } sighandler_t Signal(int signum, sighandler_t handler) { int _errno; sighandler_t retval; Debug2("signal(%d, %p)", signum, handler); retval = signal(signum, handler); _errno = errno; Debug1("signal() -> %p", retval); errno = _errno; return retval; } #if HAVE_SIGACTION int Sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) { int retval; Debug3("sigaction(%d, %p, %p)", signum, act, oldact); retval = sigaction(signum, act, oldact); Debug1("sigaction() -> %d", retval); return retval; } #endif /* HAVE_SIGACTION */ int Sigprocmask(int how, const sigset_t *set, sigset_t *oset) { int retval; Debug3("sigprocmask(%d, %p, %p)", how, set, oset); retval = sigprocmask(how, set, oset); Debug1("sigprocmask() -> %d", retval); return retval; } unsigned int Alarm(unsigned int seconds) { unsigned int retval; Debug1("alarm(%u)", seconds); retval = alarm(seconds); Debug1("alarm() -> %u", retval); return retval; } int Kill(pid_t pid, int sig) { int retval, _errno; Debug2("kill("F_pid", %d)", pid, sig); retval = kill(pid, sig); _errno = errno; Debug1("kill() -> %d", retval); errno = _errno; return retval; } int Link(const char *oldpath, const char *newpath) { int retval, _errno; Debug2("link(\"%s\", \"%s\")", oldpath, newpath); retval = link(oldpath, newpath); _errno = errno; Debug1("link() -> %d", retval); errno = _errno; return retval; } int Execvp(const char *file, char *const argv[]) { int result, _errno; if (argv[1] == NULL) Debug2("execvp(\"%s\", \"%s\")", file, argv[0]); else if (argv[2] == NULL) Debug3("execvp(\"%s\", \"%s\" \"%s\")", file, argv[0], argv[1]); else if (argv[3] == NULL) Debug4("execvp(\"%s\", \"%s\" \"%s\" \"%s\")", file, argv[0], argv[1], argv[2]); else if (argv[4] == NULL) Debug5("execvp(\"%s\", \"%s\" \"%s\" \"%s\" \"%s\")", file, argv[0], argv[1], argv[2], argv[3]); else if (argv[5] == NULL) Debug6("execvp(\"%s\", \"%s\" \"%s\" \"%s\" \"%s\" \"%s\")", file, argv[0], argv[1], argv[2], argv[3], argv[4]); else Debug6("execvp(\"%s\", \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" ...)", file, argv[0], argv[1], argv[2], argv[3], argv[4]); result = execvp(file, argv); _errno = errno; Debug1("execvp() -> %d", result); errno = _errno; return result; } int System(const char *string) { int result, _errno; Debug1("system(\"%s\")", string); diag_immediate_exit = 1; result = system(string); diag_immediate_exit = 0; _errno = errno; Debug1("system() -> %d", result); errno = _errno; return result; } int Socketpair(int d, int type, int protocol, int sv[2]) { int result, _errno; Debug4("socketpair(%d, %d, %d, %p)", d, type, protocol, sv); result = socketpair(d, type, protocol, sv); _errno = errno; Info6("socketpair(%d, %d, %d, {%d,%d}) -> %d", d, type, protocol, sv[0], sv[1], result); errno = _errno; return result; } #if _WITH_SOCKET int Socket(int domain, int type, int protocol) { int result, _errno; Debug3("socket(%d, %d, %d)", domain, type, protocol); result = socket(domain, type, protocol); _errno = errno; Info4("socket(%d, %d, %d) -> %d", domain, type, protocol, result); errno = _errno; return result; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int Bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) { int result, _errno; char infobuff[256]; sockaddr_info(my_addr, addrlen, infobuff, sizeof(infobuff)); Debug3("bind(%d, %s, "F_socklen")", sockfd, infobuff, addrlen); result = bind(sockfd, my_addr, addrlen); _errno = errno; Debug1("bind() -> %d", result); errno = _errno; return result; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int Connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) { int result, _errno; char infobuff[256]; if (!diag_in_handler) diag_flush(); /*sockaddr_info(serv_addr, infobuff, sizeof(infobuff)); Debug3("connect(%d, %s, "F_Zd")", sockfd, infobuff, addrlen);*/ #if 0 Debug18("connect(%d,{0x%02x%02x%02x%02x %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x}, "F_Zd")", sockfd, ((unsigned char *)serv_addr)[0], ((unsigned char *)serv_addr)[1], ((unsigned char *)serv_addr)[2], ((unsigned char *)serv_addr)[3], ((unsigned char *)serv_addr)[4], ((unsigned char *)serv_addr)[5], ((unsigned char *)serv_addr)[6], ((unsigned char *)serv_addr)[7], ((unsigned char *)serv_addr)[8], ((unsigned char *)serv_addr)[9], ((unsigned char *)serv_addr)[10], ((unsigned char *)serv_addr)[11], ((unsigned char *)serv_addr)[12], ((unsigned char *)serv_addr)[13], ((unsigned char *)serv_addr)[14], ((unsigned char *)serv_addr)[15], addrlen); #else Debug4("connect(%d, {%d,%s}, "F_socklen")", sockfd, serv_addr->sa_family, sockaddr_info(serv_addr, addrlen, infobuff, sizeof(infobuff)), addrlen); #endif result = connect(sockfd, serv_addr, addrlen); _errno = errno; if (!diag_in_handler) diag_flush(); Debug1("connect() -> %d", result); errno = _errno; return result; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int Listen(int s, int backlog) { int result, _errno; Debug2("listen(%d, %d)", s, backlog); result = listen(s, backlog); _errno = errno; Debug1("listen() -> %d", result); errno = _errno; return result; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET /* don't forget to handle EINTR when using Accept() ! */ int Accept(int s, struct sockaddr *addr, socklen_t *addrlen) { int result, _errno; fd_set accept_s; if (!diag_in_handler) diag_flush(); FD_ZERO(&accept_s); FD_SET(s, &accept_s); if (diag_select(s+1, &accept_s, NULL, NULL, NULL) < 0) { return -1; } Debug3("accept(%d, %p, %p)", s, addr, addrlen); result = accept(s, addr, addrlen); _errno = errno; if (!diag_in_handler) diag_flush(); if (result >= 0) { char infobuff[256]; sockaddr_info(addr, *addrlen, infobuff, sizeof(infobuff)); Info5("accept(%d, {%d, %s}, "F_socklen") -> %d", s, addr->sa_family, sockaddr_info(addr, *addrlen, infobuff, sizeof(infobuff)), *addrlen, result); } else { Debug1("accept(,,) -> %d", result); } errno = _errno; return result; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int Getsockname(int s, struct sockaddr *name, socklen_t *namelen) { int result, _errno; char infobuff[256]; Debug4("getsockname(%d, %p, %p{"F_socklen"})", s, name, namelen, *namelen); result = getsockname(s, name, namelen); _errno = errno; /*Debug2("getsockname(,, {"F_socklen"}) -> %d", *namelen, result);*/ Debug3("getsockname(, {%s}, {"F_socklen"}) -> %d", sockaddr_info(name, *namelen, infobuff, sizeof(infobuff)), *namelen, result); errno = _errno; return result; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int Getpeername(int s, struct sockaddr *name, socklen_t *namelen) { int result, _errno; char infobuff[256]; Debug4("getpeername(%d, %p, %p{"F_socklen"})", s, name, namelen, *namelen); result = getpeername(s, name, namelen); _errno = errno; sockaddr_info(name, *namelen, infobuff, sizeof(infobuff)); Debug3("getpeername(, {%s}, {"F_socklen"}) -> %d", infobuff, *namelen, result); errno = _errno; return result; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int Getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) { int result, _errno; Debug5("getsockopt(%d, %d, %d, %p, {"F_socklen"})", s, level, optname, optval, *optlen); result = getsockopt(s, level, optname, optval, optlen); _errno = errno; Debug3("getsockopt() -> (,,, 0x%08x, %d), %d", *(int *)optval, *optlen, result); errno = _errno; return result; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int Setsockopt(int s, int level, int optname, const void *optval, int optlen) { int result, _errno; if (optlen <= sizeof(int)) { Debug5("setsockopt(%d, %d, %d, {0x%x}, %d)", s, level, optname, *(unsigned int *)optval, optlen); } else { Debug6("setsockopt(%d, %d, %d, {0x%08x,%08x}, %d)", s, level, optname, ((unsigned int *)optval)[0], ((unsigned int *)optval)[1], optlen); } result = setsockopt(s, level, optname, optval, optlen); _errno = errno; Debug1("setsockopt() -> %d", result); errno = _errno; return result; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int Recv(int s, void *buf, size_t len, int flags) { int retval, _errno; if (!diag_in_handler) diag_flush(); Debug4("recv(%d, %p, "F_Zu", %d)", s, buf, len, flags); retval = recv(s, buf, len, flags); _errno = errno; if (!diag_in_handler) diag_flush(); Debug1("recv() -> %d", retval); errno = _errno; return retval; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int Recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) { int retval, _errno; char infobuff[256]; if (!diag_in_handler) diag_flush(); Debug6("recvfrom(%d, %p, "F_Zu", %d, %p, "F_socklen")", s, buf, len, flags, from, *fromlen); retval = recvfrom(s, buf, len, flags, from, fromlen); _errno = errno; if (!diag_in_handler) diag_flush(); if (from) { Debug4("recvfrom(,,,, {%d,%s}, "F_socklen") -> %d", from->sa_family, sockaddr_info(from, *fromlen, infobuff, sizeof(infobuff)), *fromlen, retval); } else { Debug1("recvfrom(,,,, NULL, NULL) -> %d", retval); } errno = _errno; return retval; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int Recvmsg(int s, struct msghdr *msgh, int flags) { int retval, _errno; if (!diag_in_handler) diag_flush(); char infobuff[256]; #if defined(HAVE_STRUCT_MSGHDR_MSGCONTROL) && defined(HAVE_STRUCT_MSGHDR_MSGCONTROLLEN) && defined(HAVE_STRUCT_MSGHDR_MSGFLAGS) Debug10("recvmsg(%d, %p{%p,%u,%p,"F_Zu",%p,"F_Zu",%d}, %d)", s, msgh, msgh->msg_name, msgh->msg_namelen, msgh->msg_iov, msgh->msg_iovlen, msgh->msg_control, msgh->msg_controllen, msgh->msg_flags, flags); #else Debug7("recvmsg(%d, %p{%p,%u,%p,%u}, %d)", s, msgh, msgh->msg_name, msgh->msg_namelen, msgh->msg_iov, msgh->msg_iovlen, flags); #endif retval = recvmsg(s, msgh, flags); _errno = errno; if (!diag_in_handler) diag_flush(); #if defined(HAVE_STRUCT_MSGHDR_MSGCONTROLLEN) Debug5("recvmsg(, {%s,%u,,"F_Zu",,"F_Zu",}, ) -> %d", msgh->msg_name?sockaddr_info(msgh->msg_name, msgh->msg_namelen, infobuff, sizeof(infobuff)):"NULL", msgh->msg_namelen, msgh->msg_iovlen, msgh->msg_controllen, retval); #else Debug4("recvmsg(, {%s,%u,,%u,,}, ) -> %d", msgh->msg_name?sockaddr_info(msgh->msg_name, msgh->msg_namelen, infobuff, sizeof(infobuff)):"NULL", msgh->msg_namelen, msgh->msg_iovlen, retval); #endif errno = _errno; return retval; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int Send(int s, const void *mesg, size_t len, int flags) { int retval, _errno; if (!diag_in_handler) diag_flush(); Debug5("send(%d, %p[%08x...], "F_Zu", %d)", s, mesg, ntohl(*(unsigned long *)mesg), len, flags); retval = send(s, mesg, len, flags); _errno = errno; if (!diag_in_handler) diag_flush(); Debug1("send() -> %d", retval); errno = _errno; return retval; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int Sendto(int s, const void *mesg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) { int retval, _errno; char infobuff[256]; if (!diag_in_handler) diag_flush(); sockaddr_info(to, tolen, infobuff, sizeof(infobuff)); Debug7("sendto(%d, %p[%08x...], "F_Zu", %d, {%s}, %d)", s, mesg, htonl(*(unsigned long *)mesg), len, flags, infobuff, tolen); retval = sendto(s, mesg, len, flags, to, tolen); _errno = errno; if (!diag_in_handler) diag_flush(); Debug1("sendto() -> %d", retval); errno = _errno; return retval; } #endif /* _WITH_SOCKET */ #if _WITH_SOCKET int Shutdown(int fd, int how) { int retval, _errno; Info2("shutdown(%d, %d)", fd, how); retval = shutdown(fd, how); _errno = errno; Debug1("shutdown() -> %d", retval); errno = _errno; return retval; } #endif /* _WITH_SOCKET */ unsigned int Sleep(unsigned int seconds) { unsigned int retval; Debug1("sleep(%u)", seconds); retval = sleep(seconds); Debug1("sleep() -> %u", retval); return retval; } /* obsolete by POSIX.1-2001 */ void Usleep(unsigned long usec) { Debug1("usleep(%lu)", usec); usleep(usec); Debug("usleep() ->"); return; } #if HAVE_NANOSLEEP unsigned int Nanosleep(const struct timespec *req, struct timespec *rem) { int retval, _errno; Debug3("nanosleep({"F_time",%ld},%p)", req->tv_sec, req->tv_nsec, rem); retval = nanosleep(req, rem); _errno = errno; if (rem) { Debug3("nanosleep(,{"F_time",%ld}) -> %d", rem->tv_sec, rem->tv_nsec, retval); } else { Debug1("nanosleep() -> %d", retval); } errno = _errno; return retval; } #endif /* HAVE_NANOSLEEP */ int Pause(void) { int retval, _errno; Debug("pause()"); retval = pause(); _errno = errno; Debug1("pause() -> %d", retval); errno = _errno; return retval; } #if WITH_IP4 || WITH_IP6 struct hostent *Gethostbyname(const char *name) { struct hostent *hent; Debug1("gethostbyname(\"%s\")", name); hent = gethostbyname(name); if (hent == NULL) { Debug("gethostbyname() -> NULL"); } else { Debug4("gethostbyname() -> %d.%d.%d.%d", ((unsigned char *)hent->h_addr_list[0])[0], ((unsigned char *)hent->h_addr_list[0])[1], ((unsigned char *)hent->h_addr_list[0])[2], ((unsigned char *)hent->h_addr_list[0])[3]); } return hent; } #endif /* WITH_IP4 || WITH_IP6 */ #if (_WITH_IP4 || _WITH_IP6) && HAVE_GETADDRINFO int Getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { int result; Debug15("getaddrinfo(%s%s%s, %s%s%s, {%d,%d,%d,%d,"F_socklen",%p,%p,%p}, %p)", node?"\"":"", node?node:"NULL", node?"\"":"", service?"\"":"", service?service:"NULL", service?"\"":"", hints->ai_flags, hints->ai_family, hints->ai_socktype, hints->ai_protocol, hints->ai_addrlen, hints->ai_addr, hints->ai_canonname, hints->ai_next, res); result = getaddrinfo(node, service, hints, res); if (result == 0) { char sockbuff[256]; sockaddr_info((*res)->ai_addr, hints->ai_addrlen, sockbuff, sizeof(sockbuff)); Debug2("getaddrinfo(,,,{{%s, %s}) -> 0", sockbuff, (*res)->ai_canonname?(*res)->ai_canonname:""); } else { Debug2("getaddrinfo(,,,{%p}) -> %d", *res, result); } return result; } #endif /* (_WITH_IP4 || _WITH_IP6) && HAVE_GETADDRINFO */ #if (WITH_IP4 || WITH_IP6) && HAVE_PROTOTYPE_LIB_getipnodebyname struct hostent *Getipnodebyname(const char *name, int af, int flags, int *error_num) { struct hostent *result; Debug4("getipnodebyname(\"%s\", %d, %d, %p)", name, af, flags, error_num); result = getipnodebyname(name, af, flags, error_num); if (result == NULL) { Debug1("getipnodebyname(,,, {%d}) -> NULL", *error_num); } else { Debug4("getipnodebyname() -> {\"%s\", %p, %d, %d, ???}", result->h_name, result->h_aliases, result->h_addrtype, result->h_length); } return result; } #endif /* (WITH_IP4 || WITH_IP6) && HAVE_PROTOTYPE_LIB_getipnodebyname */ void *Malloc(size_t size) { void *result; Debug1("malloc("F_Zd")", size); result = malloc(size); Debug1("malloc() -> %p", result); if (result == NULL) { Error1("malloc("F_Zd"): out of memory", size); return NULL; } return result; } void *Calloc(size_t nmemb, size_t size) { void *result; Debug2("calloc("F_Zd", "F_Zd")", nmemb, size); result = calloc(nmemb, size); Debug1("calloc() -> %p", result); if (result == NULL) { Error2("calloc("F_Zd", "F_Zd"): out of memory", nmemb, size); return NULL; } return result; } void *Realloc(void *ptr, size_t size) { void *result; Debug2("realloc(%p, "F_Zd")", ptr, size); result = realloc(ptr, size); Debug1("realloc() -> %p", result); if (result == NULL) { Error2("realloc(%p, "F_Zd"): out of memory", ptr, size); return NULL; } return result; } #if _WITH_TERMIOS int Tcgetattr(int fd, struct termios *termios_p) { int i, result, _errno; char chars[5*NCCS], *cp = chars; Debug2("tcgetattr(%d, %p)", fd, termios_p); result = tcgetattr(fd, termios_p); _errno = errno; for (i = 0; i < NCCS-1; ++i) { cp += sprintf(cp, "%02x,", termios_p->c_cc[i]); } sprintf(cp, "%02x", termios_p->c_cc[i]); Debug6("tcgetattr(, {%08x,%08x,%08x,%08x,%s}) -> %d", termios_p->c_iflag, termios_p->c_oflag, termios_p->c_cflag, termios_p->c_lflag, chars, result); errno = _errno; return result; } #endif /* _WITH_TERMIOS */ #if _WITH_TERMIOS int Tcsetattr(int fd, int optional_actions, struct termios *termios_p) { int i, result, _errno; char chars[5*NCCS], *cp = chars; for (i = 0; i < NCCS-1; ++i) { cp += sprintf(cp, "%02x,", termios_p->c_cc[i]); } sprintf(cp, "%02x", termios_p->c_cc[i]); Debug7("tcsetattr(%d, %d, {%08x,%08x,%08x,%08x,%s})", fd, optional_actions, termios_p->c_iflag, termios_p->c_oflag, termios_p->c_cflag, termios_p->c_lflag, chars); result = tcsetattr(fd, optional_actions, termios_p); _errno = errno; Debug1("tcsetattr() -> %d", result); errno = _errno; return result; } #endif /* _WITH_TERMIOS */ char *Ttyname(int fd) { char *result; int _errno; Debug1("ttyname(%d)", fd); result = ttyname(fd); _errno = errno; if (result) Debug1("ttyname() -> %s", result); else Debug("ttyname() -> NULL"); errno = _errno; return result; } int Isatty(int fd) { int result, _errno; Debug1("isatty(%d)", fd); result = isatty(fd); _errno = errno; Debug1("isatty() -> %d", result); errno = _errno; return result; } #if HAVE_OPENPTY int Openpty(int *ptyfd, int *ttyfd, char *ptyname, struct termios *termp, struct winsize *winp) { int result, _errno; Debug5("openpty(%p, %p, %p, %p, %p)", ptyfd, ttyfd, ptyname, termp, winp); result = openpty(ptyfd, ttyfd, ptyname, termp, winp); _errno = errno; Info4("openpty({%d}, {%d}, {\"%s\"},,) -> %d", *ptyfd, *ttyfd, ptyname, result); errno = _errno; return result; } #endif /* HAVE_OPENPTY */ #if HAVE_GRANTPT int Grantpt(int fd) { int result, _errno; Debug1("grantpt(%d)", fd); result = grantpt(fd); _errno = errno; Debug1("grantpt() -> %d", result); errno = _errno; return result; } #endif /* HAVE_GRANTPT */ #if HAVE_UNLOCKPT int Unlockpt(int fd) { int result, _errno; Debug1("unlockpt(%d)", fd); result = unlockpt(fd); _errno = errno; Debug1("unlockpt() -> %d", result); errno = _errno; return result; } #endif /* HAVE_UNLOCKPT */ #if HAVE_PROTOTYPE_LIB_ptsname /* AIX, not Linux */ char *Ptsname(int fd) { char *result; int _errno; Debug1("ptsname(%d)", fd); result = ptsname(fd); _errno = errno; if (result) Debug1("ptsname() -> %s", result); else Debug("ptsname() -> NULL"); errno = _errno; return result; } #endif /* HAVE_PROTOTYPE_LIB_ptsname */ int Uname(struct utsname *buf) { int result, _errno; Debug1("uname(%p)", buf); result = uname(buf); _errno = errno; #if UNAME_DOMAINNAME Debug6("uname({%s, %s, %s, %s, %s, %s})", buf->sysname, buf->nodename, buf->release, buf->version, buf->machine, buf->domainname); #else Debug5("uname({%s, %s, %s, %s, %s})", buf->sysname, buf->nodename, buf->release, buf->version, buf->machine); #endif errno = _errno; return result; } int Gethostname(char *name, size_t len) { int result, _errno; Debug2("gethostname(%p, "F_Zu")", name, len); result = gethostname(name, len); _errno = errno; Debug2("gethostname(\"%s\", ) -> %d", name, result); errno = _errno; return result; } /* due to Linux docu, it does not set errno */ int Atexit(void (*func)(void)) { int result; Debug1("atexit(%p)", func); result = atexit(func); Debug1("atexit() -> %d", result); return result; } void Exit(int status) { if (!diag_in_handler) diag_flush(); Debug1("exit(%d)", status); exit(status); } void Abort(void) { Debug("abort()"); abort(); } int Mkstemp(char *template) { int result, _errno; Debug1("mkstemp(\"%s\")", template); result = mkstemp(template); _errno = errno; Info2("mkstemp({%s}) -> %d", template, result); errno = _errno; return result; } int Setenv(const char *name, const char *value, int overwrite) { int result, _errno; Debug3("setenv(\"%s\", \"%s\", %d)", name, value, overwrite); result = setenv(name, value, overwrite); _errno = errno; Debug1("setenv() -> %d", result); errno = _errno; return result; } #if HAVE_UNSETENV /* on Linux it returns int but on FreeBSD void. we do not expect many errors, so we take void which works on all systems. */ void Unsetenv(const char *name) { int _errno; Debug1("unsetenv(\"%s\")", name); unsetenv(name); _errno = errno; Debug("unsetenv() ->"); errno = _errno; return; } #endif #if WITH_READLINE char *Readline(const char *prompt) { char *result; if (prompt) { Debug1("readline(\"%s\")", prompt); } else { Debug("readline(NULL)"); } result = readline(prompt); if (result) { Debug("readline() -> \"...\""); } else { Debug("readline() -> NULL"); } return result; } void Using_history(void) { Debug("using_history()"); using_history(); Debug("using_history() ->"); } int Read_history(const char *filename) { int result; if (filename) { Debug1("read_history(\"%s\")", filename); } else { Debug("read_history(NULL)"); } result = read_history(filename); if (result) { Debug1("read_history() -> %d", result); } else { Debug("read_history() -> 0"); } return result; } int Write_history(const char *filename) { int result; if (filename) { Debug1("write_history(\"%s\")", filename); } else { Debug("write_history(NULL)"); } result = write_history(filename); if (result) { Debug1("write_history() -> %d", result); } else { Debug("write_history() -> 0"); } return result; } int Append_history(int nelements, const char *filename) { int result; if (filename) { Debug2("append_history(%d, \"%s\")", nelements, filename); } else { Debug1("append_history(%d, NULL)", nelements); } result = append_history(nelements, filename); if (result) { Debug1("append_history() -> %d", result); } else { Debug("append_history() -> 0"); } return result; } int Where_history(void) { int result; Debug("where_history()"); result = where_history(); Debug1("where_history() -> %d", result); return result; } void Add_history(const char *string) { Debug1("add_history(\"%s\")", string); add_history(string); Debug("add_history() ->"); } #endif /* WITH_READLINE */ #endif /* WITH_SYCLS */ socat-1.7.3.1/xioopts.c0000644000201000020100000035612612460670272014454 0ustar gerhardgerhard/* source: xioopts.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for address options handling */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-unix.h" #include "xiomodes.h" #include "xiolockfile.h" #include "nestlex.h" bool xioopts_ignoregroups; #define IF_ANY(a,b) {a,b}, #if WITH_NAMED # define IF_NAMED(a,b) {a,b}, #else # define IF_NAMED(a,b) #endif #if WITH_PIPE || WITH_GOPEN # define IF_OPEN(a,b) {a,b}, #else # define IF_OPEN(a,b) #endif #if WITH_TERMIOS # define IF_TERMIOS(a,b) {a,b}, #else # define IF_TERMIOS(a,b) #endif #if WITH_EXEC # define IF_EXEC(a,b) {a,b}, #else # define IF_EXEC(a,b) #endif #if _WITH_SOCKET # define IF_SOCKET(a,b) {a,b}, #else # define IF_SOCKET(a,b) #endif #if WITH_LISTEN # define IF_LISTEN(a,b) {a,b}, #else # define IF_LISTEN(a,b) #endif #if (WITH_UDP || WITH_TCP) && WITH_LISTEN # define IF_RANGE(a,b) {a,b}, #else # define IF_RANGE(a,b) #endif #if WITH_IP4 || WITH_IP6 # define IF_IP(a,b) {a,b}, #else # define IF_IP(a,b) #endif #if WITH_IP6 # define IF_IP6(a,b) {a,b}, #else # define IF_IP6(a,b) #endif #if WITH_TCP|WITH_UDP # define IF_IPAPP(a,b) {a,b}, #else # define IF_IPAPP(a,b) #endif #if WITH_TCP # define IF_TCP(a,b) {a,b}, #else # define IF_TCP(a,b) #endif #if WITH_SCTP # define IF_SCTP(a,b) {a,b}, #else # define IF_SCTP(a,b) #endif #if WITH_SOCKS4 # define IF_SOCKS4(a,b) {a,b}, #else # define IF_SOCKS4(a,b) #endif #if WITH_PROXY # define IF_PROXY(a,b) {a,b}, #else # define IF_PROXY(a,b) #endif #if WITH_READLINE # define IF_READLINE(a,b) {a,b}, #else # define IF_READLINE(a,b) #endif #if WITH_PTY # define IF_PTY(a,b) {a,b}, #else # define IF_PTY(a,b) #endif #if WITH_OPENSSL # define IF_OPENSSL(a,b) {a,b}, #else # define IF_OPENSSL(a,b) #endif #if WITH_TUN # define IF_TUN(a,b) {a,b}, #else # define IF_TUN(a,b) #endif #if WITH_UNIX # define IF_UNIX(a,b) {a,b}, #else # define IF_UNIX(a,b) #endif #if WITH_RETRY # define IF_RETRY(a,b) {a,b}, #else # define IF_RETRY(a,b) #endif static int applyopt_offset(struct single *xfd, struct opt *opt); /* address options - keep this array strictly alphabetically sorted for binary search! */ /* NULL terminated */ const struct optname optionnames[] = { #if HAVE_RESOLV_H IF_IP ("aaonly", &opt_res_aaonly) #endif /* HAVE_RESOLV_H */ #ifdef TCP_ABORT_THRESHOLD /* HP_UX */ IF_TCP ("abort-threshold", &opt_tcp_abort_threshold) #endif #ifdef SO_ACCEPTCONN /* AIX433 */ IF_SOCKET ("acceptconn", &opt_so_acceptconn) #endif /* SO_ACCEPTCONN */ #ifdef IP_ADD_MEMBERSHIP IF_IP ("add-membership", &opt_ip_add_membership) #endif IF_TUN ("allmulti", &opt_iff_allmulti) #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE) IF_IPAPP ("allow-table", &opt_tcpwrap_hosts_allow_table) #endif IF_ANY ("append", &opt_append) #ifdef O_ASYNC IF_ANY ("async", &opt_async) #endif #ifdef SO_ATTACH_FILTER IF_SOCKET ("attach-filter", &opt_so_attach_filter) IF_SOCKET ("attachfilter", &opt_so_attach_filter) #endif #ifdef SO_AUDIT /* AIX 4.3.3 */ IF_SOCKET ("audit", &opt_so_audit) #endif /* SO_AUDIT */ #ifdef IPV6_AUTHHDR IF_IP6 ("authhdr", &opt_ipv6_authhdr) #endif IF_TUN ("automedia", &opt_iff_automedia) #ifdef CBAUD IF_TERMIOS("b0", &opt_b0) #ifdef B1000000 IF_TERMIOS("b1000000", &opt_b1000000) #endif IF_TERMIOS("b110", &opt_b110) #ifdef B115200 IF_TERMIOS("b115200", &opt_b115200) #endif #ifdef B1152000 IF_TERMIOS("b1152000", &opt_b1152000) #endif IF_TERMIOS("b1200", &opt_b1200) IF_TERMIOS("b134", &opt_b134) IF_TERMIOS("b150", &opt_b150) #ifdef B1500000 IF_TERMIOS("b1500000", &opt_b1500000) #endif IF_TERMIOS("b1800", &opt_b1800) IF_TERMIOS("b19200", &opt_b19200) IF_TERMIOS("b200", &opt_b200) #ifdef B2000000 IF_TERMIOS("b2000000", &opt_b2000000) #endif #ifdef B230400 IF_TERMIOS("b230400", &opt_b230400) #endif IF_TERMIOS("b2400", &opt_b2400) #ifdef B2500000 IF_TERMIOS("b2500000", &opt_b2500000) #endif IF_TERMIOS("b300", &opt_b300) #ifdef B3000000 IF_TERMIOS("b3000000", &opt_b3000000) #endif #ifdef B3500000 IF_TERMIOS("b3500000", &opt_b3500000) #endif #ifdef B3600 /* HP-UX */ IF_TERMIOS("b3600", &opt_b3600) #endif IF_TERMIOS("b38400", &opt_b38400) #ifdef B4000000 IF_TERMIOS("b4000000", &opt_b4000000) #endif #ifdef B460800 IF_TERMIOS("b460800", &opt_b460800) #endif IF_TERMIOS("b4800", &opt_b4800) IF_TERMIOS("b50", &opt_b50) #ifdef B500000 IF_TERMIOS("b500000", &opt_b500000) #endif #ifdef B57600 IF_TERMIOS("b57600", &opt_b57600) #endif #ifdef B576000 IF_TERMIOS("b576000", &opt_b576000) #endif IF_TERMIOS("b600", &opt_b600) #ifdef B7200 /* HP-UX */ IF_TERMIOS("b7200", &opt_b7200) #endif IF_TERMIOS("b75", &opt_b75) #ifdef B900 /* HP-UX */ IF_TERMIOS("b900", &opt_b900) #endif #ifdef B921600 IF_TERMIOS("b921600", &opt_b921600) #endif IF_TERMIOS("b9600", &opt_b9600) #endif /* defined(CBAUD) */ IF_LISTEN ("backlog", &opt_backlog) #ifdef O_BINARY IF_OPEN ("bin", &opt_o_binary) IF_OPEN ("binary", &opt_o_binary) #endif IF_SOCKET ("bind", &opt_bind) #ifdef SO_BINDTODEVICE IF_SOCKET ("bindtodevice", &opt_so_bindtodevice) #endif IF_TERMIOS("brkint", &opt_brkint) IF_SOCKET ("broadcast", &opt_so_broadcast) #ifdef BSDLY # ifdef BS0 IF_TERMIOS("bs0", &opt_bs0) # endif # ifdef BS1 IF_TERMIOS("bs1", &opt_bs1) # endif #endif #ifdef SO_BSDCOMPAT IF_SOCKET ("bsdcompat", &opt_so_bsdcompat) #endif #ifdef BSDLY IF_TERMIOS("bsdly", &opt_bsdly) #endif IF_ANY ("bytes", &opt_readbytes) IF_OPENSSL("cafile", &opt_openssl_cafile) IF_OPENSSL("capath", &opt_openssl_capath) IF_OPENSSL("cert", &opt_openssl_certificate) IF_OPENSSL("certificate", &opt_openssl_certificate) IF_TERMIOS("cfmakeraw", &opt_termios_cfmakeraw) IF_ANY ("chroot", &opt_chroot) IF_ANY ("chroot-early", &opt_chroot_early) /*IF_TERMIOS("cibaud", &opt_cibaud)*/ IF_OPENSSL("cipher", &opt_openssl_cipherlist) IF_OPENSSL("cipherlist", &opt_openssl_cipherlist) IF_OPENSSL("ciphers", &opt_openssl_cipherlist) #ifdef SO_CKSUMRECV IF_SOCKET ("cksumrecv", &opt_so_cksumrecv) #endif /* SO_CKSUMRECV */ /*IF_NAMED ("cleanup", &opt_cleanup)*/ IF_TERMIOS("clocal", &opt_clocal) IF_ANY ("cloexec", &opt_cloexec) IF_ANY ("close", &opt_end_close) IF_OPENSSL("cn", &opt_openssl_commonname) IF_OPENSSL("commonname", &opt_openssl_commonname) #if WITH_EXT2 && defined(EXT2_COMPR_FL) IF_ANY ("compr", &opt_ext2_compr) #endif #if OPENSSL_VERSION_NUMBER >= 0x00908000L IF_OPENSSL("compress", &opt_openssl_compress) #endif #ifdef TCP_CONN_ABORT_THRESHOLD /* HP_UX */ IF_TCP ("conn-abort-threshold", &opt_tcp_conn_abort_threshold) #endif IF_SOCKET ("connect-timeout", &opt_connect_timeout) IF_LISTEN ("cool-write", &opt_cool_write) IF_LISTEN ("coolwrite", &opt_cool_write) #ifdef TCP_CORK IF_TCP ("cork", &opt_tcp_cork) #endif IF_ANY ("cr", &opt_cr) #ifdef CRDLY # ifdef CR0 IF_TERMIOS("cr0", &opt_cr0) # endif # ifdef CR1 IF_TERMIOS("cr1", &opt_cr1) # endif # ifdef CR2 IF_TERMIOS("cr2", &opt_cr2) # endif # ifdef CR3 IF_TERMIOS("cr3", &opt_cr3) # endif # if CRDLY_SHIFT >= 0 IF_TERMIOS("crdly", &opt_crdly) # endif #endif /* defined(CRDLY) */ IF_TERMIOS("cread", &opt_cread) IF_OPEN ("creat", &opt_o_create) IF_OPEN ("create", &opt_o_create) IF_ANY ("crlf", &opt_crnl) IF_ANY ("crnl", &opt_crnl) IF_TERMIOS("crterase", &opt_echoe) IF_TERMIOS("crtkill", &opt_echoke) #ifdef CRTSCTS IF_TERMIOS("crtscts", &opt_crtscts) #endif IF_TERMIOS("cs5", &opt_cs5) IF_TERMIOS("cs6", &opt_cs6) IF_TERMIOS("cs7", &opt_cs7) IF_TERMIOS("cs8", &opt_cs8) #if CSIZE_SHIFT >= 0 IF_TERMIOS("csize", &opt_csize) #endif IF_TERMIOS("cstopb", &opt_cstopb) IF_TERMIOS("ctlecho", &opt_echoctl) IF_TERMIOS("ctty", &opt_tiocsctty) IF_EXEC ("dash", &opt_dash) IF_SOCKET ("debug", &opt_so_debug) /*IF_IP ("debug", &opt_res_debug)*/ #ifdef O_DEFER IF_OPEN ("defer", &opt_o_defer) #endif #ifdef TCP_DEFER_ACCEPT /* Linux 2.4.0 */ IF_TCP ("defer-accept", &opt_tcp_defer_accept) #endif #if HAVE_RESOLV_H IF_IP ("defnames", &opt_res_defnames) #endif /* HAVE_RESOLV_H */ #ifdef O_DELAY IF_OPEN ("delay", &opt_o_delay) #endif IF_NAMED ("delete", &opt_unlink) #if WITH_LIBWRAP && defined(HAVE_HOSTS_DENY_TABLE) IF_IPAPP ("deny-table", &opt_tcpwrap_hosts_deny_table) #endif #ifdef SO_DETACH_FILTER IF_SOCKET ("detach-filter", &opt_so_detach_filter) IF_SOCKET ("detachfilter", &opt_so_detach_filter) #endif #ifdef SO_DGRAM_ERRIND IF_SOCKET ("dgram-errind", &opt_so_dgram_errind) IF_SOCKET ("dgramerrind", &opt_so_dgram_errind) #endif IF_OPENSSL("dh", &opt_openssl_dhparam) IF_OPENSSL("dhparam", &opt_openssl_dhparam) #ifdef O_DIRECT IF_OPEN ("direct", &opt_o_direct) #endif #ifdef O_DIRECTORY IF_OPEN ("directory", &opt_o_directory) #endif #if WITH_EXT2 && defined(EXT2_DIRSYNC_FL) IF_ANY ("dirsync", &opt_ext2_dirsync) #endif #ifdef VDISCARD IF_TERMIOS("discard", &opt_vdiscard) #endif #if HAVE_RESOLV_H IF_IP ("dnsrch", &opt_res_dnsrch) #endif /* HAVE_RESOLV_H */ #ifdef SO_DONTLINGER IF_SOCKET ("dontlinger", &opt_so_dontlinger) #endif IF_SOCKET ("dontroute", &opt_so_dontroute) #ifdef IPV6_DSTOPTS IF_IP6 ("dstopts", &opt_ipv6_dstopts) #endif #ifdef VDSUSP /* HP-UX */ IF_TERMIOS("dsusp", &opt_vdsusp) #endif #ifdef O_DSYNC IF_OPEN ("dsync", &opt_o_dsync) #endif IF_TERMIOS("echo", &opt_echo) IF_TERMIOS("echoctl", &opt_echoctl) IF_TERMIOS("echoe", &opt_echoe) IF_TERMIOS("echok", &opt_echok) IF_TERMIOS("echoke", &opt_echoke) IF_TERMIOS("echonl", &opt_echonl) #ifdef ECHOPRT IF_TERMIOS("echoprt", &opt_echoprt) #endif IF_OPENSSL("egd", &opt_openssl_egd) IF_ANY ("end-close", &opt_end_close) IF_TERMIOS("eof", &opt_veof) IF_TERMIOS("eol", &opt_veol) IF_TERMIOS("eol2", &opt_veol2) IF_TERMIOS("erase", &opt_verase) IF_SOCKET ("error", &opt_so_error) IF_ANY ("escape", &opt_escape) IF_OPEN ("excl", &opt_o_excl) #if WITH_EXT2 && defined(EXT2_APPEND_FL) IF_ANY ("ext2-append", &opt_ext2_append) #endif #if WITH_EXT2 && defined(EXT2_COMPR_FL) IF_ANY ("ext2-compr", &opt_ext2_compr) #endif #if WITH_EXT2 && defined(EXT2_DIRSYNC_FL) IF_ANY ("ext2-dirsync", &opt_ext2_dirsync) #endif #if WITH_EXT2 && defined(EXT2_IMMUTABLE_FL) IF_ANY ("ext2-immutable", &opt_ext2_immutable) #endif #if WITH_EXT2 && defined(EXT2_JOURNAL_DATA_FL) IF_ANY ("ext2-journal-data", &opt_ext2_journal_data) #endif #if WITH_EXT2 && defined(EXT2_NOATIME_FL) IF_ANY ("ext2-noatime", &opt_ext2_noatime) #endif #if WITH_EXT2 && defined(EXT2_NODUMP_FL) IF_ANY ("ext2-nodump", &opt_ext2_nodump) #endif #if WITH_EXT2 && defined(EXT2_NOTAIL_FL) IF_ANY ("ext2-notail", &opt_ext2_notail) #endif #if WITH_EXT2 && defined(EXT2_SECRM_FL) IF_ANY ("ext2-secrm", &opt_ext2_secrm) #endif #if WITH_EXT2 && defined(EXT2_SYNC_FL) IF_ANY ("ext2-sync", &opt_ext2_sync) #endif #if WITH_EXT2 && defined(EXT2_TOPDIR_FL) IF_ANY ("ext2-topdir", &opt_ext2_topdir) #endif #if WITH_EXT2 && defined(EXT2_UNRM_FL) IF_ANY ("ext2-unrm", &opt_ext2_unrm) #endif #if WITH_EXT2 && defined(EXT2_APPEND_FL) IF_ANY ("ext3-append", &opt_ext2_append) #endif #if WITH_EXT2 && defined(EXT2_COMPR_FL) IF_ANY ("ext3-compr", &opt_ext2_compr) #endif #if WITH_EXT2 && defined(EXT2_DIRSYNC_FL) IF_ANY ("ext3-dirsync", &opt_ext2_dirsync) #endif #if WITH_EXT2 && defined(EXT2_IMMUTABLE_FL) IF_ANY ("ext3-immutable", &opt_ext2_immutable) #endif #if WITH_EXT2 && defined(EXT2_JOURNAL_DATA_FL) IF_ANY ("ext3-journal-data", &opt_ext2_journal_data) #endif #if WITH_EXT2 && defined(EXT2_NOATIME_FL) IF_ANY ("ext3-noatime", &opt_ext2_noatime) #endif #if WITH_EXT2 && defined(EXT2_NODUMP_FL) IF_ANY ("ext3-nodump", &opt_ext2_nodump) #endif #if WITH_EXT2 && defined(EXT2_NOTAIL_FL) IF_ANY ("ext3-notail", &opt_ext2_notail) #endif #if WITH_EXT2 && defined(EXT2_SECRM_FL) IF_ANY ("ext3-secrm", &opt_ext2_secrm) #endif #if WITH_EXT2 && defined(EXT2_SYNC_FL) IF_ANY ("ext3-sync", &opt_ext2_sync) #endif #if WITH_EXT2 && defined(EXT2_TOPDIR_FL) IF_ANY ("ext3-topdir", &opt_ext2_topdir) #endif #if WITH_EXT2 && defined(EXT2_UNRM_FL) IF_ANY ("ext3-unrm", &opt_ext2_unrm) #endif IF_ANY ("f-setlk", &opt_f_setlk_wr) IF_ANY ("f-setlk-rd", &opt_f_setlk_rd) IF_ANY ("f-setlk-wr", &opt_f_setlk_wr) IF_ANY ("f-setlkw", &opt_f_setlkw_wr) IF_ANY ("f-setlkw-rd", &opt_f_setlkw_rd) IF_ANY ("f-setlkw-wr", &opt_f_setlkw_wr) IF_EXEC ("fdin", &opt_fdin) IF_EXEC ("fdout", &opt_fdout) #ifdef FFDLY # ifdef FF0 IF_TERMIOS("ff0", &opt_ff0) # endif # ifdef FF1 IF_TERMIOS("ff1", &opt_ff1) # endif IF_TERMIOS("ffdly", &opt_ffdly) #endif #ifdef FIOSETOWN IF_SOCKET ("fiosetown", &opt_fiosetown) #endif #if WITH_FIPS IF_OPENSSL("fips", &opt_openssl_fips) #endif #if HAVE_FLOCK IF_ANY ("flock", &opt_flock_ex) IF_ANY ("flock-ex", &opt_flock_ex) IF_ANY ("flock-ex-nb", &opt_flock_ex_nb) IF_ANY ("flock-nb", &opt_flock_ex_nb) IF_ANY ("flock-sh", &opt_flock_sh) IF_ANY ("flock-sh-nb", &opt_flock_sh_nb) #endif #ifdef IPV4_FLOWINFO IF_IP6 ("flowinfo", &opt_ipv6_flowinfo) #endif IF_TERMIOS("flusho", &opt_flusho) IF_RETRY ("forever", &opt_forever) IF_LISTEN ("fork", &opt_fork) #ifdef IP_FREEBIND IF_IP ("freebind", &opt_ip_freebind) #endif #if HAVE_FTRUNCATE64 IF_ANY ("ftruncate", &opt_ftruncate64) #else IF_ANY ("ftruncate", &opt_ftruncate32) #endif IF_ANY ("ftruncate32", &opt_ftruncate32) #if HAVE_FTRUNCATE64 IF_ANY ("ftruncate64", &opt_ftruncate64) #endif IF_ANY ("gid", &opt_group) IF_NAMED ("gid-e", &opt_group_early) IF_ANY ("gid-l", &opt_group_late) IF_ANY ("group", &opt_group) IF_NAMED ("group-early", &opt_group_early) IF_ANY ("group-late", &opt_group_late) #ifdef IP_HDRINCL IF_IP ("hdrincl", &opt_ip_hdrincl) #endif IF_READLINE("history", &opt_history_file) IF_READLINE("history-file", &opt_history_file) #ifdef IPV6_HOPLIMIT IF_IP6 ("hoplimit", &opt_ipv6_hoplimit) #endif #ifdef IPV6_HOPOPTS IF_IP6 ("hopopts", &opt_ipv6_hopopts) #endif #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE) IF_IPAPP ("hosts-allow", &opt_tcpwrap_hosts_allow_table) #endif #if WITH_LIBWRAP && defined(HAVE_HOSTS_DENY_TABLE) IF_IPAPP ("hosts-deny", &opt_tcpwrap_hosts_deny_table) #endif IF_TERMIOS("hup", &opt_hupcl) IF_TERMIOS("hupcl", &opt_hupcl) #ifdef I_POP IF_ANY ("i-pop-all", &opt_streams_i_pop_all) #endif #ifdef I_PUSH IF_ANY ("i-push", &opt_streams_i_push) #endif IF_TERMIOS("icanon", &opt_icanon) IF_TERMIOS("icrnl", &opt_icrnl) IF_TERMIOS("iexten", &opt_iexten) #ifdef SO_BINDTODEVICE IF_SOCKET ("if", &opt_so_bindtodevice) #endif IF_TUN ("iff-allmulti", &opt_iff_allmulti) IF_TUN ("iff-automedia", &opt_iff_automedia) IF_TUN ("iff-broadcast", &opt_iff_broadcast) IF_TUN ("iff-debug", &opt_iff_debug) /*IF_TUN ("iff-dynamic", &opt_iff_dynamic)*/ IF_TUN ("iff-loopback", &opt_iff_loopback) IF_TUN ("iff-master", &opt_iff_master) IF_TUN ("iff-multicast", &opt_iff_multicast) IF_TUN ("iff-no-pi", &opt_iff_no_pi) IF_TUN ("iff-noarp", &opt_iff_noarp) IF_TUN ("iff-notrailers", &opt_iff_notrailers) IF_TUN ("iff-pointopoint", &opt_iff_pointopoint) IF_TUN ("iff-portsel", &opt_iff_portsel) IF_TUN ("iff-promisc", &opt_iff_promisc) IF_TUN ("iff-running", &opt_iff_running) IF_TUN ("iff-slave", &opt_iff_slave) IF_TUN ("iff-up", &opt_iff_up) IF_TERMIOS("ignbrk", &opt_ignbrk) IF_TERMIOS("igncr", &opt_igncr) /* you might need to terminate socat manually if you use this option: */ IF_PROXY ("ignorecr", &opt_ignorecr) IF_ANY ("ignoreeof", &opt_ignoreeof) IF_ANY ("ignoreof", &opt_ignoreeof) IF_TERMIOS("ignpar", &opt_ignpar) #if HAVE_RESOLV_H IF_IP ("igntc", &opt_res_igntc) #endif /* HAVE_RESOLV_H */ IF_TERMIOS("imaxbel", &opt_imaxbel) #if WITH_EXT2 && defined(EXT2_IMMUTABLE_FL) IF_ANY ("immutable", &opt_ext2_immutable) #endif #ifdef TCP_INFO /* Linux 2.4.0 */ IF_TCP ("info", &opt_tcp_info) #endif IF_TERMIOS("inlcr", &opt_inlcr) IF_TERMIOS("inpck", &opt_inpck) #ifdef SO_BINDTODEVICE IF_SOCKET ("interface", &opt_so_bindtodevice) #endif IF_RETRY ("interval", &opt_intervall) IF_RETRY ("intervall", &opt_intervall) IF_TERMIOS("intr", &opt_vintr) IF_ANY ("ioctl", &opt_ioctl_void) IF_ANY ("ioctl-bin", &opt_ioctl_bin) IF_ANY ("ioctl-int", &opt_ioctl_int) IF_ANY ("ioctl-intp", &opt_ioctl_intp) IF_ANY ("ioctl-string", &opt_ioctl_string) IF_ANY ("ioctl-void", &opt_ioctl_void) #ifdef IP_ADD_MEMBERSHIP IF_IP ("ip-add-membership", &opt_ip_add_membership) #endif #ifdef IP_FREEBIND IF_IP ("ip-freebind", &opt_ip_freebind) #endif #ifdef IP_HDRINCL IF_IP ("ip-hdrincl", &opt_ip_hdrincl) #endif #ifdef IP_ADD_MEMBERSHIP IF_IP ("ip-membership", &opt_ip_add_membership) #endif #ifdef IP_MTU IF_IP ("ip-mtu", &opt_ip_mtu) #endif #ifdef IP_MTU_DISCOVER IF_IP ("ip-mtu-discover", &opt_ip_mtu_discover) #endif IF_IP ("ip-multicast-if", &opt_ip_multicast_if) IF_IP ("ip-multicast-loop", &opt_ip_multicast_loop) IF_IP ("ip-multicast-ttl", &opt_ip_multicast_ttl) #ifdef IP_OPTIONS IF_IP ("ip-options", &opt_ip_options) #endif #ifdef IP_PKTINFO IF_IP ("ip-pktinfo", &opt_ip_pktinfo) #endif #ifdef IP_PKTOPTIONS IF_IP ("ip-pktoptions", &opt_ip_pktoptions) #endif #ifdef IP_RECVDSTADDR IF_IP ("ip-recvdstaddr", &opt_ip_recvdstaddr) #endif #ifdef IP_RECVERR IF_IP ("ip-recverr", &opt_ip_recverr) #endif #ifdef IP_RECVIF IF_IP ("ip-recvif", &opt_ip_recvif) #endif #ifdef IP_RECVOPTS IF_IP ("ip-recvopts", &opt_ip_recvopts) #endif #ifdef IP_RECVTOS IF_IP ("ip-recvtos", &opt_ip_recvtos) #endif #ifdef IP_RECVTTL IF_IP ("ip-recvttl", &opt_ip_recvttl) #endif #ifdef IP_RETOPTS IF_IP ("ip-retopts", &opt_ip_retopts) #endif #ifdef IP_ROUTER_ALERT IF_IP ("ip-router-alert", &opt_ip_router_alert) #endif IF_IP ("ip-tos", &opt_ip_tos) IF_IP ("ip-ttl", &opt_ip_ttl) #ifdef IP_FREEBIND IF_IP ("ipfreebind", &opt_ip_freebind) #endif #ifdef IP_HDRINCL IF_IP ("iphdrincl", &opt_ip_hdrincl) #endif #ifdef IP_MTU IF_IP ("ipmtu", &opt_ip_mtu) #endif #ifdef IP_MTU_DISCOVER IF_IP ("ipmtudiscover", &opt_ip_mtu_discover) #endif IF_IP ("ipmulticastloop", &opt_ip_multicast_loop) IF_IP ("ipmulticastttl", &opt_ip_multicast_ttl) #ifdef IP_OPTIONS IF_IP ("ipoptions", &opt_ip_options) #endif #ifdef IP_PKTINFO IF_IP ("ippktinfo", &opt_ip_pktinfo) #endif #ifdef IP_PKTOPTIONS IF_IP ("ippktoptions", &opt_ip_pktoptions) #endif #ifdef IP_RECVDSTADDR IF_IP ("iprecvdstaddr", &opt_ip_recvdstaddr) #endif #ifdef IP_RECVERR IF_IP ("iprecverr", &opt_ip_recverr) #endif #ifdef IP_RECVOPTS IF_IP ("iprecvopts", &opt_ip_recvopts) #endif #ifdef IP_RECVTOS IF_IP ("iprecvtos", &opt_ip_recvtos) #endif #ifdef IP_RECVTTL IF_IP ("iprecvttl", &opt_ip_recvttl) #endif #ifdef IP_RETOPTS IF_IP ("ipretopts", &opt_ip_retopts) #endif #ifdef IP_ROUTER_ALERT IF_IP ("iprouteralert", &opt_ip_router_alert) #endif IF_IP ("iptos", &opt_ip_tos) IF_IP ("ipttl", &opt_ip_ttl) #ifdef IPV6_JOIN_GROUP IF_IP6 ("ipv6-add-membership", &opt_ipv6_join_group) #endif #ifdef IPV6_AUTHHDR IF_IP6 ("ipv6-authhdr", &opt_ipv6_authhdr) #endif #ifdef IPV6_DSTOPTS IF_IP6 ("ipv6-dstopts", &opt_ipv6_dstopts) #endif #ifdef IPV4_FLOWINFO IF_IP6 ("ipv6-flowinfo", &opt_ipv6_flowinfo) #endif #ifdef IPV6_HOPLIMIT IF_IP6 ("ipv6-hoplimit", &opt_ipv6_hoplimit) #endif #ifdef IPV6_HOPOPTS IF_IP6 ("ipv6-hopopts", &opt_ipv6_hopopts) #endif #ifdef IPV6_JOIN_GROUP IF_IP6 ("ipv6-join-group", &opt_ipv6_join_group) #endif #ifdef IPV6_PKTINFO IF_IP6 ("ipv6-pktinfo", &opt_ipv6_pktinfo) #endif #ifdef IPV6_RECVDSTOPTS IF_IP6 ("ipv6-recvdstopts", &opt_ipv6_recvdstopts) #endif #ifdef IPV6_RECVERR IF_IP6 ("ipv6-recverr", &opt_ipv6_recverr) #endif #ifdef IPV6_RECVHOPLIMIT IF_IP6 ("ipv6-recvhoplimit", &opt_ipv6_recvhoplimit) #endif #ifdef IPV6_RECVHOPOPTS IF_IP6 ("ipv6-recvhopopts", &opt_ipv6_recvhopopts) #endif #ifdef IPV6_PATHMTU IF_IP6 ("ipv6-recvpathmtu", &opt_ipv6_recvpathmtu) #endif #ifdef IPV6_RECVPKTINFO IF_IP6 ("ipv6-recvpktinfo", &opt_ipv6_recvpktinfo) #endif #ifdef IPV6_RECVRTHDR IF_IP6 ("ipv6-recvrthdr", &opt_ipv6_recvrthdr) #endif #ifdef IPV6_RECVTCLASS IF_IP6 ("ipv6-recvtclass", &opt_ipv6_recvtclass) #endif #ifdef IPV6_RTHDR IF_IP6 ("ipv6-rthdr", &opt_ipv6_rthdr) #endif #ifdef IPV6_TCLASS IF_IP6 ("ipv6-tclass", &opt_ipv6_tclass) #endif IF_IP6 ("ipv6-unicast-hops", &opt_ipv6_unicast_hops) #ifdef IPV6_V6ONLY IF_IP6 ("ipv6-v6only", &opt_ipv6_v6only) IF_IP6 ("ipv6only", &opt_ipv6_v6only) #endif IF_TERMIOS("isig", &opt_isig) #if defined(HAVE_TERMIOS_ISPEED) && defined(ISPEED_OFFSET) && (ISPEED_OFFSET != -1) IF_TERMIOS("ispeed", &opt_ispeed) #endif IF_TERMIOS("istrip", &opt_istrip) #ifdef IUCLC IF_TERMIOS("iuclc", &opt_iuclc) #endif IF_TERMIOS("ixany", &opt_ixany) IF_TERMIOS("ixoff", &opt_ixoff) IF_TERMIOS("ixon", &opt_ixon) #ifdef IPV6_JOIN_GROUP IF_IP6 ("join-group", &opt_ipv6_join_group) #endif #if WITH_EXT2 && defined(EXT2_JOURNAL_DATA_FL) IF_ANY ("journal", &opt_ext2_journal_data) IF_ANY ("journal-data", &opt_ext2_journal_data) #endif IF_SOCKET ("keepalive", &opt_so_keepalive) #ifdef TCP_KEEPCNT /* Linux 2.4.0 */ IF_TCP ("keepcnt", &opt_tcp_keepcnt) #endif #ifdef TCP_KEEPIDLE /* Linux 2.4.0 */ IF_TCP ("keepidle", &opt_tcp_keepidle) #endif #ifdef TCP_KEEPINIT /* OSF1 */ IF_TCP ("keepinit", &opt_tcp_keepinit) #endif #ifdef TCP_KEEPINTVL /* Linux 2.4.0 */ IF_TCP ("keepintvl", &opt_tcp_keepintvl) #endif #ifdef SO_KERNACCEPT /* AIX 4.3.3 */ IF_SOCKET ("kernaccept", &opt_so_kernaccept) #endif /* SO_KERNACCEPT */ IF_OPENSSL("key", &opt_openssl_key) IF_TERMIOS("kill", &opt_vkill) #ifdef O_LARGEFILE IF_OPEN ("largefile", &opt_o_largefile) #endif #if WITH_LIBWRAP IF_IPAPP ("libwrap", &opt_tcpwrappers) #endif IF_SOCKET ("linger", &opt_so_linger) #ifdef TCP_LINGER2 /* Linux 2.4.0 */ IF_TCP ("linger2", &opt_tcp_linger2) #endif IF_PTY ("link", &opt_symbolic_link) IF_TERMIOS("lnext", &opt_vlnext) #if defined(F_SETLKW) IF_ANY ("lock", &opt_f_setlkw_wr) /* POSIX, first choice */ #elif defined(HAVE_FLOCK) IF_ANY ("lock", &opt_flock_ex) /* BSD, fallback */ #endif IF_ANY ("lockfile", &opt_lockfile) #if defined(F_SETLKW) IF_ANY ("lockw", &opt_f_setlkw_wr) /* POSIX, first choice */ #elif defined(HAVE_FLOCK) IF_ANY ("lockw", &opt_flock_ex_nb) /* BSD, fallback */ #endif IF_EXEC ("login", &opt_dash) IF_TUN ("loopback", &opt_iff_loopback) IF_IPAPP ("lowport", &opt_lowport) #if HAVE_LSEEK64 IF_ANY ("lseek", &opt_lseek64_set) #else IF_ANY ("lseek", &opt_lseek32_set) #endif IF_ANY ("lseek32", &opt_lseek32_set) IF_ANY ("lseek32-cur", &opt_lseek32_cur) IF_ANY ("lseek32-end", &opt_lseek32_end) IF_ANY ("lseek32-set", &opt_lseek32_set) #if HAVE_LSEEK64 IF_ANY ("lseek64", &opt_lseek64_set) IF_ANY ("lseek64-cur", &opt_lseek64_cur) IF_ANY ("lseek64-end", &opt_lseek64_end) IF_ANY ("lseek64-set", &opt_lseek64_set) #endif IF_TUN ("master", &opt_iff_master) IF_LISTEN ("max-children", &opt_max_children) IF_LISTEN ("maxchildren", &opt_max_children) #ifdef TCP_MAXSEG IF_TCP ("maxseg", &opt_tcp_maxseg) IF_TCP ("maxseg-late", &opt_tcp_maxseg_late) #endif #ifdef TCP_MD5SUM IF_TCP ("md5sig", &opt_tcp_md5sig) #endif #ifdef IP_ADD_MEMBERSHIP IF_IP ("membership", &opt_ip_add_membership) #endif IF_OPENSSL("method", &opt_openssl_method) IF_TERMIOS("min", &opt_vmin) IF_ANY ("mode", &opt_perm) #ifdef TCP_MAXSEG IF_TCP ("mss", &opt_tcp_maxseg) IF_TCP ("mss-late", &opt_tcp_maxseg_late) #endif #ifdef IP_MTU IF_IP ("mtu", &opt_ip_mtu) #endif #ifdef IP_MTU_DISCOVER IF_IP ("mtudiscover", &opt_ip_mtu_discover) #endif IF_TUN ("multicast", &opt_iff_multicast) IF_IP ("multicast-if", &opt_ip_multicast_if) IF_IP ("multicast-loop", &opt_ip_multicast_loop) IF_IP ("multicast-ttl", &opt_ip_multicast_ttl) IF_IP ("multicastloop", &opt_ip_multicast_loop) IF_IP ("multicastttl", &opt_ip_multicast_ttl) #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK) IF_ANY ("ndelay", &opt_o_ndelay) #else IF_ANY ("ndelay", &opt_nonblock) #endif IF_NAMED ("new", &opt_unlink_early) #ifdef NLDLY # ifdef NL0 IF_TERMIOS("nl0", &opt_nl0) # endif # ifdef NL1 IF_TERMIOS("nl1", &opt_nl1) # endif IF_TERMIOS("nldly", &opt_nldly) #endif /* defined(NLDLY) */ #ifdef SO_NO_CHECK IF_SOCKET ("no-check", &opt_so_no_check) #endif IF_TUN ("no-pi", &opt_iff_no_pi) IF_TUN ("noarp", &opt_iff_noarp) #ifdef O_NOATIME IF_OPEN ("noatime", &opt_o_noatime) #endif #ifdef SO_NO_CHECK IF_SOCKET ("nocheck", &opt_so_no_check) #endif IF_OPEN ("noctty", &opt_o_noctty) #ifdef TCP_NODELAY IF_TCP ("nodelay", &opt_tcp_nodelay) #endif #if WITH_EXT2 && defined(EXT2_NODUMP_FL) IF_ANY ("nodump", &opt_ext2_nodump) #endif #if HAVE_REGEX_H IF_READLINE("noecho", &opt_noecho) #endif /* HAVE_REGEX_H */ IF_TERMIOS("noflsh", &opt_noflsh) #ifdef O_NOFOLLOW IF_OPEN ("nofollow", &opt_o_nofollow) #endif IF_EXEC ("nofork", &opt_nofork) #ifdef O_NOINHERIT IF_ANY ("noinherit", &opt_o_noinherit) #endif IF_ANY ("nonblock", &opt_nonblock) #ifdef TCP_NOOPT IF_TCP ("noopt", &opt_tcp_noopt) #endif IF_READLINE("noprompt", &opt_noprompt) #ifdef TCP_NOPUSH IF_TCP ("nopush", &opt_tcp_nopush) #endif #ifdef SO_NOREUSEADDR /* AIX 4.3.3 */ IF_SOCKET ("noreuseaddr", &opt_so_noreuseaddr) #endif /* SO_NOREUSEADDR */ IF_TUN ("notrailers", &opt_iff_notrailers) #ifdef O_NSHARE IF_OPEN ("nshare", &opt_o_nshare) #endif IF_SOCKET ("null-eof", &opt_null_eof) IF_ANY ("o-append", &opt_append) #ifdef O_ASYNC IF_ANY ("o-async", &opt_async) #endif #ifdef O_BINARY IF_OPEN ("o-binary", &opt_o_binary) #endif IF_OPEN ("o-creat", &opt_o_create) IF_OPEN ("o-create", &opt_o_create) #ifdef O_DEFER IF_OPEN ("o-defer", &opt_o_defer) #endif #ifdef O_DELAY IF_OPEN ("o-delay", &opt_o_delay) #endif #ifdef O_DIRECT IF_OPEN ("o-direct", &opt_o_direct) #endif #ifdef O_DIRECTORY IF_OPEN ("o-directory", &opt_o_directory) #endif #ifdef O_DSYNC IF_OPEN ("o-dsync", &opt_o_dsync) #endif IF_OPEN ("o-excl", &opt_o_excl) #ifdef O_LARGEFILE IF_OPEN ("o-largefile", &opt_o_largefile) #endif #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK) IF_ANY ("o-ndelay", &opt_o_ndelay) #else IF_ANY ("o-ndelay", &opt_nonblock) #endif #ifdef O_NOATIME IF_OPEN ("o-noatime", &opt_o_noatime) #endif IF_OPEN ("o-noctty", &opt_o_noctty) #ifdef O_NOFOLLOW IF_OPEN ("o-nofollow", &opt_o_nofollow) #endif #ifdef O_NOINHERIT IF_ANY ("o-noinherit", &opt_o_noinherit) #endif IF_ANY ("o-nonblock", &opt_nonblock) #ifdef O_NSHARE IF_OPEN ("o-nshare", &opt_o_nshare) #endif #ifdef O_PRIV IF_OPEN ("o-priv", &opt_o_priv) #endif IF_OPEN ("o-rdonly", &opt_o_rdonly) IF_OPEN ("o-rdwr", &opt_o_rdwr) #ifdef O_RSHARE IF_OPEN ("o-rshare", &opt_o_rshare) #endif #ifdef O_RSYNC IF_OPEN ("o-rsync", &opt_o_rsync) #endif #ifdef O_SYNC IF_OPEN ("o-sync", &opt_o_sync) #endif #ifdef O_TEXT IF_ANY ("o-text", &opt_o_text) #endif IF_OPEN ("o-trunc", &opt_o_trunc) IF_OPEN ("o-wronly", &opt_o_wronly) IF_OPEN ("o_create", &opt_o_create) #ifdef O_DEFER IF_OPEN ("o_defer", &opt_o_defer) #endif #ifdef O_DELAY IF_OPEN ("o_delay", &opt_o_delay) #endif #ifdef O_DIRECT IF_OPEN ("o_direct", &opt_o_direct) #endif #ifdef O_DIRECTORY IF_OPEN ("o_directory", &opt_o_directory) #endif #ifdef O_DSYNC IF_OPEN ("o_dsync", &opt_o_dsync) #endif IF_OPEN ("o_excl", &opt_o_excl) #ifdef O_LARGEFILE IF_OPEN ("o_largefile", &opt_o_largefile) #endif #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK) IF_ANY ("o_ndelay", &opt_o_ndelay) #else IF_ANY ("o_ndelay", &opt_nonblock) #endif IF_OPEN ("o_noctty", &opt_o_noctty) #ifdef O_NOFOLLOW IF_OPEN ("o_nofollow", &opt_o_nofollow) #endif #ifdef O_NSHARE IF_OPEN ("o_nshare", &opt_o_nshare) #endif #ifdef O_PRIV IF_OPEN ("o_priv", &opt_o_priv) #endif IF_OPEN ("o_rdonly", &opt_o_rdonly) IF_OPEN ("o_rdwr", &opt_o_rdwr) #ifdef O_RSHARE IF_OPEN ("o_rshare", &opt_o_rshare) #endif #ifdef O_RSYNC IF_OPEN ("o_rsync", &opt_o_rsync) #endif #ifdef O_SYNC IF_OPEN ("o_sync", &opt_o_sync) #endif IF_OPEN ("o_wronly", &opt_o_wronly) #ifdef OCRNL IF_TERMIOS("ocrnl", &opt_ocrnl) #endif #ifdef OFDEL IF_TERMIOS("ofdel", &opt_ofdel) #endif #ifdef OFILL IF_TERMIOS("ofill", &opt_ofill) #endif #ifdef OLCUC IF_TERMIOS("olcuc", &opt_olcuc) #endif IF_TERMIOS("onlcr", &opt_onlcr) #ifdef ONLRET IF_TERMIOS("onlret", &opt_onlret) #endif #ifdef ONOCR IF_TERMIOS("onocr", &opt_onocr) #endif IF_SOCKET ("oobinline", &opt_so_oobinline) #if HAVE_OPENPTY IF_EXEC ("openpty", &opt_openpty) #endif /* HAVE_OPENPTY */ IF_OPENSSL("openssl-cafile", &opt_openssl_cafile) IF_OPENSSL("openssl-capath", &opt_openssl_capath) IF_OPENSSL("openssl-certificate", &opt_openssl_certificate) IF_OPENSSL("openssl-cipherlist", &opt_openssl_cipherlist) IF_OPENSSL("openssl-commonname", &opt_openssl_commonname) #if OPENSSL_VERSION_NUMBER >= 0x00908000L IF_OPENSSL("openssl-compress", &opt_openssl_compress) #endif IF_OPENSSL("openssl-dhparam", &opt_openssl_dhparam) IF_OPENSSL("openssl-egd", &opt_openssl_egd) #if WITH_FIPS IF_OPENSSL("openssl-fips", &opt_openssl_fips) #endif IF_OPENSSL("openssl-key", &opt_openssl_key) IF_OPENSSL("openssl-method", &opt_openssl_method) IF_OPENSSL("openssl-pseudo", &opt_openssl_pseudo) IF_OPENSSL("openssl-verify", &opt_openssl_verify) IF_TERMIOS("opost", &opt_opost) #if defined(HAVE_TERMIOS_ISPEED) && defined(OSPEED_OFFSET) && (OSPEED_OFFSET != -1) IF_TERMIOS("ospeed", &opt_ospeed) #endif IF_ANY ("owner", &opt_user) IF_TERMIOS("parenb", &opt_parenb) IF_TERMIOS("parmrk", &opt_parmrk) IF_TERMIOS("parodd", &opt_parodd) #ifdef SO_PASSCRED IF_SOCKET ("passcred", &opt_so_passcred) #endif IF_EXEC ("path", &opt_path) #ifdef TCP_PAWS /* OSF1 */ IF_TCP ("paws", &opt_tcp_paws) #endif #ifdef SO_PEERCRED IF_SOCKET ("peercred", &opt_so_peercred) #endif #ifdef PENDIN IF_TERMIOS("pendin", &opt_pendin) #endif IF_ANY ("perm", &opt_perm) IF_NAMED ("perm-early", &opt_perm_early) IF_ANY ("perm-late", &opt_perm_late) IF_SOCKET ("pf", &opt_protocol_family) IF_EXEC ("pgid", &opt_setpgid) IF_EXEC ("pipes", &opt_pipes) #ifdef IP_PKTINFO IF_IP ("pktinfo", &opt_ip_pktinfo) #endif #ifdef IP_PKTOPTIONS IF_IP ("pktoptions", &opt_ip_pktoptions) IF_IP ("pktopts", &opt_ip_pktoptions) #endif IF_TUN ("pointopoint", &opt_iff_pointopoint) #ifdef I_POP IF_ANY ("pop-all", &opt_streams_i_pop_all) #endif /*IF_IPAPP("port", &opt_port)*/ IF_TUN ("portsel", &opt_iff_portsel) #if HAVE_RESOLV_H IF_IP ("primary", &opt_res_primary) #endif /* HAVE_RESOLV_H */ #ifdef SO_PRIORITY IF_SOCKET ("priority", &opt_so_priority) #endif #ifdef O_PRIV IF_OPEN ("priv", &opt_o_priv) #endif IF_TUN ("promisc", &opt_iff_promisc) IF_READLINE("prompt", &opt_prompt) #ifdef SO_PROTOTYPE IF_SOCKET ("protocol", &opt_so_prototype) #endif IF_SOCKET ("protocol-family", &opt_protocol_family) #ifdef SO_PROTOTYPE IF_SOCKET ("prototype", &opt_so_prototype) #endif IF_PROXY ("proxy-auth", &opt_proxy_authorization) IF_PROXY ("proxy-authorization", &opt_proxy_authorization) IF_PROXY ("proxy-resolve", &opt_proxy_resolve) IF_PROXY ("proxyauth", &opt_proxy_authorization) IF_PROXY ("proxyport", &opt_proxyport) #ifdef ECHOPRT IF_TERMIOS("prterase", &opt_echoprt) #endif IF_OPENSSL("pseudo", &opt_openssl_pseudo) #if HAVE_DEV_PTMX || HAVE_DEV_PTC IF_EXEC ("ptmx", &opt_ptmx) #endif #if HAVE_PTY IF_EXEC ("pty", &opt_pty) #endif #if HAVE_PTY && HAVE_POLL IF_PTY ("pty-interval", &opt_pty_intervall) IF_PTY ("pty-intervall", &opt_pty_intervall) IF_PTY ("pty-wait-slave", &opt_pty_wait_slave) #endif /* HAVE_PTY && HAVE_POLL */ #ifdef I_PUSH IF_ANY ("push", &opt_streams_i_push) #endif #ifdef TCP_QUICKACK IF_TCP ("quickack", &opt_tcp_quickack) #endif IF_TERMIOS("quit", &opt_vquit) IF_RANGE ("range", &opt_range) IF_TERMIOS("raw", &opt_raw) IF_TERMIOS("rawer", &opt_termios_rawer) IF_SOCKET ("rcvbuf", &opt_so_rcvbuf) IF_SOCKET ("rcvbuf-late", &opt_so_rcvbuf_late) #ifdef SO_RCVLOWAT IF_SOCKET ("rcvlowat", &opt_so_rcvlowat) #endif #ifdef SO_RCVTIMEO IF_SOCKET ("rcvtimeo", &opt_so_rcvtimeo) #endif IF_OPEN ("rdonly", &opt_o_rdonly) IF_OPEN ("rdwr", &opt_o_rdwr) IF_ANY ("readbytes", &opt_readbytes) #if HAVE_RESOLV_H IF_IP ("recurse", &opt_res_recurse) #endif /* HAVE_RESOLV_H */ #ifdef IP_RECVDSTADDR IF_IP ("recvdstaddr", &opt_ip_recvdstaddr) #endif #ifdef IPV6_RECVDSTOPTS IF_IP6 ("recvdstopts", &opt_ipv6_recvdstopts) #endif #ifdef IP_RECVERR IF_IP ("recverr", &opt_ip_recverr) #endif #ifdef IPV6_RECVHOPLIMIT IF_IP6 ("recvhoplimit", &opt_ipv6_recvhoplimit) #endif #ifdef IPV6_RECVHOPOPTS IF_IP6 ("recvhopopts", &opt_ipv6_recvhopopts) #endif #ifdef IP_RECVIF IF_IP ("recvif", &opt_ip_recvif) #endif #ifdef IP_RECVOPTS IF_IP ("recvopts", &opt_ip_recvopts) #endif #ifdef IPV6_RECVPKTINFO IF_IP6 ("recvpktinfo", &opt_ipv6_recvpktinfo) #endif #ifdef IPV6_RECVRTHDR IF_IP6 ("recvrthdr", &opt_ipv6_recvrthdr) #endif #ifdef IP_RECVTOS IF_IP ("recvtos", &opt_ip_recvtos) #endif #ifdef IP_RECVTTL IF_IP ("recvttl", &opt_ip_recvttl) #endif IF_NAMED ("remove", &opt_unlink) #ifdef VREPRINT IF_TERMIOS("reprint", &opt_vreprint) #endif #if HAVE_RESOLV_H IF_IP ("res-aaonly", &opt_res_aaonly) IF_IP ("res-debug", &opt_res_debug) IF_IP ("res-defnames", &opt_res_defnames) IF_IP ("res-dnsrch", &opt_res_dnsrch) IF_IP ("res-igntc", &opt_res_igntc) IF_IP ("res-primary", &opt_res_primary) IF_IP ("res-recurse", &opt_res_recurse) IF_IP ("res-stayopen", &opt_res_stayopen) IF_IP ("res-usevc", &opt_res_usevc) #endif /* HAVE_RESOLV_H */ IF_PROXY ("resolv", &opt_proxy_resolve) IF_PROXY ("resolve", &opt_proxy_resolve) #ifdef IP_RETOPTS IF_IP ("retopts", &opt_ip_retopts) #endif IF_RETRY ("retry", &opt_retry) IF_SOCKET ("reuseaddr", &opt_so_reuseaddr) #ifdef SO_REUSEPORT /* AIX 4.3.3 */ IF_SOCKET ("reuseport", &opt_so_reuseport) #endif /* defined(SO_REUSEPORT) */ #ifdef TCP_RFC1323 IF_TCP ("rfc1323", &opt_tcp_rfc1323) #endif #ifdef IP_ROUTER_ALERT IF_IP ("routeralert", &opt_ip_router_alert) #endif #ifdef VREPRINT IF_TERMIOS("rprnt", &opt_vreprint) #endif #ifdef O_RSHARE IF_OPEN ("rshare", &opt_o_rshare) #endif #ifdef O_RSYNC IF_OPEN ("rsync", &opt_o_rsync) #endif #ifdef IPV6_RTHDR IF_IP6 ("rthdr", &opt_ipv6_rthdr) #endif IF_TUN ("running", &opt_iff_running) #ifdef TCP_SACK_DISABLE IF_TCP ("sack-disable", &opt_tcp_sack_disable) #endif #ifdef TCP_SACKENA /* OSF1 */ IF_TCP ("sackena", &opt_tcp_sackena) #endif IF_TERMIOS("sane", &opt_sane) #ifdef SCTP_MAXSEG IF_SCTP ("sctp-maxseg", &opt_sctp_maxseg) IF_SCTP ("sctp-maxseg-late", &opt_sctp_maxseg_late) #endif #ifdef SCTP_NODELAY IF_SCTP ("sctp-nodelay", &opt_sctp_nodelay) #endif #if WITH_EXT2 && defined(EXT2_SECRM_FL) IF_ANY ("secrm", &opt_ext2_secrm) #endif #ifdef SO_SECURITY_AUTHENTICATION IF_SOCKET ("security-authentication", &opt_so_security_authentication) #endif #ifdef SO_SECURITY_ENCRYPTION_NETWORK IF_SOCKET ("security-encryption-network", &opt_so_security_encryption_network) #endif #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT IF_SOCKET ("security-encryption-transport", &opt_so_security_encryption_transport) #endif #ifdef SO_SECURITY_AUTHENTICATION IF_SOCKET ("securityauthentication", &opt_so_security_authentication) #endif #ifdef SO_SECURITY_ENCRYPTION_NETWORK IF_SOCKET ("securityencryptionnetwork", &opt_so_security_encryption_network) #endif #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT IF_SOCKET ("securityencryptiontransport", &opt_so_security_encryption_transport) #endif #if HAVE_LSEEK64 IF_ANY ("seek", &opt_lseek64_set) IF_ANY ("seek-cur", &opt_lseek64_cur) IF_ANY ("seek-end", &opt_lseek64_end) IF_ANY ("seek-set", &opt_lseek64_set) #else IF_ANY ("seek", &opt_lseek32_set) IF_ANY ("seek-cur", &opt_lseek32_cur) IF_ANY ("seek-end", &opt_lseek32_end) IF_ANY ("seek-set", &opt_lseek32_set) #endif IF_ANY ("setgid", &opt_setgid) IF_ANY ("setgid-early", &opt_setgid_early) IF_ANY ("setlk", &opt_f_setlk_wr) IF_ANY ("setlk-rd", &opt_f_setlk_rd) IF_ANY ("setlk-wr", &opt_f_setlk_wr) IF_ANY ("setlkw", &opt_f_setlkw_wr) IF_ANY ("setlkw-rd", &opt_f_setlkw_rd) IF_ANY ("setlkw-wr", &opt_f_setlkw_wr) IF_EXEC ("setpgid", &opt_setpgid) #if WITH_EXEC || WITH_SYSTEM IF_EXEC ("setsid", &opt_setsid) #endif IF_SOCKET ("setsockopt-bin", &opt_setsockopt_bin) IF_SOCKET ("setsockopt-int", &opt_setsockopt_int) IF_SOCKET ("setsockopt-string", &opt_setsockopt_string) IF_ANY ("setuid", &opt_setuid) IF_ANY ("setuid-early", &opt_setuid_early) IF_ANY ("shut-close", &opt_shut_close) IF_ANY ("shut-down", &opt_shut_down) IF_ANY ("shut-none", &opt_shut_none) IF_ANY ("shut-null", &opt_shut_null) #if WITH_EXEC || WITH_SYSTEM IF_ANY ("sid", &opt_setsid) #endif IF_EXEC ("sighup", &opt_sighup) IF_EXEC ("sigint", &opt_sigint) #ifdef TCP_SIGNATURE_ENABLE IF_TCP ("signature-enable", &opt_tcp_signature_enable) #endif IF_EXEC ("sigquit", &opt_sigquit) #ifdef SIOCSPGRP IF_SOCKET ("siocspgrp", &opt_siocspgrp) #endif IF_TUN ("slave", &opt_iff_slave) IF_SOCKET ("sndbuf", &opt_so_sndbuf) IF_SOCKET ("sndbuf-late", &opt_so_sndbuf_late) #ifdef SO_SNDLOWAT IF_SOCKET ("sndlowat", &opt_so_sndlowat) #endif #ifdef SO_SNDTIMEO IF_SOCKET ("sndtimeo", &opt_so_sndtimeo) #endif #ifdef SO_ACCEPTCONN /* AIX433 */ IF_SOCKET ("so-acceptconn", &opt_so_acceptconn) #endif /* SO_ACCEPTCONN */ #ifdef SO_ATTACH_FILTER IF_SOCKET ("so-attach-filter", &opt_so_attach_filter) #endif #ifdef SO_AUDIT /* AIX 4.3.3 */ IF_SOCKET ("so-audit", &opt_so_audit) #endif /* SO_AUDIT */ #ifdef SO_BINDTODEVICE IF_SOCKET ("so-bindtodevice", &opt_so_bindtodevice) #endif IF_SOCKET ("so-broadcast", &opt_so_broadcast) #ifdef SO_BSDCOMPAT IF_SOCKET ("so-bsdcompat", &opt_so_bsdcompat) #endif #ifdef SO_CKSUMRECV IF_SOCKET ("so-cksumrecv", &opt_so_cksumrecv) #endif /* SO_CKSUMRECV */ IF_SOCKET ("so-debug", &opt_so_debug) #ifdef SO_DETACH_FILTER IF_SOCKET ("so-detach-filter", &opt_so_detach_filter) #endif #ifdef SO_DGRAM_ERRIND IF_SOCKET ("so-dgram-errind", &opt_so_dgram_errind) #endif #ifdef SO_DONTLINGER IF_SOCKET ("so-dontlinger", &opt_so_dontlinger) #endif IF_SOCKET ("so-dontroute", &opt_so_dontroute) IF_SOCKET ("so-error", &opt_so_error) IF_SOCKET ("so-keepalive", &opt_so_keepalive) #ifdef SO_KERNACCEPT /* AIX 4.3.3 */ IF_SOCKET ("so-kernaccept", &opt_so_kernaccept) #endif /* SO_KERNACCEPT */ IF_SOCKET ("so-linger", &opt_so_linger) #ifdef SO_NO_CHECK IF_SOCKET ("so-no-check", &opt_so_no_check) #endif #ifdef SO_NOREUSEADDR /* AIX 4.3.3 */ IF_SOCKET ("so-noreuseaddr", &opt_so_noreuseaddr) #endif /* SO_NOREUSEADDR */ IF_SOCKET ("so-oobinline", &opt_so_oobinline) #ifdef SO_PASSCRED IF_SOCKET ("so-passcred", &opt_so_passcred) #endif #ifdef SO_PEERCRED IF_SOCKET ("so-peercred", &opt_so_peercred) #endif #ifdef SO_PRIORITY IF_SOCKET ("so-priority", &opt_so_priority) #endif #ifdef SO_PROTOTYPE IF_SOCKET ("so-prototype", &opt_so_prototype) #endif IF_SOCKET ("so-rcvbuf", &opt_so_rcvbuf) IF_SOCKET ("so-rcvbuf-late", &opt_so_rcvbuf_late) #ifdef SO_RCVLOWAT IF_SOCKET ("so-rcvlowat", &opt_so_rcvlowat) #endif #ifdef SO_RCVTIMEO IF_SOCKET ("so-rcvtimeo", &opt_so_rcvtimeo) #endif IF_SOCKET ("so-reuseaddr", &opt_so_reuseaddr) #ifdef SO_REUSEPORT /* AIX 4.3.3 */ IF_SOCKET ("so-reuseport", &opt_so_reuseport) #endif /* defined(SO_REUSEPORT) */ #ifdef SO_SECURITY_AUTHENTICATION IF_SOCKET ("so-security-authentication", &opt_so_security_authentication) #endif #ifdef SO_SECURITY_ENCRYPTION_NETWORK IF_SOCKET ("so-security-encryption-network", &opt_so_security_encryption_network) #endif #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT IF_SOCKET ("so-security-encryption-transport", &opt_so_security_encryption_transport) #endif IF_SOCKET ("so-sndbuf", &opt_so_sndbuf) IF_SOCKET ("so-sndbuf-late", &opt_so_sndbuf_late) #ifdef SO_SNDLOWAT IF_SOCKET ("so-sndlowat", &opt_so_sndlowat) #endif #ifdef SO_SNDTIMEO IF_SOCKET ("so-sndtimeo", &opt_so_sndtimeo) #endif #ifdef SO_TIMESTAMP IF_SOCKET ("so-timestamp", &opt_so_timestamp) #endif IF_SOCKET ("so-type", &opt_so_type) #ifdef SO_USE_IFBUFS IF_SOCKET ("so-use-ifbufs", &opt_so_use_ifbufs) #endif /* SO_USE_IFBUFS */ #ifdef SO_USELOOPBACK /* AIX433, Solaris */ IF_SOCKET ("so-useloopback", &opt_so_useloopback) #endif /* SO_USELOOPBACK */ IF_SOCKET ("sockopt-bin", &opt_setsockopt_bin) IF_SOCKET ("sockopt-int", &opt_setsockopt_int) IF_SOCKET ("sockopt-string", &opt_setsockopt_string) IF_SOCKS4 ("socksport", &opt_socksport) IF_SOCKS4 ("socksuser", &opt_socksuser) IF_SOCKET ("socktype", &opt_so_type) IF_IPAPP ("sourceport", &opt_sourceport) IF_IPAPP ("sp", &opt_sourceport) IF_TERMIOS("start", &opt_vstart) #if HAVE_RESOLV_H IF_IP ("stayopen", &opt_res_stayopen) #endif /* HAVE_RESOLV_H */ IF_EXEC ("stderr", &opt_stderr) #ifdef TCP_STDURG IF_TCP ("stdurg", &opt_tcp_stdurg) #endif IF_TERMIOS("stop", &opt_vstop) #ifdef I_POP IF_ANY ("streams-i-pop-all", &opt_streams_i_pop_all) #endif #ifdef I_PUSH IF_ANY ("streams-i-push", &opt_streams_i_push) #endif IF_ANY ("su", &opt_substuser) #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT) IF_ANY ("su-d", &opt_substuser_delayed) #endif IF_ANY ("su-e", &opt_substuser_early) IF_ANY ("substuser", &opt_substuser) #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT) IF_ANY ("substuser-delayed", &opt_substuser_delayed) #endif IF_ANY ("substuser-early", &opt_substuser_early) IF_TERMIOS("susp", &opt_vsusp) #ifdef VSWTC IF_TERMIOS("swtc", &opt_vswtc) IF_TERMIOS("swtch", &opt_vswtc) #endif IF_PTY ("symbolic-link", &opt_symbolic_link) #ifdef O_SYNC IF_OPEN ("sync", &opt_o_sync) #elif EXT2_SYNC_FL IF_ANY ("sync", &opt_ext2_sync) #endif #ifdef TCP_SYNCNT IF_TCP ("syncnt", &opt_tcp_syncnt) #endif #ifdef TABDLY # ifdef TAB0 IF_TERMIOS("tab0", &opt_tab0) # endif # ifdef TAB1 IF_TERMIOS("tab1", &opt_tab1) # endif # ifdef TAB2 IF_TERMIOS("tab2", &opt_tab2) # endif # ifdef TAB3 IF_TERMIOS("tab3", &opt_tab3) # endif # if TABDLY_SHIFT >= 0 IF_TERMIOS("tabdly", &opt_tabdly) # endif #endif IF_TERMIOS("tandem", &opt_ixoff) #ifdef TCP_ABORT_THRESHOLD /* HP_UX */ IF_TCP ("tcp-abort-threshold", &opt_tcp_abort_threshold) #endif #ifdef TCP_CONN_ABORT_THRESHOLD /* HP_UX */ IF_TCP ("tcp-conn-abort-threshold", &opt_tcp_conn_abort_threshold) #endif #ifdef TCP_CORK IF_TCP ("tcp-cork", &opt_tcp_cork) #endif #ifdef TCP_DEFER_ACCEPT /* Linux 2.4.0 */ IF_TCP ("tcp-defer-accept", &opt_tcp_defer_accept) #endif #ifdef TCP_INFO /* Linux 2.4.0 */ IF_TCP ("tcp-info", &opt_tcp_info) #endif #ifdef TCP_KEEPCNT /* Linux 2.4.0 */ IF_TCP ("tcp-keepcnt", &opt_tcp_keepcnt) #endif #ifdef TCP_KEEPIDLE /* Linux 2.4.0 */ IF_TCP ("tcp-keepidle", &opt_tcp_keepidle) #endif #ifdef TCP_KEEPINIT /* OSF1 */ IF_TCP ("tcp-keepinit", &opt_tcp_keepinit) #endif #ifdef TCP_KEEPINTVL /* Linux 2.4.0 */ IF_TCP ("tcp-keepintvl", &opt_tcp_keepintvl) #endif #ifdef TCP_LINGER2 /* Linux 2.4.0 */ IF_TCP ("tcp-linger2", &opt_tcp_linger2) #endif #ifdef TCP_MAXSEG IF_TCP ("tcp-maxseg", &opt_tcp_maxseg) IF_TCP ("tcp-maxseg-late", &opt_tcp_maxseg_late) #endif #ifdef TCP_MD5SIG IF_TCP ("tcp-md5sig", &opt_tcp_md5sig) #endif #ifdef TCP_NODELAY IF_TCP ("tcp-nodelay", &opt_tcp_nodelay) #endif #ifdef TCP_NOOPT IF_TCP ("tcp-noopt", &opt_tcp_noopt) #endif #ifdef TCP_NOPUSH IF_TCP ("tcp-nopush", &opt_tcp_nopush) #endif #ifdef TCP_PAWS /* OSF1 */ IF_TCP ("tcp-paws", &opt_tcp_paws) #endif #ifdef TCP_QUICKACK IF_TCP ("tcp-quickack", &opt_tcp_quickack) #endif #ifdef TCP_RFC1323 IF_TCP ("tcp-rfc1323", &opt_tcp_rfc1323) #endif #ifdef TCP_SACK_DISABLE IF_TCP ("tcp-sack-disable", &opt_tcp_sack_disable) #endif #ifdef TCP_SACKENA /* OSF1 */ IF_TCP ("tcp-sackena", &opt_tcp_sackena) #endif #ifdef TCP_SIGNATURE_ENABLE IF_TCP ("tcp-signature-enable", &opt_tcp_signature_enable) #endif #ifdef TCP_STDURG IF_TCP ("tcp-stdurg", &opt_tcp_stdurg) #endif #ifdef TCP_SYNCNT /* Linux 2.4.0 */ IF_TCP ("tcp-syncnt", &opt_tcp_syncnt) #endif #ifdef TCP_TSOPTENA /* OSF1 */ IF_TCP ("tcp-tsoptena", &opt_tcp_tsoptena) #endif #ifdef TCP_WINDOW_CLAMP /* Linux 2.4.0 */ IF_TCP ("tcp-window-clamp", &opt_tcp_window_clamp) #endif #if WITH_LIBWRAP IF_IPAPP ("tcpwrap", &opt_tcpwrappers) IF_IPAPP ("tcpwrap-dir", &opt_tcpwrap_etc) IF_IPAPP ("tcpwrap-etc", &opt_tcpwrap_etc) #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE) IF_IPAPP ("tcpwrap-hosts-allow-table", &opt_tcpwrap_hosts_allow_table) #endif #if WITH_LIBWRAP && defined(HAVE_HOSTS_DENY_TABLE) IF_IPAPP ("tcpwrap-hosts-deny-table", &opt_tcpwrap_hosts_deny_table) #endif IF_IPAPP ("tcpwrapper", &opt_tcpwrappers) IF_IPAPP ("tcpwrappers", &opt_tcpwrappers) #endif IF_TERMIOS("termios-cfmakeraw", &opt_termios_cfmakeraw) IF_TERMIOS("termios-rawer", &opt_termios_rawer) #ifdef O_TEXT IF_ANY ("text", &opt_o_text) #endif IF_UNIX ("tightsocklen", &xioopt_unix_tightsocklen) IF_TERMIOS("time", &opt_vtime) #ifdef SO_TIMESTAMP IF_SOCKET ("timestamp", &opt_so_timestamp) #endif IF_TERMIOS("tiocsctty", &opt_tiocsctty) #if WITH_EXT2 && defined(EXT2_TOPDIR_FL) IF_ANY ("topdir", &opt_ext2_topdir) #endif IF_IP ("tos", &opt_ip_tos) IF_TERMIOS("tostop", &opt_tostop) IF_OPEN ("trunc", &opt_o_trunc) #if HAVE_FTRUNCATE64 IF_ANY ("truncate", &opt_ftruncate64) #else IF_ANY ("truncate", &opt_ftruncate32) #endif #ifdef TCP_TSOPTENA /* OSF1 */ IF_TCP ("tsoptena", &opt_tcp_tsoptena) #endif IF_IP ("ttl", &opt_ip_ttl) IF_TUN ("tun-device", &opt_tun_device) IF_TUN ("tun-name", &opt_tun_name) IF_TUN ("tun-no-pi", &opt_iff_no_pi) IF_TUN ("tun-type", &opt_tun_type) IF_SOCKET ("type", &opt_so_type) IF_ANY ("uid", &opt_user) IF_NAMED ("uid-e", &opt_user_early) IF_ANY ("uid-l", &opt_user_late) IF_NAMED ("umask", &opt_umask) IF_IP6 ("unicast-hops", &opt_ipv6_unicast_hops) IF_UNIX ("unix-tightsocklen", &xioopt_unix_tightsocklen) IF_NAMED ("unlink", &opt_unlink) IF_NAMED ("unlink-close", &opt_unlink_close) IF_NAMED ("unlink-early", &opt_unlink_early) IF_NAMED ("unlink-late", &opt_unlink_late) #if WITH_EXT2 && defined(EXT2_UNRM_FL) IF_ANY ("unrm", &opt_ext2_unrm) #endif IF_TUN ("up", &opt_iff_up) #ifdef SO_USE_IFBUFS IF_SOCKET ("use-ifbufs", &opt_so_use_ifbufs) IF_SOCKET ("useifbufs", &opt_so_use_ifbufs) #endif /* SO_USE_IFBUFS */ #ifdef SO_USELOOPBACK /* AIX433, Solaris */ IF_SOCKET ("useloopback", &opt_so_useloopback) #endif /* SO_USELOOPBACK */ IF_ANY ("user", &opt_user) IF_NAMED ("user-early", &opt_user_early) IF_ANY ("user-late", &opt_user_late) #if HAVE_RESOLV_H IF_IP ("usevc", &opt_res_usevc) #endif /* HAVE_RESOLV_H */ #ifdef IPV6_V6ONLY IF_IP6 ("v6only", &opt_ipv6_v6only) #endif #ifdef VDISCARD IF_TERMIOS("vdiscard", &opt_vdiscard) #endif #ifdef VDSUSP /* HP-UX */ IF_TERMIOS("vdsusp", &opt_vdsusp) #endif IF_TERMIOS("veof", &opt_veof) IF_TERMIOS("veol", &opt_veol) IF_TERMIOS("veol2", &opt_veol2) IF_TERMIOS("verase", &opt_verase) IF_OPENSSL("verify", &opt_openssl_verify) IF_TERMIOS("vintr", &opt_vintr) IF_TERMIOS("vkill", &opt_vkill) IF_TERMIOS("vlnext", &opt_vlnext) IF_TERMIOS("vmin", &opt_vmin) IF_TERMIOS("vquit", &opt_vquit) #ifdef VREPRINT IF_TERMIOS("vreprint", &opt_vreprint) #endif IF_TERMIOS("vstart", &opt_vstart) IF_TERMIOS("vstop", &opt_vstop) IF_TERMIOS("vsusp", &opt_vsusp) #ifdef VSWTC IF_TERMIOS("vswtc", &opt_vswtc) #endif #ifdef VTDLY # ifdef VT0 IF_TERMIOS("vt0", &opt_vt0) # endif # ifdef VT1 IF_TERMIOS("vt1", &opt_vt1) # endif IF_TERMIOS("vtdly", &opt_vtdly) #endif IF_TERMIOS("vtime", &opt_vtime) #ifdef VWERASE IF_TERMIOS("vwerase", &opt_vwerase) #endif #if HAVE_PTY && HAVE_POLL IF_PTY ("wait-slave", &opt_pty_wait_slave) #endif /* HAVE_PTY && HAVE_POLL */ IF_ANY ("waitlock", &opt_waitlock) #if HAVE_PTY && HAVE_POLL IF_PTY ("waitslave", &opt_pty_wait_slave) #endif /* HAVE_PTY && HAVE_POLL */ #ifdef VWERASE IF_TERMIOS("werase", &opt_vwerase) #endif #ifdef TCP_WINDOW_CLAMP /* Linux 2.4.0 */ IF_TCP ("window-clamp", &opt_tcp_window_clamp) #endif #if WITH_LIBWRAP IF_IPAPP ("wrap", &opt_tcpwrappers) #endif IF_OPEN ("wronly", &opt_o_wronly) #ifdef XCASE IF_TERMIOS("xcase", &opt_xcase) #endif #if defined(TABDLY) && defined(XTABS) IF_TERMIOS("xtabs", &opt_xtabs) #endif { NULL } } ; /* walks the text argument a and writes its options that conform to groups to the array opts. Uses the option table 'optionnames'. returns 0 on success, -1 on error, 1 on unknown/wrong option */ int parseopts(const char **a, unsigned int groups, struct opt **opts) { return parseopts_table(a, groups, opts, optionnames, sizeof(optionnames)/sizeof(struct optname)-1); } /* walks the text argument a and writes its options that conform to groups to the array opts. Uses the specified option table. returns 0 on success, -1 on error, 1 on unknown/wrong option */ int parseopts_table(const char **a, unsigned int groups, struct opt **opts, const struct optname optionnames[], size_t optionnum) { int i=0; struct opt *opt; bool assign; const char *a0 = *a; unsigned long ulongval; long slongval; long long slonglongval; char token[512], *tokp; size_t len; int parsres; int result; char optbuf[256]; size_t optlen; const char *endkey[6+1]; const char *endval[5+1]; const char *assign_str = "="; const char *hquotes[] = { "'", NULL } ; const char *squotes[] = { "\"", NULL } ; const char *nests[] = { "(", ")", "[", "]", "{", "}", NULL } ; i = 0; /*endkey[i++] = xioopts.chainsep;*/ /* default: "|" */ endkey[i++] = xioopts.pipesep; /* default: "!!" */ endkey[i++] = ","/*xioopts.comma*/; /* default: "," */ endkey[i++] = "="; endkey[i++] = NULL; i = 0; /*endval[i++] = xioopts.chainsep;*/ /* default: "|" */ endval[i++] = xioopts.pipesep; /* default: "!!" */ endval[i++] = ","/*xioopts.comma*/; /* default: "," */ endval[i++] = NULL; i = 0; *opts = Malloc((i+8)*sizeof(struct opt)); if (*opts == NULL) { return -1; } if (*a == NULL) { (*opts)[i].desc = ODESC_END; return 0; } while (true) { const struct optname *ent; if (a == NULL || *a == NULL || **a == '\0') break; while (!strncmp(*a, ",", strlen(","))) { (*a) += strlen(","); } a0 = *a; len = sizeof(token); tokp = token; parsres = nestlex(a, &tokp, &len, endkey, hquotes, squotes, nests, true, true, false); if (parsres < 0) { Error1("option too long: \"%s\"", *a); return -1; } else if (parsres > 0) { Error1("syntax error in \"%s\"", *a); return -1; } if (tokp == token) { /* no option found */ break; } *tokp = '\0'; ent = (struct optname *) keyw((struct wordent *)optionnames, token, optionnum); if (ent == NULL) { Error1("parseopts(): unknown option \"%s\"", token); continue; } if (!(ent->desc->group & groups) && !(ent->desc->group & GROUP_ANY) && !xioopts_ignoregroups) { Error1("parseopts(): option \"%s\" not supported with this address type", token /*a0*/); Info2("parseopts() groups=%08x, ent->group=%08x", groups, ent->desc->group); #if 0 continue; #endif } (*opts)[i].desc = ent->desc; if (!strncmp(*a, assign_str, strlen(assign_str))) { /* there is an assignment (mostly "=") */ (*a) += strlen(assign_str); len = sizeof(token); tokp = token; parsres = nestlex(a, &tokp, &len, endval, hquotes, squotes, nests, true, true, false); if (parsres < 0) { Error1("option too long: \"%s\"", *a); return -1; } else if (parsres > 0) { Error1("syntax error in \"%s\"", *a); return -1; } *tokp = '\0'; assign = true; } else { assign = false; } opt = &(*opts)[i]; switch (ent->desc->type) { case TYPE_CONST: if (assign) { Error1("no value permitted for option \"%s\"", ent->desc->defname); continue; } Info1("setting option \"%s\"", ent->desc->defname); break; case TYPE_BIN: if (!assign) { Error1("option \"%s\": value required", a0); continue; } optlen = 0; if ((result = dalan(token, optbuf, &optlen, sizeof(optbuf))) != 0) { Error1("parseopts(): problem with \"%s\" data", token); continue; } if (((*opts)[i].value.u_bin.b_data = memdup(optbuf, optlen)) == NULL) { Error1("memdup(, "F_Zu"): out of memory", optlen); return -1; } (*opts)[i].value.u_bin.b_len = optlen; break; case TYPE_BYTE: if (assign) { unsigned long ul; char *rest; ul = strtoul(token, &rest/*!*/, 0); if (ul > UCHAR_MAX) { Error3("parseopts(%s): byte value exceeds limit (%lu vs. %u), using max", a0, ul, UCHAR_MAX); (*opts)[i].value.u_byte = UCHAR_MAX; } else { (*opts)[i].value.u_byte = ul; } } else { (*opts)[i].value.u_byte = 1; } Info2("setting option \"%s\" to %d", ent->desc->defname, (*opts)[i].value.u_byte); break; #if HAVE_BASIC_OFF_T==3 case TYPE_OFF32: #endif case TYPE_INT: if (assign) { char *rest; (*opts)[i].value.u_int = strtoul(token, &rest/*!*/, 0); } else { (*opts)[i].value.u_int = 1; } Info2("setting option \"%s\" to %d", ent->desc->defname, (*opts)[i].value.u_int); break; case TYPE_BOOL: if (!assign) { (*opts)[i].value.u_bool = 1; } else { char *rest; (*opts)[i].value.u_bool = strtoul(token, &rest, 0); if (rest && *rest) { Error1("error in option \"%s\": \"0\" or \"1\" required", a0); } } Info2("setting option \"%s\" to %d", ent->desc->defname, (*opts)[i].value.u_bool); break; #if HAVE_BASIC_SIZE_T==4 case TYPE_SIZE_T: #endif case TYPE_UINT: if (!assign) { (*opts)[i].value.u_uint = 1; } else { char *rest; ulongval = strtoul(token, &rest/*!*/, 0); if (ulongval > UINT_MAX) { Error3("parseopts(%s): unsigned int value exceeds limit (%lu vs. %u), using max", a0, ulongval, UINT_MAX); } (*opts)[i].value.u_uint = ulongval; } Info2("setting option \"%s\" to %u", ent->desc->defname, (*opts)[i].value.u_uint); break; #if HAVE_BASIC_SIZE_T==2 case TYPE_SIZE_T: #endif case TYPE_USHORT: if (!assign) { (*opts)[i].value.u_ushort = 1; } else { char *rest; ulongval = strtoul(token, &rest/*!*/, 0); if (ulongval > USHRT_MAX) { Error3("parseopts(%s): unsigned short value exceeds limit (%lu vs. %u), using max", a0, ulongval, USHRT_MAX); } (*opts)[i].value.u_ushort = ulongval; } Info2("setting option \"%s\" to %u", ent->desc->defname, (*opts)[i].value.u_ushort); break; #if HAVE_BASIC_OFF_T==5 case TYPE_OFF32: #endif #if HAVE_STAT64 && defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T==5 case TYPE_OFF64: #endif case TYPE_LONG: if (!assign) { (*opts)[i].value.u_long = 1; } else { char *rest; slongval = strtol(token, &rest, 0); (*opts)[i].value.u_long = slongval; } Info2("setting option \"%s\" to %lu", ent->desc->defname, (*opts)[i].value.u_long); break; #if HAVE_BASIC_SIZE_T==6 case TYPE_SIZE_T: #endif case TYPE_ULONG: if (!assign) { (*opts)[i].value.u_ulong = 1; } else { char *rest; ulongval = strtoul(token, &rest, 0); (*opts)[i].value.u_ulong = ulongval; } Info2("setting option \"%s\" to %lu", ent->desc->defname, (*opts)[i].value.u_ulong); break; #if HAVE_BASIC_OFF_T==7 case TYPE_OFF32: #endif #if HAVE_TYPE_LONGLONG case TYPE_LONGLONG: # if HAVE_STAT64 && defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T==7 case TYPE_OFF64: # endif if (!assign) { (*opts)[i].value.u_longlong = 1; } else { char *rest; # if HAVE_STRTOLL slonglongval = strtoll(token, &rest, 0); # else /* in this case, input value range is limited */ slonglongval = strtol(token, &rest, 0); # endif /* HAVE_STRTOLL */ (*opts)[i].value.u_longlong = slonglongval; } Info2("setting option \"%s\" to %Lu", ent->desc->defname, (*opts)[i].value.u_longlong); break; #endif /* HAVE_TYPE_LONGLONG */ case TYPE_UIDT: if (!assign) { Error1("option \"%s\": value required", a0); continue; } if (isdigit((*token)&0xff)) { char *rest; (*opts)[i].value.u_uidt = strtoul(token, &rest/*!*/, 0); } else { struct passwd *pwd; if ((pwd = getpwnam(token)) == NULL) { Error1("getpwnam(\"%s\"): no such user", token); continue; } (*opts)[i].value.u_uidt = getpwnam(token)->pw_uid; } Info2("setting option \"%s\" to %u", ent->desc->defname, (*opts)[i].value.u_uidt); break; case TYPE_GIDT: if (!assign) { Error1("option \"%s\": value required", a0); continue; } if (isdigit((token[0])&0xff)) { char *rest; (*opts)[i].value.u_gidt = strtoul(token, &rest/*!*/, 0); } else { struct group *grp; grp = getgrnam(token); if (grp == NULL) { Error1("getgrnam(\"%s\"): no such group", token); continue; } (*opts)[i].value.u_gidt = grp->gr_gid; } Info2("setting option \"%s\" to %u", ent->desc->defname, (*opts)[i].value.u_gidt); break; case TYPE_MODET: if (!assign) { Error1("option \"%s\": value required", a0); continue; } { char *rest; (*opts)[i].value.u_modet = strtoul(token, &rest/*!*/, 8); } Info2("setting option \"%s\" to %u", ent->desc->defname, (*opts)[i].value.u_modet); break; case TYPE_STRING: if (!assign) { Error1("option \"%s\": value required", a0); continue; } if (((*opts)[i].value.u_string = strdup(token)) == NULL) { Error("out of memory"); return -1; } Info2("setting option \"%s\" to \"%s\"", ent->desc->defname, (*opts)[i].value.u_string); break; case TYPE_STRING_NULL: if (!assign) { (*opts)[i].value.u_string = NULL; Info1("setting option \"%s\" to NULL", ent->desc->defname); } else { (*opts)[i].value.u_string = strdup(token); Info2("setting option \"%s\" to \"%s\"", ent->desc->defname, (*opts)[i].value.u_string); } break; #if LATER case TYPE_INT3: break; #endif case TYPE_TIMEVAL: if (!assign) { Error1("option \"%s\": value required", a0); continue; } else { double val; val = strtod(token, NULL); if (val == HUGE_VAL || val == -HUGE_VAL || val == 0.0 && errno == ERANGE) { Error2("strtod(\"%s\", NULL): %s", token, strerror(errno)); val = 0.0; } (*opts)[i].value.u_timeval.tv_sec = val; (*opts)[i].value.u_timeval.tv_usec = (val-(*opts)[i].value.u_timeval.tv_sec) * 1000000; } break; #if HAVE_STRUCT_TIMESPEC case TYPE_TIMESPEC: if (!assign) { Error1("option \"%s\": value required", a0); continue; } else { double val; val = strtod(token, NULL); if (val == HUGE_VAL || val == -HUGE_VAL || val == 0.0 && errno == ERANGE) { Error2("strtod(\"%s\", NULL): %s", token, strerror(errno)); val = 0.0; } (*opts)[i].value.u_timespec.tv_sec = val; (*opts)[i].value.u_timespec.tv_nsec = (val-(*opts)[i].value.u_timespec.tv_sec) * 1000000000.; } break; #endif /* HAVE_STRUCT_TIMESPEC */ #if HAVE_STRUCT_LINGER case TYPE_LINGER: if (!assign) { Error1("option \"%s\": value required", a0); continue; } (*opts)[i].value.u_linger.l_onoff = 1; { char *rest; (*opts)[i].value.u_linger.l_linger = strtoul(token, &rest/*!*/, 0); } Info3("setting option \"%s\" to {%d,%d}", ent->desc->defname, (*opts)[i].value.u_linger.l_onoff, (*opts)[i].value.u_linger.l_linger); break; #endif /* HAVE_STRUCT_LINGER */ case TYPE_INT_INT: case TYPE_INT_INTP: if (!assign) { Error1("option \"%s\": values required", a0); continue; } { char *rest; (*opts)[i].value.u_int = strtoul(token, &rest, 0); if (*rest != ':') { Error1("option \"%s\": 2 arguments required", ent->desc->defname); } ++rest; (*opts)[i].value2.u_int = strtoul(rest, &rest, 0); } Info3("setting option \"%s\" to %d:%d", ent->desc->defname, (*opts)[i].value.u_int, (*opts)[i].value2.u_int); break; case TYPE_INT_BIN: if (!assign) { Error1("option \"%s\": values required", a0); continue; } { char *rest; (*opts)[i].value.u_int = strtoul(token, &rest, 0); if (*rest != ':') { Error1("option \"%s\": 2 arguments required", ent->desc->defname); } ++rest; optlen = 0; if ((result = dalan(rest, optbuf, &optlen, sizeof(optbuf))) != 0) { Error1("parseopts(): problem with \"%s\" data", rest); continue; } if (((*opts)[i].value2.u_bin.b_data = memdup(optbuf, optlen)) == NULL) { Error1("memdup(, "F_Zu"): out of memory", optlen); return -1; } (*opts)[i].value2.u_bin.b_len = optlen; } Info2("setting option \"%s\" to %d:..."/*!!!*/, ent->desc->defname, (*opts)[i].value.u_int); break; case TYPE_INT_STRING: if (!assign) { Error1("option \"%s\": values required", a0); continue; } { char *rest; (*opts)[i].value.u_int = strtoul(token, &rest, 0); if (*rest != ':') { Error1("option \"%s\": 2 arguments required", ent->desc->defname); } ++rest; if (((*opts)[i].value2.u_string = strdup(rest)) == NULL) { Error("out of memory"); return -1; } } Info3("setting option \"%s\" to %d:\"%s\"", ent->desc->defname, (*opts)[i].value.u_int, (*opts)[i].value2.u_string); break; case TYPE_INT_INT_INT: if (!assign) { Error1("option \"%s\": values required", a0); continue; } { char *rest; (*opts)[i].value.u_int = strtoul(token, &rest, 0); if (*rest != ':') { Error1("option \"%s\": 3 arguments required", ent->desc->defname); } ++rest; (*opts)[i].value2.u_int = strtoul(rest, &rest, 0); if (*rest != ':') { Error1("option \"%s\": 3 arguments required", ent->desc->defname); } ++rest; (*opts)[i].value3.u_int = strtoul(rest, &rest, 0); } Info4("setting option \"%s\" to %d:%d:%d", ent->desc->defname, (*opts)[i].value.u_int, (*opts)[i].value2.u_int, (*opts)[i].value3.u_int); break; case TYPE_INT_INT_BIN: if (!assign) { Error1("option \"%s\": values required", a0); continue; } { char *rest; (*opts)[i].value.u_int = strtoul(token, &rest, 0); if (*rest != ':') { Error1("option \"%s\": 3 arguments required", ent->desc->defname); } ++rest; (*opts)[i].value2.u_int = strtoul(rest, &rest, 0); if (*rest != ':') { Error1("option \"%s\": 3 arguments required", ent->desc->defname); } ++rest; optlen = 0; if ((result = dalan(rest, optbuf, &optlen, sizeof(optbuf))) != 0) { Error1("parseopts(): problem with \"%s\" data", rest); continue; } if (((*opts)[i].value3.u_bin.b_data = memdup(optbuf, optlen)) == NULL) { Error1("memdup(, "F_Zu"): out of memory", optlen); return -1; } (*opts)[i].value3.u_bin.b_len = optlen; } Info3("setting option \"%s\" to %d:%d:..."/*!!!*/, ent->desc->defname, (*opts)[i].value.u_int, (*opts)[i].value2.u_int); break; case TYPE_INT_INT_STRING: if (!assign) { Error1("option \"%s\": values required", a0); continue; } { char *rest; (*opts)[i].value.u_int = strtoul(token, &rest, 0); if (*rest != ':') { Error1("option \"%s\": 3 arguments required", ent->desc->defname); } ++rest; (*opts)[i].value2.u_int = strtoul(rest, &rest, 0); if (*rest != ':') { Error1("option \"%s\": 3 arguments required", ent->desc->defname); } ++rest; if (((*opts)[i].value3.u_string = strdup(rest)) == NULL) { Error("out of memory"); return -1; } } Info4("setting option \"%s\" to %d:%d:\"%s\"", ent->desc->defname, (*opts)[i].value.u_int, (*opts)[i].value2.u_int, (*opts)[i].value3.u_string); break; #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) case TYPE_IP_MREQN: { /* we do not resolve the addresses here because we do not yet know if we are coping with a IPv4 or IPv6 socat address */ const char *ends[] = { ":", NULL }; const char *nests[] = { "[","]", NULL }; char buff[512], *buffp=buff; size_t bufspc = sizeof(buff)-1; /* parse first IP address, expect ':' */ tokp = token; /*! result= */ parsres = nestlex((const char **)&tokp, &buffp, &bufspc, ends, NULL, NULL, nests, true, false, false); if (parsres < 0) { Error1("option too long: \"%s\"", *a); return -1; } else if (parsres > 0) { Error1("syntax error in \"%s\"", *a); return -1; } if (*tokp != ':') { Error1("syntax in option %s: missing ':'", token); } *buffp++ = '\0'; (*opts)[i].value.u_ip_mreq.multiaddr = strdup(buff); /*!!! NULL */ ++tokp; /* parse second IP address, expect ':' or '\0'' */ buffp = buff; /*! result= */ parsres = nestlex((const char **)&tokp, &buffp, &bufspc, ends, NULL, NULL, nests, true, false, false); if (parsres < 0) { Error1("option too long: \"%s\"", *a); return -1; } else if (parsres > 0) { Error1("syntax error in \"%s\"", *a); return -1; } *buffp++ = '\0'; (*opts)[i].value.u_ip_mreq.param2 = strdup(buff); /*!!! NULL */ #if HAVE_STRUCT_IP_MREQN if (*tokp++ == ':') { strncpy((*opts)[i].value.u_ip_mreq.ifindex, tokp, IF_NAMESIZE); /* ok */ Info4("setting option \"%s\" to {\"%s\",\"%s\",\"%s\"}", ent->desc->defname, (*opts)[i].value.u_ip_mreq.multiaddr, (*opts)[i].value.u_ip_mreq.param2, (*opts)[i].value.u_ip_mreq.ifindex); } else { (*opts)[i].value.u_ip_mreq.ifindex[0] = '\0'; Info3("setting option \"%s\" to {\"%s\",\"%s\"}", ent->desc->defname, (*opts)[i].value.u_ip_mreq.multiaddr, (*opts)[i].value.u_ip_mreq.param2); } #else /* !HAVE_STRUCT_IP_MREQN */ Info3("setting option \"%s\" to {0x%08x,0x%08x}", ent->desc->defname, (*opts)[i].value.u_ip_mreq.multiaddr, (*opts)[i].value.u_ip_mreq.param2); #endif /* !HAVE_STRUCT_IP_MREQN */ } break; #endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */ #if WITH_IP4 case TYPE_IP4NAME: { struct sockaddr_in sa; socklen_t salen = sizeof(sa); const char *ends[] = { NULL }; const char *nests[] = { "[","]", NULL }; char buff[512], *buffp=buff; size_t bufspc = sizeof(buff)-1; tokp = token; parsres = nestlex((const char **)&tokp, &buffp, &bufspc, ends, NULL, NULL, nests, true, false, false); if (parsres < 0) { Error1("option too long: \"%s\"", *a); return -1; } else if (parsres > 0) { Error1("syntax error in \"%s\"", *a); return -1; } if (*tokp != '\0') { Error1("trailing data in option \"%s\"", token); } *buffp = '\0'; if (xiogetaddrinfo(buff, NULL, AF_INET, SOCK_DGRAM, IPPROTO_IP, (union sockaddr_union *)&sa, &salen, 0, 0/*!!!*/) != STAT_OK) { opt->desc = ODESC_ERROR; continue; } opt->value.u_ip4addr = sa.sin_addr; } break; #endif /* defined(WITH_IP4) */ default: Error2("parseopts(): internal error on option \"%s\": unimplemented type %d", ent->desc->defname, ent->desc->type); continue; } ++i; if ((i % 8) == 0) { *opts = Realloc(*opts, (i+8) * sizeof(struct opt)); if (*opts == NULL) { return -1; } } } /*(*opts)[i+1].desc = ODESC_END;*/ (*opts)[i].desc = ODESC_END; return 0; } /* copy the already parsed options for repeated application, but only those matching groups ANY and */ struct opt *copyopts(const struct opt *opts, unsigned int groups) { struct opt *new; int i, j, n; if (!opts) return NULL; /* just count the options in the array */ i = 0; while (opts[i].desc != ODESC_END) { ++i; } n = i+1; new = Malloc(n * sizeof(struct opt)); if (new == NULL) { return NULL; } i = 0, j = 0; while (i < n-1) { if (opts[i].desc == ODESC_DONE) { new[j].desc = ODESC_DONE; } else if ((opts[i].desc->group & (GROUP_ANY&~GROUP_PROCESS)) || (opts[i].desc->group & groups)) { new[j++] = opts[i]; } ++i; } new[j].desc = ODESC_END; return new; } /* move options to a new options list move only those matching */ struct opt *moveopts(struct opt *opts, unsigned int groups) { struct opt *new; int i, j, n; if (!opts) return NULL; /* just count the options in the array */ i = 0; j = 0; while (opts[i].desc != ODESC_END) { if (opts[i].desc != ODESC_DONE && opts[i].desc != ODESC_ERROR) ++j; ++i; } n = i; new = Malloc((j+1) * sizeof(struct opt)); if (new == NULL) { return NULL; } i = 0, j = 0; while (i < n) { if (opts[i].desc == ODESC_DONE || opts[i].desc == ODESC_ERROR) { ++i; continue; } else if (opts[i].desc->group & groups) { new[j++] = opts[i]; opts[i].desc = ODESC_DONE; } ++i; } new[j].desc = ODESC_END; return new; } /* return the number of yet unconsumed options; -1 on error */ int leftopts(const struct opt *opts) { const struct opt *opt = opts; int num = 0; if (!opts) return 0; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE) { ++num; } ++opt; } return num; } /* show as warning which options are still unused */ int showleft(const struct opt *opts) { const struct opt *opt = opts; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE) { Warn1("showleft(): option \"%s\" not inquired", opt->desc->defname); } ++opt; } return 0; } /* determines the address group from mode_t */ /* does not set GROUP_FD; cannot determine GROUP_TERMIOS ! */ int _groupbits(mode_t mode) { unsigned int result = 0; switch ((mode&S_IFMT)>>12) { case (S_IFIFO>>12): /* 1, FIFO */ result = GROUP_FIFO; break; case (S_IFCHR>>12): /* 2, character device */ result = GROUP_CHR|GROUP_TERMIOS; break; case (S_IFDIR>>12): /* 4, directory !!! not supported */ result = GROUP_NONE; break; case (S_IFBLK>>12): /* 6, block device */ result = GROUP_BLK; break; case (S_IFREG>>12): /* 8, regular file */ result = GROUP_REG; break; case (S_IFLNK>>12): /* 10, symbolic link !!! not supported */ result = GROUP_NONE; break; #ifdef S_IFSOCK case (S_IFSOCK>>12): /* 12, socket */ result = GROUP_SOCKET|GROUP_SOCK_UNIX; break; #else default: /* some systems (pure POSIX.1) do not know S_IFSOCK */ result = GROUP_SOCKET|GROUP_SOCK_UNIX; break; #endif } Debug2("_groupbits(%d) -> %d", mode, result); return result; } /* does not set GROUP_FD */ int groupbits(int fd) { #if HAVE_STAT64 struct stat64 buf; #else struct stat buf; #endif /* !HAVE_STAT64 */ int result; if ( #if HAVE_STAT64 Fstat64(fd, &buf) < 0 #else Fstat(fd, &buf) < 0 #endif /* !HAVE_STAT64 */ ) { Error4("groupbits(%d): fstat(%d, %p): %s", fd, fd, &buf, strerror(errno)); return -1; } result = _groupbits(buf.st_mode&S_IFMT); if (result == GROUP_CHR) { if (Isatty(fd) > 0) { result |= GROUP_TERMIOS; } } return result; } #if 0 /* currently not used */ int retropt(struct opt *opts, int optcode, union integral *result) { struct opt *opt = opts; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) { *result = opt->value; opt->desc = ODESC_DONE; return 0; } ++opt; } return -1; } #endif static struct opt *xio_findopt(struct opt *opts, int optcode) { struct opt *opt = opts; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) { return opt; } ++opt; } return NULL; } int retropt_timespec(struct opt *opts, int optcode, struct timespec *result) { struct opt *opt; if (!(opt = xio_findopt(opts, optcode))) { return -1; } *result = opt->value.u_timespec; opt->desc = ODESC_DONE; return 0; } /* Looks for the first option of type . If the option is found, this function stores its bool value in *result, "consumes" the option, and returns 0. If the option is not found, *result is not modified, and -1 is returned. */ int retropt_bool(struct opt *opts, int optcode, bool *result) { struct opt *opt = opts; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) { *result = opt->value.u_bool; opt->desc = ODESC_DONE; return 0; } ++opt; } return -1; } #if 0 /* currently not used */ /* Looks for the first option of type . If the option is found, this function stores its short value in *result, "consumes" the option, and returns 0. If the option is not found, *result is not modified, and -1 is returned. */ int retropt_short(struct opt *opts, int optcode, short *result) { struct opt *opt = opts; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) { *result = opt->value.u_short; opt->desc = ODESC_DONE; return 0; } ++opt; } return -1; } #endif /* Looks for the first option of type . If the option is found, this function stores its unsigned short value in *result, "consumes" the option, and returns 0. If the option is not found, *result is not modified, and -1 is returned. */ int retropt_ushort(struct opt *opts, int optcode, unsigned short *result) { struct opt *opt = opts; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) { *result = opt->value.u_ushort; opt->desc = ODESC_DONE; return 0; } ++opt; } return -1; } /* Looks for the first option of type . If the option is found, this function stores its int value in *result, "consumes" the option, and returns 0. If the option is not found, *result is not modified, and -1 is returned. */ int retropt_int(struct opt *opts, int optcode, int *result) { struct opt *opt = opts; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) { switch (opt->desc->type) { case TYPE_INT: *result = opt->value.u_int; break; case TYPE_STRING: *result = strtol(opt->value.u_string, NULL, 0); break; default: Error2("cannot convert type %d of option %s to int", opt->desc->type, opt->desc->defname); opt->desc = ODESC_ERROR; return -1; } opt->desc = ODESC_DONE; return 0; } ++opt; } return -1; } /* Looks for the first option of type . If the option is found, this function stores its unsigned int value in *result, "consumes" the option, and returns 0. If the option is not found, *result is not modified, and -1 is returned. */ int retropt_uint(struct opt *opts, int optcode, unsigned int *result) { struct opt *opt = opts; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) { *result = opt->value.u_uint; opt->desc = ODESC_DONE; return 0; } ++opt; } return -1; } /* Looks for the first option of type . If the option is found, this function stores its long value in *result, "consumes" the option, and returns 0. If the option is not found, *result is not modified, and -1 is returned. */ int retropt_long(struct opt *opts, int optcode, long *result) { struct opt *opt = opts; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) { *result = opt->value.u_long; opt->desc = ODESC_DONE; return 0; } ++opt; } return -1; } /* Looks for the first option of type . If the option is found, this function stores its unsigned long value in *result, "consumes" the option, and returns 0. If the option is not found, *result is not modified, and -1 is returned. */ int retropt_ulong(struct opt *opts, int optcode, unsigned long *result) { struct opt *opt = opts; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) { *result = opt->value.u_ulong; opt->desc = ODESC_DONE; return 0; } ++opt; } return -1; } #if 0 /* currently not used */ /* get the value of a FLAG typed option, and apply it to the appropriate bit position. Mark the option as consumed (done). return 0 if options was found and successfully applied, or -1 if option was not in opts */ int retropt_flag(struct opt *opts, int optcode, flags_t *result) { struct opt *opt = opts; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) { if (opt->value.u_bool) { *result |= opt->desc->major; } else { *result &= ~opt->desc->major; } opt->desc = ODESC_DONE; return 0; } ++opt; } return -1; } #endif /* Looks for the first option of type . If the option is found, this function stores its character pointer value in *result, "consumes" the option, and returns 0. Note that, for options of type STRING_NULL, the character pointer might degenerate to NULL. The resulting string is malloc'ed and should be freed after use. If the option is not found, *result is not modified, and -1 is returned. */ int retropt_string(struct opt *opts, int optcode, char **result) { struct opt *opt = opts; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) { if (opt->value.u_string == NULL) { *result = NULL; } else if ((*result = strdup(opt->value.u_string)) == NULL) { Error1("strdup("F_Zu"): out of memory", strlen(opt->value.u_string)); return -1; } opt->desc = ODESC_DONE; return 0; } ++opt; } return -1; } #if _WITH_SOCKET /* looks for a bind option and, if found, overwrites the complete contents of sa with the appropriate value(s). returns STAT_OK if option exists and could be resolved, STAT_NORETRY if option exists but had error, or STAT_NOACTION if it does not exist */ /* currently only for IP (v4, v6) and raw (PF_UNSPEC) */ int retropt_bind(struct opt *opts, int af, int socktype, int ipproto, struct sockaddr *sa, socklen_t *salen, int feats, /* TCP etc: 1..address allowed, 3..address and port allowed UNIX (or'd): 1..tight 2..abstract */ unsigned long res_opts0, unsigned long res_opts1) { const char portsep[] = ":"; const char *ends[] = { portsep, NULL }; const char *nests[] = { "[", "]", NULL }; bool portallowed; char *bindname, *bindp; char hostname[512], *hostp = hostname, *portp = NULL; size_t hostlen = sizeof(hostname)-1; int parsres; int result; if (retropt_string(opts, OPT_BIND, &bindname) < 0) { return STAT_NOACTION; } bindp = bindname; switch (af) { case AF_UNSPEC: { size_t p = 0; dalan(bindname, (char *)sa->sa_data, &p, *salen-sizeof(sa->sa_family)); *salen = p + sizeof(sa->sa_family); *salen = p + #if HAVE_STRUCT_SOCKADDR_SALEN sizeof(sa->sa_len) + #endif sizeof(sa->sa_family); #if HAVE_STRUCT_SOCKADDR_SALEN sa->sa_len = *salen; #endif } break; #if WITH_IP4 || WITH_IP6 #if WITH_IP4 case AF_INET: #endif #if WITH_IP6 case AF_INET6: #endif /*WITH_IP6 */ portallowed = (feats>=2); parsres = nestlex((const char **)&bindp, &hostp, &hostlen, ends, NULL, NULL, nests, true, false, false); if (parsres < 0) { Error1("option too long: \"%s\"", bindp); return STAT_NORETRY; } else if (parsres > 0) { Error1("syntax error in \"%s\"", bindp); return STAT_NORETRY; } *hostp++ = '\0'; if (!strncmp(bindp, portsep, strlen(portsep))) { if (!portallowed) { Error("port specification not allowed in this bind option"); return STAT_NORETRY; } else { portp = bindp + strlen(portsep); } } if ((result = xiogetaddrinfo(hostname[0]!='\0'?hostname:NULL, portp, af, socktype, ipproto, (union sockaddr_union *)sa, salen, res_opts0, res_opts1)) != STAT_OK) { Error("error resolving bind option"); return STAT_NORETRY; } break; #endif /* WITH_IP4 || WITH_IP6 */ #if WITH_UNIX case AF_UNIX: { bool abstract = (feats&2); bool tight = (feats&1); struct sockaddr_un *s_un = (struct sockaddr_un *)sa; *salen = xiosetunix(af, s_un, bindname, abstract, tight); } break; #endif /* WITH_UNIX */ default: Error1("bind: unknown address family %d", af); return STAT_NORETRY; } return STAT_OK; } #endif /* _WITH_SOCKET */ /* applies to fd all options belonging to phase */ /* note: not all options can be applied this way (e.g. OFUNC_SPEC with PH_OPEN) implemented are: OFUNC_FCNTL, OFUNC_SOCKOPT (probably not all types), OFUNC_TERMIOS_FLAG, OFUNC_TERMIOS_PATTERN, and some OFUNC_SPEC */ int applyopts(int fd, struct opt *opts, enum e_phase phase) { struct opt *opt; opt = opts; while (opt && opt->desc != ODESC_END) { if (opt->desc == ODESC_DONE || (phase != PH_ALL && opt->desc->phase != phase)) { ++opt; continue; } if (opt->desc->func == OFUNC_SEEK32) { if (Lseek(fd, opt->value.u_off, opt->desc->major) < 0) { Error4("lseek(%d, "F_off", %d): %s", fd, opt->value.u_off, opt->desc->major, strerror(errno)); } #if HAVE_LSEEK64 } else if (opt->desc->func == OFUNC_SEEK64) { /*! this depends on off64_t atomic type */ if (Lseek64(fd, opt->value.u_off64, opt->desc->major) < 0) { Error4("lseek64(%d, "F_off64", %d): %s", fd, opt->value.u_off64, opt->desc->major, strerror(errno)); } #endif /* HAVE_LSEEK64 */ } else if (opt->desc->func == OFUNC_FCNTL) { int flag; /* retrieve existing flag setttings */ if ((flag = Fcntl(fd, opt->desc->major-1)) < 0) { Error3("fcntl(%d, %d): %s", fd, opt->desc->major, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } else { if (opt->value.u_bool) { flag |= opt->desc->minor; } else { flag &= ~opt->desc->minor; } if (Fcntl_l(fd, opt->desc->major, flag) < 0) { Error4("fcntl(%d, %d, %d): %s", fd, opt->desc->major, flag, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } } } else if (opt->desc->func == OFUNC_IOCTL) { if (Ioctl(fd, opt->desc->major, (void *)&opt->value) < 0) { Error4("ioctl(%d, 0x%x, %p): %s", fd, opt->desc->major, (void *)&opt->value, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } } else if (opt->desc->func == OFUNC_IOCTL_MASK_LONG) { long val; int getreq = opt->desc->major; int setreq = opt->desc->minor; long mask = opt->desc->arg3; if (Ioctl(fd, getreq, (void *)&val) < 0) { Error4("ioctl(%d, 0x%x, %p): %s", fd, opt->desc->major, (void *)&val, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } val &= ~mask; if (opt->value.u_bool) val |= mask; if (Ioctl(fd, setreq, (void *)&val) < 0) { Error4("ioctl(%d, 0x%x, %p): %s", fd, opt->desc->major, (void *)&val, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } } else if (opt->desc->func == OFUNC_IOCTL_GENERIC) { switch (opt->desc->type) { case TYPE_INT: if (Ioctl(fd, opt->value.u_int, NULL) < 0) { Error3("ioctl(%d, 0x%x, NULL): %s", fd, opt->value.u_int, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case TYPE_INT_INT: if (Ioctl_int(fd, opt->value.u_int, opt->value2.u_int) < 0) { Error4("ioctl(%d, 0x%x, 0x%x): %s", fd, opt->value.u_int, opt->value2.u_int, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case TYPE_INT_INTP: if (Ioctl(fd, opt->value.u_int, (void *)&opt->value2.u_int) < 0) { Error4("ioctl(%d, 0x%x, %p): %s", fd, opt->value.u_int, (void *)&opt->value2.u_int, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case TYPE_INT_BIN: if (Ioctl(fd, opt->value.u_int, (void *)opt->value2.u_bin.b_data) < 0) { Error4("ioctl(%d, 0x%x, %p): %s", fd, opt->value.u_int, (void *)opt->value2.u_bin.b_data, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case TYPE_INT_STRING: if (Ioctl(fd, opt->value.u_int, (void *)opt->value2.u_string) < 0) { Error4("ioctl(%d, 0x%x, %p): %s", fd, opt->value.u_int, (void *)opt->value2.u_string, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; default: Error1("ioctl() data type %d not implemented", opt->desc->type); } #if _WITH_SOCKET } else if (opt->desc->func == OFUNC_SOCKOPT) { if (0) { ; #if 0 && HAVE_STRUCT_LINGER } else if (opt->desc->optcode == OPT_SO_LINGER) { struct linger lingstru; lingstru.l_onoff = (opt->value.u_int>=0 ? 1 : 0); lingstru.l_linger = opt->value.u_int; if (Setsockopt(fd, opt->desc->major, opt->desc->minor, &lingstru, sizeof(lingstru)) < 0) { Error6("setsockopt(%d, %d, %d, {%d,%d}, "F_Zu, fd, opt->desc->major, opt->desc->minor, lingstru.l_onoff, lingstru.l_linger, sizeof(lingstru)); opt->desc = ODESC_ERROR; ++opt; continue; } #endif /* HAVE_STRUCT_LINGER */ } else { switch (opt->desc->type) { case TYPE_BIN: if (Setsockopt(fd, opt->desc->major, opt->desc->minor, opt->value.u_bin.b_data, opt->value.u_bin.b_len) < 0) { Error6("setsockopt(%d, %d, %d, %p, "F_Zu"): %s", fd, opt->desc->major, opt->desc->minor, opt->value.u_bin.b_data, opt->value.u_bin.b_len, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case TYPE_BOOL: if (Setsockopt(fd, opt->desc->major, opt->desc->minor, &opt->value.u_bool, sizeof(opt->value.u_bool)) < 0) { Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu"): %s", fd, opt->desc->major, opt->desc->minor, opt->value.u_bool, sizeof(opt->value.u_bool), strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case TYPE_BYTE: if (Setsockopt(fd, opt->desc->major, opt->desc->minor, &opt->value.u_byte, sizeof(uint8_t)) < 0) { Error6("setsockopt(%d, %d, %d, {%u}, "F_Zu"): %s", fd, opt->desc->major, opt->desc->minor, opt->value.u_byte, sizeof(uint8_t), strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case TYPE_INT: if (Setsockopt(fd, opt->desc->major, opt->desc->minor, &opt->value.u_int, sizeof(int)) < 0) { Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu"): %s", fd, opt->desc->major, opt->desc->minor, opt->value.u_int, sizeof(int), strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case TYPE_LONG: if (Setsockopt(fd, opt->desc->major, opt->desc->minor, &opt->value.u_long, sizeof(long)) < 0) { Error6("setsockopt(%d, %d, %d, {%ld}, "F_Zu"): %s", fd, opt->desc->major, opt->desc->minor, opt->value.u_long, sizeof(long), strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case TYPE_STRING: if (Setsockopt(fd, opt->desc->major, opt->desc->minor, opt->value.u_string, strlen(opt->value.u_string)+1) < 0) { Error6("setsockopt(%d, %d, %d, \"%s\", "F_Zu"): %s", fd, opt->desc->major, opt->desc->minor, opt->value.u_string, strlen(opt->value.u_string)+1, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case TYPE_UINT: if (Setsockopt(fd, opt->desc->major, opt->desc->minor, &opt->value.u_uint, sizeof(unsigned int)) < 0) { Error6("setsockopt(%d, %d, %d, {%u}, "F_Zu"): %s", fd, opt->desc->major, opt->desc->minor, opt->value.u_uint, sizeof(unsigned int), strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case TYPE_TIMEVAL: if (Setsockopt(fd, opt->desc->major, opt->desc->minor, &opt->value.u_timeval, sizeof(struct timeval)) < 0) { Error7("setsockopt(%d, %d, %d, {%ld,%ld}, "F_Zu"): %s", fd, opt->desc->major, opt->desc->minor, opt->value.u_timeval.tv_sec, opt->value.u_timeval.tv_usec, sizeof(struct timeval), strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; #if HAVE_STRUCT_LINGER case TYPE_LINGER: { struct linger lingstru; lingstru.l_onoff = (opt->value.u_linger.l_onoff>=0 ? 1 : 0); lingstru.l_linger = opt->value.u_linger.l_linger; if (Setsockopt(fd, opt->desc->major, opt->desc->minor, &lingstru, sizeof(lingstru)) < 0) { Error6("setsockopt(%d, %d, %d, {%d,%d}): %s", fd, opt->desc->major, opt->desc->minor, lingstru.l_onoff, lingstru.l_linger, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } } break; #endif /* HAVE_STRUCT_LINGER */ #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) case TYPE_IP_MREQN: /* handled in applyopts_single */ ++opt; continue; #endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */ /*! still many types missing; implement on demand */ #if WITH_IP4 case TYPE_IP4NAME: if (Setsockopt(fd, opt->desc->major, opt->desc->minor, &opt->value.u_ip4addr, sizeof(opt->value.u_ip4addr)) < 0) { Error6("setsockopt(%d, %d, %d, {0x%x}, "F_Zu"): %s", fd, opt->desc->major, opt->desc->minor, *(uint32_t *)&opt->value.u_ip4addr, sizeof(opt->value.u_ip4addr), strerror(errno)); } break; #endif /* defined(WITH_IP4) */ default: #if !NDEBUG Error1("applyopts(): type %d not implemented", opt->desc->type); #else Warn1("applyopts(): type %d not implemented", opt->desc->type); #endif opt->desc = ODESC_ERROR; ++opt; continue; } } } else if (opt->desc->func == OFUNC_SOCKOPT_APPEND) { switch (opt->desc->type) { uint8_t data[256]; socklen_t oldlen, newlen; case TYPE_BIN: oldlen = sizeof(data); if (Getsockopt(fd, opt->desc->major, opt->desc->minor, data, &oldlen) < 0) { Error6("getsockopt(%d, %d, %d, %p, {"F_socklen"}): %s", fd, opt->desc->major, opt->desc->minor, data, oldlen, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } memcpy(&data[oldlen], opt->value.u_bin.b_data, MIN(opt->value.u_bin.b_len, sizeof(data)-oldlen)); newlen = oldlen + MIN(opt->value.u_bin.b_len, sizeof(data)-oldlen); if (Setsockopt(fd, opt->desc->major, opt->desc->minor, data, newlen) < 0) { Error6("setsockopt(%d, %d, %d, %p, %d): %s", fd, opt->desc->major, opt->desc->minor, data, newlen, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; default: Error2("internal: option \"%s\": unimplemented type %d", opt->desc->defname, opt->desc->type); break; } } else if (opt->desc->func == OFUNC_SOCKOPT_GENERIC) { switch (opt->desc->type) { case TYPE_INT_INT_INT: if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int, &opt->value3.u_int, sizeof(int)) < 0) { Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu"): %s", fd, opt->value.u_int, opt->value2.u_int, opt->value3.u_int, sizeof(int), strerror(errno)); } break; case TYPE_INT_INT_BIN: if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int, opt->value3.u_bin.b_data, opt->value3.u_bin.b_len) < 0) { Error5("setsockopt(%d, %d, %d, {...}, "F_Zu"): %s", fd, opt->value.u_int, opt->value2.u_int, opt->value3.u_bin.b_len, strerror(errno)); } break; case TYPE_INT_INT_STRING: if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int, opt->value3.u_string, strlen(opt->value3.u_string)+1) < 0) { Error6("setsockopt(%d, %d, %d, \"%s\", "F_Zu"): %s", fd, opt->value.u_int, opt->value2.u_int, opt->value3.u_string, strlen(opt->value3.u_string)+1, strerror(errno)); } break; default: Error1("setsockopt() data type %d not implemented", opt->desc->type); } #endif /* _WITH_SOCKET */ #if HAVE_FLOCK } else if (opt->desc->func == OFUNC_FLOCK) { if (Flock(fd, opt->desc->major) < 0) { Error3("flock(%d, %d): %s", fd, opt->desc->major, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } #endif /* defined(HAVE_FLOCK) */ } else if (opt->desc->func == OFUNC_SPEC || opt->desc->func == OFUNC_FLAG) { switch (opt->desc->optcode) { case OPT_USER: case OPT_USER_LATE: if (Fchown(fd, opt->value.u_uidt, -1) < 0) { Error3("fchown(%d, "F_uid", -1): %s", fd, opt->value.u_uidt, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case OPT_GROUP: case OPT_GROUP_LATE: if (Fchown(fd, -1, opt->value.u_gidt) < 0) { Error3("fchown(%d, -1, "F_gid"): %s", fd, opt->value.u_gidt, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case OPT_PERM: case OPT_PERM_LATE: if (Fchmod(fd, opt->value.u_modet) < 0) { Error3("fchmod(%d, %u): %s", fd, opt->value.u_modet, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case OPT_FTRUNCATE32: if (Ftruncate(fd, opt->value.u_off) < 0) { Error3("ftruncate(%d, "F_off"): %s", fd, opt->value.u_off, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; #if HAVE_FTRUNCATE64 case OPT_FTRUNCATE64: if (Ftruncate64(fd, opt->value.u_off64) < 0) { Error3("ftruncate64(%d, "F_off64"): %s", fd, opt->value.u_off64, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } #endif /* HAVE_FTRUNCATE64 */ break; case OPT_F_SETLK_RD: case OPT_F_SETLK_WR: case OPT_F_SETLKW_RD: case OPT_F_SETLKW_WR: { struct flock l; /* Linux: */ l.l_type = opt->desc->minor; l.l_whence = SEEK_SET; l.l_start = 0; l.l_len = LONG_MAX; l.l_pid = 0; /* hope this uses our current process */ if (Fcntl_lock(fd, opt->desc->major, &l) < 0) { Error3("fcntl(%d, %d, {type=F_WRLCK,whence=SEEK_SET,start=0,len=LONG_MAX,pid=0}): %s", fd, opt->desc->major, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } } break; case OPT_SETUID_EARLY: case OPT_SETUID: if (Setuid(opt->value.u_uidt) < 0) { Error2("setuid("F_uid"): %s", opt->value.u_uidt, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case OPT_SETGID_EARLY: case OPT_SETGID: if (Setgid(opt->value.u_gidt) < 0) { Error2("setgid("F_gid"): %s", opt->value.u_gidt, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } break; case OPT_SUBSTUSER_EARLY: case OPT_SUBSTUSER: { struct passwd *pwd; if ((pwd = getpwuid(opt->value.u_uidt)) == NULL) { Error1("getpwuid("F_uid"): no such user", opt->value.u_uidt); opt->desc = ODESC_ERROR; ++opt; continue; } if (Initgroups(pwd->pw_name, pwd->pw_gid) < 0) { Error3("initgroups(%s, "F_gid"): %s", pwd->pw_name, pwd->pw_gid, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } if (Setgid(pwd->pw_gid) < 0) { Error2("setgid("F_gid"): %s", pwd->pw_gid, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } if (Setuid(opt->value.u_uidt) < 0) { Error2("setuid("F_uid"): %s", opt->value.u_uidt, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } #if 1 if (setenv("USER", pwd->pw_name, 1) < 0) Error1("setenv(\"USER\", \"%s\", 1): insufficient space", pwd->pw_name); if (setenv("LOGNAME", pwd->pw_name, 1) < 0) Error1("setenv(\"LOGNAME\", \"%s\", 1): insufficient space", pwd->pw_name); if (setenv("HOME", pwd->pw_dir, 1) < 0) Error1("setenv(\"HOME\", \"%s\", 1): insufficient space", pwd->pw_dir); if (setenv("SHELL", pwd->pw_shell, 1) < 0) Error1("setenv(\"SHELL\", \"%s\", 1): insufficient space", pwd->pw_shell); #endif } break; #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT) case OPT_SUBSTUSER_DELAYED: { struct passwd *pwd; if ((pwd = getpwuid(opt->value.u_uidt)) == NULL) { Error1("getpwuid("F_uid"): no such user", opt->value.u_uidt); opt->desc = ODESC_ERROR; ++opt; continue; } delayeduser_uid = opt->value.u_uidt; delayeduser_gid = pwd->pw_gid; if ((delayeduser_name = strdup(pwd->pw_name)) == NULL) { Error1("strdup("F_Zu"): out of memory", strlen(pwd->pw_name)+1); opt->desc = ODESC_ERROR; ++opt; continue; } if ((delayeduser_dir = strdup(pwd->pw_dir)) == NULL) { Error1("strdup("F_Zu"): out of memory", strlen(pwd->pw_dir)+1); opt->desc = ODESC_ERROR; ++opt; continue; } if ((delayeduser_shell = strdup(pwd->pw_shell)) == NULL) { Error1("strdup("F_Zu"): out of memory", strlen(pwd->pw_shell)+1); opt->desc = ODESC_ERROR; ++opt; continue; } /* function to get all supplementary groups of user */ delayeduser_ngids = sizeof(delayeduser_gids)/sizeof(gid_t); getusergroups(delayeduser_name, delayeduser_gids, &delayeduser_ngids); delayeduser = true; } break; #endif case OPT_CHROOT_EARLY: case OPT_CHROOT: if (Chroot(opt->value.u_string) < 0) { Error2("chroot(\"%s\"): %s", opt->value.u_string, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } if (Chdir("/") < 0) { Error1("chdir(\"/\"): %s", strerror(errno)); } break; case OPT_SETSID: if (Setsid() < 0) { Warn1("setsid(): %s", strerror(errno)); if (Setpgid(getpid(), getppid()) < 0) { Warn3("setpgid(%d, %d): %s", getpid(), getppid(), strerror(errno)); } else { if (Setsid() < 0) { Error1("setsid(): %s", strerror(errno)); } } } break; case OPT_SETPGID: if (Setpgid(0, opt->value.u_int) < 0) { Warn2("setpgid(0, "F_pid"): %s", opt->value.u_int, strerror(errno)); } break; case OPT_TIOCSCTTY: { int mytty; /* this code idea taken from ssh/pty.c: make pty controlling term. */ if ((mytty = Open("/dev/tty", O_NOCTTY, 0640)) < 0) { Warn1("open(\"/dev/tty\", O_NOCTTY, 0640): %s", strerror(errno)); } else { /*0 Info1("open(\"/dev/tty\", O_NOCTTY, 0640) -> %d", mytty);*/ #ifdef TIOCNOTTY if (Ioctl(mytty, TIOCNOTTY, NULL) < 0) { Warn2("ioctl(%d, TIOCNOTTY, NULL): %s", mytty, strerror(errno)); } #endif if (Close(mytty) < 0) { Info2("close(%d): %s", mytty, strerror(errno)); } } #ifdef TIOCSCTTY if (Ioctl(fd, TIOCSCTTY, NULL) < 0) { Warn2("ioctl(%d, TIOCSCTTY, NULL): %s", fd, strerror(errno)); } #endif if (Tcsetpgrp(0, getpid()) < 0) { Warn2("tcsetpgrp("F_pid"): %s", getpid(), strerror(errno)); } } break; default: Error1("applyopts(): option \"%s\" not implemented", opt->desc->defname); opt->desc = ODESC_ERROR; ++opt; continue; } #if WITH_TERMIOS } else if (opt->desc->func == OFUNC_TERMIOS_FLAG) { #if 0 union { struct termios termarg; tcflag_t flags[4]; } tdata; if (Tcgetattr(fd, &tdata.termarg) < 0) { Error3("tcgetattr(%d, %p): %s", fd, &tdata.termarg, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } if (opt->value.u_bool) { tdata.flags[opt->desc->major] |= opt->desc->minor; } else { tdata.flags[opt->desc->major] &= ~opt->desc->minor; } if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) { Error3("tcsetattr(%d, TCSADRAIN, %p): %s", fd, &tdata.termarg, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } #else if (xiotermiosflag_applyopt(fd, opt) < 0) { opt->desc = ODESC_ERROR; ++opt; continue; } #endif } else if (opt->desc->func == OFUNC_TERMIOS_VALUE) { union { struct termios termarg; tcflag_t flags[4]; } tdata; if (((opt->value.u_uint << opt->desc->arg3) & opt->desc->minor) != (opt->value.u_uint << opt->desc->arg3)) { Error2("option %s: invalid value %u", opt->desc->defname, opt->value.u_uint); opt->desc = ODESC_ERROR; ++opt; continue; } if (Tcgetattr(fd, &tdata.termarg) < 0) { Error3("tcgetattr(%d, %p): %s", fd, &tdata.termarg, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } tdata.flags[opt->desc->major] &= ~opt->desc->minor; tdata.flags[opt->desc->major] |= ((opt->value.u_uint << opt->desc->arg3) & opt->desc->minor); if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) { Error3("tcsetattr(%d, TCSADRAIN, %p): %s", fd, &tdata.termarg, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } } else if (opt->desc->func == OFUNC_TERMIOS_PATTERN) { union { struct termios termarg; tcflag_t flags[4]; } tdata; if (Tcgetattr(fd, &tdata.termarg) < 0) { Error3("tcgetattr(%d, %p): %s", fd, &tdata.termarg, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } tdata.flags[opt->desc->major] &= ~opt->desc->arg3; tdata.flags[opt->desc->major] |= opt->desc->minor; if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) { Error3("tcsetattr(%d, TCSADRAIN, %p): %s", fd, &tdata.termarg, strerror(errno)); opt->desc = ODESC_ERROR;++opt; continue; } } else if (opt->desc->func == OFUNC_TERMIOS_CHAR) { struct termios termarg; if (Tcgetattr(fd, &termarg) < 0) { Error3("tcgetattr(%d, %p): %s", fd, &termarg, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } termarg.c_cc[opt->desc->major] = opt->value.u_byte; if (Tcsetattr(fd, TCSADRAIN, &termarg) < 0) { Error3("tcsetattr(%d, TCSADRAIN, %p): %s", fd, &termarg, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } #ifdef HAVE_TERMIOS_ISPEED } else if (opt->desc->func == OFUNC_TERMIOS_SPEED) { union { struct termios termarg; speed_t speeds[sizeof(struct termios)/sizeof(speed_t)]; } tdata; if (Tcgetattr(fd, &tdata.termarg) < 0) { Error3("tcgetattr(%d, %p): %s", fd, &tdata.termarg, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } tdata.speeds[opt->desc->major] = opt->value.u_uint; if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) { Error3("tcsetattr(%d, TCSADRAIN, %p): %s", fd, &tdata.termarg, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } #endif /* HAVE_TERMIOS_ISPEED */ } else if (opt->desc->func == OFUNC_TERMIOS_SPEC) { struct termios termarg; if (Tcgetattr(fd, &termarg) < 0) { Error3("tcgetattr(%d, %p): %s", fd, &termarg, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } switch (opt->desc->optcode) { case OPT_RAW: termarg.c_iflag &= ~(IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXOFF #ifdef IUCLC |IUCLC #endif |IXANY|IMAXBEL); termarg.c_iflag |= (0); termarg.c_oflag &= ~(OPOST); termarg.c_oflag |= (0); termarg.c_cflag &= ~(0); termarg.c_cflag |= (0); termarg.c_lflag &= ~(ISIG|ICANON #ifdef XCASE |XCASE #endif ); termarg.c_lflag |= (0); termarg.c_cc[VMIN] = 1; termarg.c_cc[VTIME] = 0; break; case OPT_TERMIOS_RAWER: termarg.c_iflag = 0; termarg.c_oflag = 0; termarg.c_lflag = 0; termarg.c_cflag = (CS8); termarg.c_cc[VMIN] = 1; termarg.c_cc[VTIME] = 0; break; case OPT_SANE: /* cread -ignbrk brkint -inlcr -igncr icrnl -ixoff -iuclc -ixany imaxbel opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke, and also sets all special characters to their default values. */ termarg.c_iflag &= ~(IGNBRK|INLCR|IGNCR|IXOFF #ifdef IUCLC |IUCLC #endif |IXANY); termarg.c_iflag |= (BRKINT|ICRNL|IMAXBEL); termarg.c_oflag &= ~(0 /* for canonical reasons */ #ifdef OLCUC |OLCUC #endif #ifdef OCRNL |OCRNL #endif #ifdef ONOCR |ONOCR #endif #ifdef ONLRET |ONLRET #endif #ifdef OFILL |OFILL #endif #ifdef OFDEL |OFDEL #endif #ifdef NLDLY |NLDLY #endif #ifdef CRDLY |CRDLY #endif #ifdef TABDLY |TABDLY #endif #ifdef BSDLY |BSDLY #endif #ifdef VTDLY |VTDLY #endif #ifdef FFDLY |FFDLY #endif ); termarg.c_oflag |= (OPOST|ONLCR #ifdef NL0 |NL0 #endif #ifdef CR0 |CR0 #endif #ifdef TAB0 |TAB0 #endif #ifdef BS0 |BS0 #endif #ifdef VT0 |VT0 #endif #ifdef FF0 |FF0 #endif ); termarg.c_cflag &= ~(0); termarg.c_cflag |= (CREAD); termarg.c_lflag &= ~(ECHONL|NOFLSH #ifdef XCASE |XCASE #endif |TOSTOP #ifdef ECHOPRT |ECHOPRT #endif ); termarg.c_lflag |= (ISIG|ICANON|IEXTEN|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE); /*! "sets characters to their default values... - which? */ break; case OPT_TERMIOS_CFMAKERAW: #if HAVE_CFMAKERAW cfmakeraw(&termarg); #else /* these setting follow the Linux documenation of cfmakeraw */ termarg.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); termarg.c_oflag &= ~(OPOST); termarg.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); termarg.c_cflag &= ~(CSIZE|PARENB); termarg.c_cflag |= (CS8); #endif break; default: Error("TERMIOS option not handled - internal error?"); } if (Tcsetattr(fd, TCSADRAIN, &termarg) < 0) { Error3("tcsetattr(%d, TCSADRAIN, %p): %s", fd, &termarg, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } #endif /* WITH_TERMIOS */ #if WITH_STREAMS #define ENABLE_APPLYOPT #include "xio-streams.c" #undef ENABLE_APPLYOPT #endif /* WITH_STREAMS */ } else { /*Error1("applyopts(): function %d not implemented", opt->desc->func);*/ if (opt->desc->func != OFUNC_EXT && opt->desc->func != OFUNC_SIGNAL) { Error1("applyopts(): option \"%s\" does not apply", opt->desc->defname); opt->desc = ODESC_ERROR; ++opt; continue; } ++opt; continue; } opt->desc = ODESC_DONE; ++opt; } return 0; } /* applies to fd all options belonging to phases */ /* note: not all options can be applied this way (e.g. OFUNC_SPEC with PH_OPEN) implemented are: OFUNC_FCNTL, OFUNC_SOCKOPT (probably not all types), OFUNC_TERMIOS_FLAG, OFUNC_TERMIOS_PATTERN, and some OFUNC_SPEC */ int applyopts2(int fd, struct opt *opts, unsigned int from, unsigned int to) { unsigned int i; int stat; for (i = from; i <= to; ++i) { if ((stat = applyopts(fd, opts, i)) < 0) return stat; } return 0; } /* apply and consume all options of type FLAG and group. Return 0 if everything went right, or -1 if an error occurred. */ int applyopts_flags(struct opt *opts, int group, flags_t *result) { struct opt *opt = opts; if (!opts) return 0; while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && (opt->desc->group & group)) { if (opt->desc->func == OFUNC_FLAG) { if (opt->value.u_bool) { *result |= opt->desc->major; } else { *result &= ~opt->desc->major; } opt->desc = ODESC_DONE; } else if (opt->desc->func == OFUNC_FLAG_PATTERN) { *result &= ~opt->desc->minor; *result |= opt->desc->major; opt->desc = ODESC_DONE; } } ++opt; } return 0; } /* set the FD_CLOEXEC fcntl if the options do not set it to 0 */ int applyopts_cloexec(int fd, struct opt *opts) { bool docloexec = 1; if (!opts) return 0; retropt_bool(opts, OPT_CLOEXEC, &docloexec); if (docloexec) { if (Fcntl_l(fd, F_SETFD, FD_CLOEXEC) < 0) { Warn2("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", fd, strerror(errno)); } } return 0; } int applyopts_fchown(int fd, struct opt *opts) { uid_t user = -1; gid_t group = -1; retropt_uidt(opts, OPT_USER, &user); retropt_gidt(opts, OPT_GROUP, &group); if (user != (uid_t)-1 || group != (gid_t)-1) { if (Fchown(fd, user, group) < 0) { Error4("fchown(%d, "F_uid", "F_gid"): %s", fd, user, group, strerror(errno)); return STAT_RETRYLATER; } } return 0; } /* caller must make sure that option is not yet consumed */ static int applyopt_offset(struct single *xfd, struct opt *opt) { unsigned char *ptr; ptr = (unsigned char *)xfd + opt->desc->major; switch (opt->desc->type) { case TYPE_BOOL: *(bool *)ptr = opt->value.u_bool; break; case TYPE_INT: *(int *)ptr = opt->value.u_int; break; case TYPE_DOUBLE: *(double *)ptr = opt->value.u_double; break; case TYPE_TIMEVAL: *(struct timeval *)ptr = opt->value.u_timeval; break; case TYPE_STRING_NULL: if (opt->value.u_string == NULL) { *(char **)ptr = NULL; break; } /* PASSTHROUGH */ case TYPE_STRING: if ((*(char **)ptr = strdup(opt->value.u_string)) == NULL) { Error1("strdup("F_Zu"): out of memory", strlen(opt->value.u_string)+1); } break; case TYPE_CONST: *(int *)ptr = opt->desc->minor; break; default: Error1("applyopt_offset(): type %d not implemented", opt->desc->type); return -1; } opt->desc = ODESC_DONE; return 0; } int applyopts_offset(struct single *xfd, struct opt *opts) { struct opt *opt; opt = opts; while (opt->desc != ODESC_END) { if ((opt->desc == ODESC_DONE) || opt->desc->func != OFUNC_OFFSET) { ++opt; continue; } applyopt_offset(xfd, opt); opt->desc = ODESC_DONE; ++opt; } return 0; } /* applies to xfd 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) { struct opt *opt; int lockrc; if (!opts) return 0; opt = opts; while (opt->desc != ODESC_END) { if ((opt->desc == ODESC_DONE) || (opt->desc->phase != phase && phase != PH_ALL)) { /* option not handled in this function */ ++opt; continue; } else { switch (opt->desc->func) { case OFUNC_OFFSET: applyopt_offset(xfd, opt); break; case OFUNC_EXT: switch (opt->desc->optcode) { #if 0 case OPT_IGNOREEOF: xfd->ignoreeof = true; break; case OPT_CR: xfd->lineterm = LINETERM_CR; break; case OPT_CRNL: xfd->lineterm = LINETERM_CRNL; break; #endif /* 0 */ case OPT_READBYTES: xfd->readbytes = opt->value.u_sizet; xfd->actbytes = xfd->readbytes; break; case OPT_LOCKFILE: if (xfd->lock.lockfile) { Error("only one use of options lockfile and waitlock allowed"); } xfd->lock.lockfile = strdup(opt->value.u_string); xfd->lock.intervall.tv_sec = 1; xfd->lock.intervall.tv_nsec = 0; if ((lockrc = xiolock(&xfd->lock)) < 0) { /* error message already printed */ return -1; } if (lockrc) { Error1("could not obtain lock \"%s\"", xfd->lock.lockfile); } else { xfd->havelock = true; } break; case OPT_WAITLOCK: if (xfd->lock.lockfile) { Error("only one use of options lockfile and waitlock allowed"); } xfd->lock.lockfile = strdup(opt->value.u_string); xfd->lock.waitlock = true; xfd->lock.intervall.tv_sec = 1; xfd->lock.intervall.tv_nsec = 0; /*! this should be integrated into central select()/poll() loop */ if (xiolock(&xfd->lock) < 0) { return -1; } xfd->havelock = true; break; default: /* just store the value in the correct component of struct single */ if (opt->desc->type == TYPE_CONST) { /* only for integral types compatible to int */ *(int *)(&((char *)xfd)[opt->desc->major]) = opt->desc->arg3; } else { memcpy(&((char *)xfd)[opt->desc->major], &opt->value, opt->desc->minor); } } break; case OFUNC_OFFSET_MASKS: { void *masks = (char *)xfd + opt->desc->major; size_t masksize = opt->desc->minor; unsigned long bit = opt->desc->arg3; switch (masksize) { case sizeof(uint16_t): if (opt->value.u_bool) { ((uint16_t *)masks)[0] |= bit; } else { ((uint16_t *)masks)[1] |= bit; } break; case sizeof(uint32_t): if (opt->value.u_bool) { ((uint32_t *)masks)[0] |= bit; } else { ((uint32_t *)masks)[1] |= bit; } break; default: Info1("sizeof(uint32_t)="F_Zu, sizeof(uint32_t)); Error1("applyopts_single: masksize "F_Zu" not implemented", masksize); } } break; #if _WITH_SOCKET case OFUNC_SOCKOPT: switch (opt->desc->optcode) { #if WITH_IP4 && (defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)) case OPT_IP_ADD_MEMBERSHIP: { union { #if HAVE_STRUCT_IP_MREQN struct ip_mreqn mreqn; #endif struct ip_mreq mreq; } ip4_mreqn = {{{0}}}; /* IPv6 not supported - seems to have different handling */ /* mc:addr:ifname|ifind mc:ifname|ifind mc:addr */ union sockaddr_union sockaddr1; socklen_t socklen1 = sizeof(sockaddr1.ip4); union sockaddr_union sockaddr2; socklen_t socklen2 = sizeof(sockaddr2.ip4); /* first parameter is alway multicast address */ /*! result */ xiogetaddrinfo(opt->value.u_ip_mreq.multiaddr, NULL, xfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr1, &socklen1, 0, 0); ip4_mreqn.mreq.imr_multiaddr = sockaddr1.ip4.sin_addr; if (0) { ; /* for canonical reasons */ #if HAVE_STRUCT_IP_MREQN } else if (opt->value.u_ip_mreq.ifindex[0] != '\0') { /* three parameters */ /* second parameter is interface address */ xiogetaddrinfo(opt->value.u_ip_mreq.param2, NULL, xfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr2, &socklen2, 0, 0); ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_addr; /* third parameter is interface */ if (ifindex(opt->value.u_ip_mreq.ifindex, (unsigned int *)&ip4_mreqn.mreqn.imr_ifindex, -1) < 0) { Error1("cannot resolve interface \"%s\"", opt->value.u_ip_mreq.ifindex); } #endif /* HAVE_STRUCT_IP_MREQN */ } else { /* two parameters */ if (0) { ; /* for canonical reasons */ #if HAVE_STRUCT_IP_MREQN /* there is a form with two parameters that uses mreqn */ } else if (ifindex(opt->value.u_ip_mreq.param2, (unsigned int *)&ip4_mreqn.mreqn.imr_ifindex, -1) >= 0) { /* yes, second param converts to interface */ ip4_mreqn.mreq.imr_interface.s_addr = htonl(0); #endif /* HAVE_STRUCT_IP_MREQN */ } else { /*! result */ xiogetaddrinfo(opt->value.u_ip_mreq.param2, NULL, xfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr2, &socklen2, 0, 0); ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_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) { 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, &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, ip4_mreqn.mreqn.imr_multiaddr.s_addr, ip4_mreqn.mreqn.imr_address.s_addr, ip4_mreqn.mreqn.imr_ifindex, sizeof(ip4_mreqn.mreqn), strerror(errno)); opt->desc = ODESC_ERROR; continue; } #else if (Setsockopt(xfd->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, ip4_mreqn.mreq.imr_multiaddr, ip4_mreqn.mreq.imr_interface, sizeof(ip4_mreqn.mreq), strerror(errno)); opt->desc = ODESC_ERROR; continue; } #endif break; } break; #endif /* WITH_IP4 && (defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)) */ #if WITH_IP6 && defined(HAVE_STRUCT_IPV6_MREQ) case OPT_IPV6_JOIN_GROUP: { struct ipv6_mreq ip6_mreq = {{{{0}}}}; union sockaddr_union sockaddr1; socklen_t socklen1 = sizeof(sockaddr1.ip6); /* always two parameters */ /* first parameter is multicast address */ /*! result */ xiogetaddrinfo(opt->value.u_ip_mreq.multiaddr, NULL, xfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr1, &socklen1, 0, 0); ip6_mreq.ipv6mr_multiaddr = sockaddr1.ip6.sin6_addr; if (ifindex(opt->value.u_ip_mreq.param2, &ip6_mreq.ipv6mr_interface, -1) < 0) { Error1("interface \"%s\" not found", opt->value.u_ip_mreq.param2); ip6_mreq.ipv6mr_interface = htonl(0); } if (Setsockopt(xfd->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, ip6_mreq.ipv6mr_interface, sizeof(ip6_mreq), strerror(errno)); opt->desc = ODESC_ERROR; continue; } } break; #endif /* WITH_IP6 && defined(HAVE_STRUCT_IPV6_MREQ) */ default: /* ignore here */ ++opt; continue; } break; #endif /* _WITH_SOCKET */ default: ++opt; continue; } opt->desc = ODESC_DONE; ++opt; } } return 0; } /* xfd->para.exec.pid must be set */ int applyopts_signal(struct single *xfd, struct opt *opts) { struct opt *opt; if (!opts) return 0; opt = opts; while (opt->desc != ODESC_END) { if (opt->desc == ODESC_DONE || opt->desc->func != OFUNC_SIGNAL) { ++opt; continue; } if (xio_opt_signal(xfd->para.exec.pid, opt->desc->major) < 0) { opt->desc = ODESC_ERROR; continue; } opt->desc = ODESC_DONE; ++opt; } return 0; } /* apply remaining options to file descriptor, and tell us if something is still unused */ int _xio_openlate(struct single *fd, struct opt *opts) { int numleft; int result; _xioopen_setdelayeduser(); if ((result = applyopts(fd->fd, opts, PH_LATE)) < 0) { return result; } if ((result = applyopts_single(fd, opts, PH_LATE)) < 0) { return result; } if ((result = applyopts(fd->fd, opts, PH_LATE2)) < 0) { return result; } if ((numleft = leftopts(opts)) > 0) { showleft(opts); Error1("%d option(s) could not be used", numleft); return -1; } return 0; } int dropopts(struct opt *opts, unsigned int phase) { struct opt *opt; if (phase == PH_ALL) { opts[0].desc = ODESC_END; return 0; } opt = opts; while (opt && opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && opt->desc->phase == phase) { Debug1("ignoring option \"%s\"", opt->desc->defname); opt->desc = ODESC_DONE; } ++opt; } return 0; } int dropopts2(struct opt *opts, unsigned int from, unsigned int to) { unsigned int i; for (i = from; i <= to; ++i) { dropopts(opts, i); } return 0; } socat-1.7.3.1/xio-ipapp.h0000644000201000020100000000345311453022152014637 0ustar gerhardgerhard/* source: xio-ipapp.h */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ipapp_h_included #define __xio_ipapp_h_included 1 /* when selecting a low port, this is the lowest possible */ #define XIO_IPPORT_LOWER 640 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, unsigned 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, unsigned long res_opts0, unsigned long res_opts1, union sockaddr_union *them, socklen_t *themlen, 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, unsigned groups, int socktype, int ipproto, int protname); extern int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0, const char *portname, int *pf, int ipproto, unsigned long res_opts0, unsigned long res_opts1, union sockaddr_union *us, socklen_t *uslen, int socktype); extern int xioopen_ip6app_connect(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, unsigned groups, int socktype, int ipproto, void *protname); #endif /* !defined(__xio_ipapp_h_included) */ socat-1.7.3.1/Makefile.in0000644000201000020100000001467512460744222014645 0ustar gerhardgerhard# source: Makefile.in # Copyright Gerhard Rieger # Published under the GNU General Public License V.2, see file COPYING # note: @...@ forms are filled in by configure script SHELL = /bin/sh AR = @AR@ RANLIB = @RANLIB@ .SUFFIXES: .c .o prefix = @prefix@ exec_prefix = @exec_prefix@ BINDEST = @bindir@ datarootdir = @datarootdir@ MANDEST = @mandir@ srcdir = @srcdir@ VPATH = @srcdir@ CC = @CC@ CCOPTS = $(CCOPT) SYSDEFS = @SYSDEFS@ CPPFLAGS = -I. @CPPFLAGS@ #0 INCLS = -I. @V_INCL@ DEFS = @DEFS@ LIBS = @LIBS@ LDFLAGS = @LDFLAGS@ INSTALL = @INSTALL@ #OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) @LIBOBJS@ #0 CFLAGS = @CFLAGS@ $(CCOPTS) $(DEFS) $(INCLS) CFLAGS = @CFLAGS@ $(CCOPTS) $(DEFS) $(CPPFLAGS) CLIBS = $(LIBS) #CLIBS = $(LIBS) -lm -lefence XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xiosignal.c xiosigchld.c xioread.c xiowrite.c \ xiolayer.c xioshutdown.c xioclose.c xioexit.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ xio-sctp.c xio-rawip.c \ xio-socks.c xio-proxy.c xio-udp.c \ xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ xio-pty.c xio-openssl.c xio-streams.c\ xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c XIOOBJS = $(XIOSRCS:.c=.o) UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c vsnprintf_r.c snprinterr.c @FILAN@ @SYCLS@ @SSLCLS@ UTLOBJS = $(UTLSRCS:.c=.o) CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c OFILES = $(CFILES:.c=.o) PROGS = socat procan filan HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h vsnprintf_r.h snprinterr.h compat.h \ xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ xio-system.h xio-termios.h xio-readline.h \ xio-pty.h xio-openssl.h xio-streams.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html doc/socat-genericsocket.html SHFILES = daemon.sh mail.sh ftp.sh readline.sh \ socat_buildscript_for_android.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ proxy.sh socks4a-echo.sh OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ Config/Makefile.NetBSD-5-1 Config/config.NetBSD-5-1.h \ Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h \ Config/Makefile.AIX-5-3 Config/config.AIX-5-3.h \ Config/Makefile.Cygwin-1-5-25 Config/config.Cygwin-1-5-25.h \ Config/Makefile.MacOSX-10-5 Config/config.MacOSX-10-5.h \ Config/Makefile.DragonFly-2-8-2 Config/config.DragonFly-2-8-2.h all: progs doc scmclean: gitclean gitclean: distclean docclean rm -f Makefile.bak configure doc: doc/socat.1 doc/socat.html docclean: rm -f doc/socat.1 doc/socat.html doc/socat.1: doc/socat.yo yodl2man -o $@ $+ doc/socat.html: doc/socat.yo cd doc; yodl2html -o socat.html socat.yo; cd .. progs: $(PROGS) depend: $(CFILES) $(HFILES) makedepend $(SYSDEFS) $(CFILES) socat: socat.o libxio.a $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o vsnprintf_r.o snprinterr.o procan: $(PROCAN_OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o vsnprintf_r.o snprinterr.o $(CLIBS) libxio.a: $(XIOOBJS) $(UTLOBJS) $(AR) r $@ $(XIOOBJS) $(UTLOBJS) $(RANLIB) $@ doc: doc/xio.help # strip: progs strip $(PROGS) install: progs $(srcdir)/doc/socat.1 mkdir -p $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) mkdir -p $(DESTDIR)$(MANDEST)/man1 $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ uninstall: rm -f $(DESTDIR)$(BINDEST)/socat rm -f $(DESTDIR)$(BINDEST)/procan rm -f $(DESTDIR)$(BINDEST)/filan rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 # make a GNU-zipped tar ball of the source files dist: socat.tar.gz socat.tar.bz2 socat.tar.gz: socat.tar gzip -9 socat.tar.gz socat.tar.bz2: socat.tar bzip2 -9 socat.tar.bz2 VERSION = `sed 's/"//g' VERSION` TARDIR = socat-$(VERSION) socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec \ configure.ac if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi tar cf - $+ |(cd $(TARDIR); tar xf -) tar cvf socat.tar $(TARDIR) rm -f $(TARDIR)/COPYING # write protected rm -r $(TARDIR) clean: rm -f *.o libxio.a socat procan filan \ socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ socat.out compile.log test.log # remove all files that are generated from the original socat distribution # note that Makefile is also removed, so you have to start with ./configure # again distclean: clean rm -f config.status config.cache config.log config.h Makefile rm -rf autom4te.cache info: socat uname -a >socat.out ./socat -V >>socat.out ./socat -hh >>socat.out # perform some tests on socat test: progs ./test.sh cert: # prepare critical files with correct permissions to avoid race cond >cert.key >cert.pem chmod 600 cert.key cert.pem # generate a private key openssl genrsa -out cert.key 1024 # generate a self signed cert openssl req -new -key cert.key -x509 -days 3653 -out cert.crt # ...enter fields # generate the pem file cat cert.key cert.crt >cert.pem #echo use cert.pem on requestors side, i.e. with option cert=cert.pem #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt socat-1.7.3.1/Config/0000755000201000020100000000000012652745660014002 5ustar gerhardgerhardsocat-1.7.3.1/Config/Makefile.SunOS-5-100000644000201000020100000001422311453022151017007 0ustar gerhardgerhard# source: Makefile.in # Copyright Gerhard Rieger 2001-2008 # Published under the GNU General Public License V.2, see file COPYING # note: @...@ forms are filled in by configure script SHELL = /bin/sh AR = ar RANLIB = ranlib .SUFFIXES: .c .o prefix = /usr/local exec_prefix = ${prefix} BINDEST = ${exec_prefix}/bin datarootdir = ${prefix}/share MANDEST = ${datarootdir}/man srcdir = . CC = gcc CCOPTS = $(CCOPT) -Wall -Wno-parentheses SYSDEFS = CPPFLAGS = -I. -I/usr/sfw/include #0 INCLS = -I. @V_INCL@ DEFS = -DHAVE_CONFIG_H LIBS = -lwrap -lrt -lsocket -lnsl -lresolv -lreadline -lcurses -L/usr/sfw/lib -lssl -lcrypto LDFLAGS = INSTALL = ./install-sh -c #OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) #0 CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(INCLS) CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(CPPFLAGS) CLIBS = $(LIBS) #CLIBS = $(LIBS) -lm -lefence XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xiosignal.c xiosigchld.c xioread.c xiowrite.c \ xiolayer.c xioshutdown.c xioclose.c xioexit.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ xio-sctp.c xio-rawip.c \ xio-socks.c xio-proxy.c xio-udp.c \ xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ xio-pty.c xio-openssl.c xio-streams.c\ xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c XIOOBJS = $(XIOSRCS:.c=.o) UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c UTLOBJS = $(UTLSRCS:.c=.o) CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c OFILES = $(CFILES:.c=.o) PROGS = socat procan filan HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ xio-system.h xio-termios.h xio-readline.h \ xio-pty.h xio-openssl.h xio-streams.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html SHFILES = daemon.sh mail.sh ftp.sh readline.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ proxy.sh socks4a-echo.sh testcert.conf OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h all: progs doc scmclean: gitclean gitclean: distclean docclean rm -f Makefile.bak configure doc: doc/socat.1 doc/socat.html docclean: rm -f doc/socat.1 doc/socat.html doc/socat.1: doc/socat.yo yodl2man -o $@ $+ doc/socat.html: doc/socat.yo cd doc; yodl2html -o socat.html socat.yo; cd .. progs: $(PROGS) depend: $(CFILES) $(HFILES) makedepend $(SYSDEFS) $(CFILES) socat: socat.o libxio.a $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o procan: $(PROCAN_OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) libxio.a: $(XIOOBJS) $(UTLOBJS) $(AR) r $@ $(XIOOBJS) $(UTLOBJS) $(RANLIB) $@ doc: doc/xio.help # strip: progs strip $(PROGS) install: progs $(srcdir)/doc/socat.1 mkdir -p $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) mkdir -p $(DESTDIR)$(MANDEST)/man1 $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ uninstall: rm -f $(DESTDIR)$(BINDEST)/socat rm -f $(DESTDIR)$(BINDEST)/procan rm -f $(DESTDIR)$(BINDEST)/filan rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 # make a GNU-zipped tar ball of the source files dist: socat.tar.gz socat.tar.bz2 socat.tar.gz: socat.tar gzip -9 socat.tar.gz socat.tar.bz2: socat.tar bzip2 -9 socat.tar.bz2 VERSION = `sed 's/"//g' VERSION` TARDIR = socat-$(VERSION) socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi tar cf - $+ |(cd $(TARDIR); tar xf -) tar cvf socat.tar $(TARDIR) rm -f $(TARDIR)/COPYING # write protected rm -r $(TARDIR) clean: rm -f *.o libxio.a socat procan filan \ socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ socat.out compile.log test.log # remove all files that are generated from the original socat distribution # note that Makefile is also removed, so you have to start with ./configure # again distclean: clean rm -f config.status config.cache config.log config.h Makefile rm -rf autom4te.cache info: socat uname -a >socat.out ./socat -V >>socat.out ./socat -hh >>socat.out # perform some tests on socat test: progs ./test.sh cert: # prepare critical files with correct permissions to avoid race cond >cert.key >cert.pem chmod 600 cert.key cert.pem # generate a private key openssl genrsa -out cert.key 1024 # generate a self signed cert openssl req -new -key cert.key -x509 -days 3653 -out cert.crt # ...enter fields # generate the pem file cat cert.key cert.crt >cert.pem #echo use cert.pem on requestors side, i.e. with option cert=cert.pem #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt socat-1.7.3.1/Config/Makefile.Linux-2-6-240000644000201000020100000001411611453022151017245 0ustar gerhardgerhard# source: Makefile.in # Copyright Gerhard Rieger 2001-2008 # Published under the GNU General Public License V.2, see file COPYING # note: @...@ forms are filled in by configure script SHELL = /bin/sh AR = ar RANLIB = ranlib .SUFFIXES: .c .o prefix = /usr/local exec_prefix = ${prefix} BINDEST = ${exec_prefix}/bin datarootdir = ${prefix}/share MANDEST = ${datarootdir}/man srcdir = . CC = gcc CCOPTS = $(CCOPT) -Wall -Wno-parentheses SYSDEFS = CPPFLAGS = -I. #0 INCLS = -I. @V_INCL@ DEFS = -DHAVE_CONFIG_H LIBS = -lwrap -lutil -lreadline -lssl LDFLAGS = INSTALL = /usr/bin/install -c #OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) #0 CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(INCLS) CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(CPPFLAGS) CLIBS = $(LIBS) #CLIBS = $(LIBS) -lm -lefence XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xiosignal.c xiosigchld.c xioread.c xiowrite.c \ xiolayer.c xioshutdown.c xioclose.c xioexit.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ xio-sctp.c xio-rawip.c \ xio-socks.c xio-proxy.c xio-udp.c \ xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ xio-pty.c xio-openssl.c xio-streams.c\ xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c XIOOBJS = $(XIOSRCS:.c=.o) UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c UTLOBJS = $(UTLSRCS:.c=.o) CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c OFILES = $(CFILES:.c=.o) PROGS = socat procan filan HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ xio-system.h xio-termios.h xio-readline.h \ xio-pty.h xio-openssl.h xio-streams.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html SHFILES = daemon.sh mail.sh ftp.sh readline.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ proxy.sh socks4a-echo.sh testcert.conf OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h all: progs doc scmclean: gitclean gitclean: distclean docclean rm -f Makefile.bak configure doc: doc/socat.1 doc/socat.html docclean: rm -f doc/socat.1 doc/socat.html doc/socat.1: doc/socat.yo yodl2man -o $@ $+ doc/socat.html: doc/socat.yo cd doc; yodl2html -o socat.html socat.yo; cd .. progs: $(PROGS) depend: $(CFILES) $(HFILES) makedepend $(SYSDEFS) $(CFILES) socat: socat.o libxio.a $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o procan: $(PROCAN_OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) libxio.a: $(XIOOBJS) $(UTLOBJS) $(AR) r $@ $(XIOOBJS) $(UTLOBJS) $(RANLIB) $@ doc: doc/xio.help # strip: progs strip $(PROGS) install: progs $(srcdir)/doc/socat.1 mkdir -p $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) mkdir -p $(DESTDIR)$(MANDEST)/man1 $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ uninstall: rm -f $(DESTDIR)$(BINDEST)/socat rm -f $(DESTDIR)$(BINDEST)/procan rm -f $(DESTDIR)$(BINDEST)/filan rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 # make a GNU-zipped tar ball of the source files dist: socat.tar.gz socat.tar.bz2 socat.tar.gz: socat.tar gzip -9 socat.tar.gz socat.tar.bz2: socat.tar bzip2 -9 socat.tar.bz2 VERSION = `sed 's/"//g' VERSION` TARDIR = socat-$(VERSION) socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi tar cf - $+ |(cd $(TARDIR); tar xf -) tar cvf socat.tar $(TARDIR) rm -f $(TARDIR)/COPYING # write protected rm -r $(TARDIR) clean: rm -f *.o libxio.a socat procan filan \ socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ socat.out compile.log test.log # remove all files that are generated from the original socat distribution # note that Makefile is also removed, so you have to start with ./configure # again distclean: clean rm -f config.status config.cache config.log config.h Makefile rm -rf autom4te.cache info: socat uname -a >socat.out ./socat -V >>socat.out ./socat -hh >>socat.out # perform some tests on socat test: progs ./test.sh cert: # prepare critical files with correct permissions to avoid race cond >cert.key >cert.pem chmod 600 cert.key cert.pem # generate a private key openssl genrsa -out cert.key 1024 # generate a self signed cert openssl req -new -key cert.key -x509 -days 3653 -out cert.crt # ...enter fields # generate the pem file cat cert.key cert.crt >cert.pem #echo use cert.pem on requestors side, i.e. with option cert=cert.pem #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt socat-1.7.3.1/Config/config.MacOSX-10-5.h0000644000201000020100000003357011453022151017056 0ustar gerhardgerhard/* config.h. Generated from config.h.in by configure. */ /* source: config.h.in */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __config_h_included #define __config_h_included 1 /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to `int' if doesn't define. */ /* #undef gid_t */ /* Define if your struct stat has st_blksize. */ #define HAVE_ST_BLKSIZE 1 /* Define if your struct stat has st_blocks. */ #define HAVE_ST_BLOCKS 1 /* Define if your struct stat has st_rdev. */ #define HAVE_ST_RDEV 1 /* Define if you have the strftime function. */ #define HAVE_STRFTIME 1 /* Define if you have that is POSIX.1 compatible. */ #define HAVE_SYS_WAIT_H 1 /* Define to `int' if doesn't define. */ /* #undef mode_t */ /* Define to `long' if doesn't define. */ /* #undef off_t */ /* Define to `int' if doesn't define. */ /* #undef pid_t */ /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define to `unsigned' if doesn't define. */ /* #undef size_t */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to `int' if doesn't define. */ /* #undef uid_t */ /* Define if you have the putenv function. */ #define HAVE_PUTENV 1 /* Define if you have the select function. */ #define HAVE_SELECT 1 /* Define if you have the poll function. */ #define HAVE_POLL 1 /* Define if you have the socket function. */ #define HAVE_SOCKET 1 /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define if you have the strerror function. */ #define HAVE_STRERROR 1 /* Define if you have the strstr function. */ #define HAVE_STRSTR 1 /* Define if you have the strtod function. */ #define HAVE_STRTOD 1 /* Define if you have the strtol function. */ #define HAVE_STRTOL 1 /* Define if you have the strtoul function. */ #define HAVE_STRTOUL 1 /* Define if you have the uname function. */ #define HAVE_UNAME 1 /* Define if you have the getpgid function. */ #define HAVE_GETPGID 1 /* Define if you have the getsid function. */ #define HAVE_GETSID 1 /* Define if you have the nanosleep function. */ #define HAVE_NANOSLEEP 1 /* Define if you have the getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define if you have the getipnodebyname function. */ #define HAVE_GETIPNODEBYNAME 1 /* Define if you have the setgroups function. */ #define HAVE_SETGROUPS 1 /* Define if you have the inet_aton function. */ #define HAVE_INET_ATON 1 /* Define if you have the memrchr function. */ /* #undef HAVE_MEMRCHR */ /* Define if you have the if_indextoname function. */ #define HAVE_IF_INDEXTONAME 1 /* Define if you have the sigaction function */ #define HAVE_SIGACTION 1 /* Define if you have the stat64 function */ #define HAVE_STAT64 1 /* Define if you have the fstat64 function */ #define HAVE_FSTAT64 1 /* Define if you have the lstat64 function */ #define HAVE_LSTAT64 1 /* Define if you have the lseek64 function */ /* #undef HAVE_LSEEK64 */ /* Define if you have the truncate64 function */ /* #undef HAVE_TRUNCATE64 */ /* Define if you have the ftruncate64 function */ /* #undef HAVE_FTRUNCATE64 */ /* Define if you have the strtoll function */ #define HAVE_STRTOLL 1 /* Define if you have the hstrerror function */ #define HAVE_HSTRERROR 1 /* Define if you have the inet_ntop function */ #define HAVE_INET_NTOP 1 /* Define if you have the hstrerror prototype */ #define HAVE_PROTOTYPE_HSTRERROR 1 /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define if you have the header file. */ #define HAVE_SYSLOG_H 1 /* Define if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define if you have the header file. */ #define HAVE_PWD_H 1 /* Define if you have the header file. */ #define HAVE_GRP_H 1 /* Define if you have the header file. */ #define HAVE_STDINT_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define if you have the header file. */ #define HAVE_SYS_POLL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define if you have the header file. */ #define HAVE_NETDB_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UN_H 1 /* Define if you have the header file. */ /* #undef HAVE_PTY_H */ /* Define if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IN_SYSTM_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP6_H 1 /* Define if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define if you have the header file. */ #define HAVE_RESOLV_H 1 /* Define if you have the header file. */ #define HAVE_TERMIOS_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_DL_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_TYPES_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_ERRQUEUE_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_IF_TUN_H */ /* Define if you have the header file. */ /* #undef HAVE_NETPACKET_PACKET_H */ /* Define if you have the header file. */ /* #undef HAVE_NETINET_IF_ETHER_H */ /* Define if you have the header file. */ #define HAVE_SYS_UTSNAME_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_SELECT_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_FILE_H 1 /* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ #define HAVE_UTIL_H 1 /* Define if you have the header file. (FreeBSD: openpty()) */ /* #undef HAVE_LIBUTIL_H */ /* Define if you have the header file. (stream opts on SunOS)*/ /* #undef HAVE_SYS_STROPTS_H */ /* Define if you have the header file. */ #define HAVE_REGEX_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_FS_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_EXT2_FS_H */ /* Define if you have the header file. */ #define HAVE_READLINE_READLINE_H 1 /* Define if you have the header file. */ #define HAVE_READLINE_HISTORY_H 1 /* Define if you have the readline library. */ #define HAVE_LIBREADLINE 1 /* Define if you have the m library (-lm). */ /* #undef HAVE_LIBM */ /* Define if you have the floor function */ /* #undef HAVE_FLOOR */ /* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ /* #undef _XOPEN_EXTENDED_SOURCE */ /* fdset may have component fds_bits or __fds_bits */ #define HAVE_FDS_BITS 1 /* Define if you have the sa_family_t */ #define HAVE_TYPE_SA_FAMILY_T 1 /* define if your struct sigaction has sa_sigaction */ #define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 /* Define if your struct termios has component c_ispeed */ #define HAVE_TERMIOS_ISPEED 1 /* the offset of c_ispeed in struct termios - usable in an speed_t array. Applies only when HAVE_TERMIOS_ISPEED is set */ #define ISPEED_OFFSET 9 /* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ #ifdef ISPEED_OFFSET # define OSPEED_OFFSET (ISPEED_OFFSET+1) #else /* # undef OSPEED_OFFSET */ #endif /* Define if your termios.h likes _SVID3 defined */ /* #undef _SVID3 */ /* Define if you have struct timespec (e.g. for nanosleep) */ #define HAVE_STRUCT_TIMESPEC 1 /* Define if you have struct linger */ #define HAVE_STRUCT_LINGER 1 /* Define if you have struct ip_mreq */ #define HAVE_STRUCT_IP_MREQ 1 /* Define if you have struct ip_mreqn */ /* #undef HAVE_STRUCT_IP_MREQN */ /* Define if you have struct ipv6_mreq */ #define HAVE_STRUCT_IPV6_MREQ 1 /* Define if you have struct ifreq */ #define HAVE_STRUCT_IFREQ 1 /* Define if you have struct ifreq.ifr_index */ /* #undef HAVE_STRUCT_IFREQ_IFR_INDEX */ /* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ /* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ /* Define if your struct sockaddr has sa_len */ #define HAVE_STRUCT_SOCKADDR_SALEN 1 /* there are several implementations of sockaddr_in6 */ #define HAVE_IP6_SOCKADDR 0 /* Define if you have struct iovec */ #define HAVE_STRUCT_IOVEC 1 /* define if your struct msghdr has msg_control */ #define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 /* define if your struct msghdr has msg_controllen */ #define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 /* define if your struct msghdr has msg_flag */ #define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 /* define if you have struct cmsghdr */ #define HAVE_STRUCT_CMSGHDR 1 /* define if you have struct in_pktinfo */ /* #undef HAVE_STRUCT_IN_PKTINFO */ /* define if your struct ip has ip_hl; otherwise assume ip_vhl */ #define HAVE_STRUCT_IP_IP_HL 1 /* Define if you have the setenv function */ #define HAVE_SETENV 1 /* Define if you have the unsetenv function. not on HP-UX */ #define HAVE_UNSETENV 1 /* Define if you have the flock function */ #define HAVE_FLOCK 1 /* Define if you have the openpty function */ #define HAVE_OPENPTY 1 /* Define if you have the grantpt function */ #define HAVE_GRANTPT 1 /* Define if you have the unlockpt function */ #define HAVE_UNLOCKPT 1 /* Define if you have the ptsname function */ #define HAVE_PTSNAME 1 /* Define if you have the /dev/ptmx pseudo terminal multiplexer */ #define HAVE_DEV_PTMX 1 /* Define if you have the /dev/ptc pseudo terminal multiplexer */ /* #undef HAVE_DEV_PTC */ /* Define if you have the long long type */ #define HAVE_TYPE_LONGLONG 1 /* is socklen_t already typedef'd? */ #define HAVE_TYPE_SOCKLEN 1 /* Define if you have the struct stat64 type */ #define HAVE_TYPE_STAT64 1 /* Define if you have the struct off64_t type */ /* #undef HAVE_TYPE_OFF64 */ /* is sighandler_t already typedef'd? */ /* #undef HAVE_TYPE_SIGHANDLER */ /* is uint8_t already defined? */ #define HAVE_TYPE_UINT8 1 /* is uint16_t already defined? */ #define HAVE_TYPE_UINT16 1 /* is uint32_t already defined? */ #define HAVE_TYPE_UINT32 1 /* is uint64_t already defined? */ #define HAVE_TYPE_UINT64 1 /* Define if you have the printf "Z" modifier */ /* #undef HAVE_FORMAT_Z */ /* Define the shift offset of the CRDLY mask */ #define CRDLY_SHIFT 12 /* Define the shift offset of the TABDLY mask */ #define TABDLY_SHIFT -1 /* Define the shift offset of the CSIZE mask */ #define CSIZE_SHIFT 8 /* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ #define HAVE_HOSTS_ALLOW_TABLE 1 #if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE # define HAVE_HOSTS_DENY_TABLE 1 #else /* # undef HAVE_HOSTS_DENY_TABLE */ #endif /* 1..short, 3..int, 5..long; 2,4,6..unsigned */ #define HAVE_BASIC_SIZE_T 6 /* unsigned long */ #define HAVE_BASIC_MODE_T 2 /* unsigned short */ #define HAVE_BASIC_PID_T 3 /* int */ #define HAVE_BASIC_UID_T 4 /* unsigned int */ #define HAVE_BASIC_GID_T 4 /* unsigned int */ #define HAVE_BASIC_TIME_T 5 /* long */ #define HAVE_BASIC_OFF64_T 0 /* unknown, taking default */ #define HAVE_BASIC_SOCKLEN_T 4 /* unsigned int */ #define HAVE_TYPEOF_ST_DEV 3 /* int */ #define HAVE_TYPEOF_ST_INO 4 /* unsigned int */ #define HAVE_TYPEOF_ST_NLINK 2 /* unsigned short */ #define HAVE_TYPEOF_ST_SIZE 7 /* long long */ #define HAVE_TYPEOF_ST_BLKSIZE 3 /* int */ #define HAVE_TYPEOF_ST_BLOCKS 7 /* long long */ #define HAVE_TYPEOF_ST64_DEV 3 /* int */ #define HAVE_TYPEOF_ST64_INO 8 /* unsigned long long */ #define HAVE_TYPEOF_ST64_NLINK 2 /* unsigned short */ #define HAVE_TYPEOF_ST64_SIZE 7 /* long long */ #define HAVE_TYPEOF_ST64_BLKSIZE 3 /* int */ #define HAVE_TYPEOF_ST64_BLOCKS 7 /* long long */ #define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 3 /* int */ #define HAVE_TYPEOF_RLIM_MAX 8 /* unsigned long long */ /* Define if you have the /proc filesystem */ /* #undef HAVE_PROC_DIR */ /* Define if you have the /proc/$$/fd directories */ /* #undef HAVE_PROC_DIR_FD */ #define WITH_HELP 1 #define WITH_STDIO 1 #define WITH_FDNUM 1 #define WITH_FILE 1 #define WITH_CREAT 1 #define WITH_GOPEN 1 #define WITH_TERMIOS 1 #define WITH_PIPE 1 #define WITH_UNIX 1 /* #undef WITH_ABSTRACT_UNIXSOCKET */ #define WITH_IP4 1 #define WITH_IP6 1 #define WITH_RAWIP 1 #define WITH_GENERICSOCKET 1 /* #undef WITH_INTERFACE */ #define WITH_TCP 1 #define WITH_UDP 1 /* #undef WITH_SCTP */ #define WITH_LISTEN 1 #define WITH_SOCKS4 1 #define WITH_SOCKS4A 1 #define WITH_PROXY 1 #define WITH_EXEC 1 #define WITH_SYSTEM 1 #define WITH_READLINE 1 /* #undef WITH_TUN */ #define WITH_PTY 1 #define WITH_EXT2 1 #define WITH_OPENSSL 1 #define WITH_STREAMS 1 /* #undef WITH_FIPS */ /* #undef OPENSSL_FIPS */ #define WITH_LIBWRAP 1 #define HAVE_TCPD_H 1 #define HAVE_LIBWRAP 1 #define WITH_SYCLS 1 #define WITH_FILAN 1 #define WITH_RETRY 1 #define WITH_MSGLEVEL 0 #endif /* !defined(__config_h_included) */ socat-1.7.3.1/Config/config.DragonFly-2-8-2.h0000644000201000020100000003502011666357711017747 0ustar gerhardgerhard/* config.h. Generated from config.h.in by configure. */ /* source: config.h.in */ /* Copyright Gerhard Rieger 2001-2011 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __config_h_included #define __config_h_included 1 /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to `int' if doesn't define. */ /* #undef gid_t */ /* Define if your struct stat has st_blksize. */ #define HAVE_ST_BLKSIZE 1 /* Define if your struct stat has st_blocks. */ #define HAVE_ST_BLOCKS 1 /* Define if your struct stat has st_rdev. */ #define HAVE_ST_RDEV 1 /* Define if you have the strftime function. */ #define HAVE_STRFTIME 1 /* Define if you have that is POSIX.1 compatible. */ #define HAVE_SYS_WAIT_H 1 /* Define to `int' if doesn't define. */ /* #undef mode_t */ /* Define to `long' if doesn't define. */ /* #undef off_t */ /* Define to `int' if doesn't define. */ /* #undef pid_t */ /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define to `unsigned' if doesn't define. */ /* #undef size_t */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to `int' if doesn't define. */ /* #undef uid_t */ /* Define if you have the putenv function. */ #define HAVE_PUTENV 1 /* Define if you have the select function. */ #define HAVE_SELECT 1 /* Define if you have the poll function. */ #define HAVE_POLL 1 /* Define if you have the socket function. */ #define HAVE_SOCKET 1 /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define if you have the strerror function. */ #define HAVE_STRERROR 1 /* Define if you have the strstr function. */ #define HAVE_STRSTR 1 /* Define if you have the strtod function. */ #define HAVE_STRTOD 1 /* Define if you have the strtol function. */ #define HAVE_STRTOL 1 /* Define if you have the strtoul function. */ #define HAVE_STRTOUL 1 /* Define if you have the uname function. */ #define HAVE_UNAME 1 /* Define if you have the getpgid function. */ #define HAVE_GETPGID 1 /* Define if you have the getsid function. */ #define HAVE_GETSID 1 /* Define if you have the nanosleep function. */ #define HAVE_NANOSLEEP 1 /* Define if you have the getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define if you have the getipnodebyname function. */ #define HAVE_GETIPNODEBYNAME 1 /* Define if you have the setgroups function. */ #define HAVE_SETGROUPS 1 /* Define if you have the inet_aton function. */ #define HAVE_INET_ATON 1 /* Define if you have the memrchr function. */ #define HAVE_MEMRCHR 1 /* Define if you have the if_indextoname function. */ #define HAVE_IF_INDEXTONAME 1 /* Define if you have the sigaction function */ #define HAVE_SIGACTION 1 /* Define if you have the stat64 function */ /* #undef HAVE_STAT64 */ /* Define if you have the fstat64 function */ /* #undef HAVE_FSTAT64 */ /* Define if you have the lstat64 function */ /* #undef HAVE_LSTAT64 */ /* Define if you have the lseek64 function */ /* #undef HAVE_LSEEK64 */ /* Define if you have the truncate64 function */ /* #undef HAVE_TRUNCATE64 */ /* Define if you have the ftruncate64 function */ /* #undef HAVE_FTRUNCATE64 */ /* Define if you have the strtoll function */ #define HAVE_STRTOLL 1 /* Define if you have the hstrerror function */ #define HAVE_HSTRERROR 1 /* Define if you have the inet_ntop function */ #define HAVE_INET_NTOP 1 /* Define if you have the hstrerror prototype */ #define HAVE_PROTOTYPE_HSTRERROR 1 /* Define if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define if you have the header file. */ #define HAVE_SYSLOG_H 1 /* Define if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define if you have the header file. */ #define HAVE_PWD_H 1 /* Define if you have the header file. */ #define HAVE_GRP_H 1 /* Define if you have the header file. */ #define HAVE_STDINT_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define if you have the header file. */ #define HAVE_SYS_POLL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define if you have the header file. */ #define HAVE_NETDB_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UN_H 1 /* Define if you have the header file. */ /* #undef HAVE_PTY_H */ /* Define if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IN_SYSTM_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP6_H 1 /* Define if you have the header file. */ /* #undef HAVE_NETINET6_IN6_H */ /* Define if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define if you have the header file. */ #define HAVE_RESOLV_H 1 /* Define if you have the header file. */ #define HAVE_TERMIOS_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_DL_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_TYPES_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_ERRQUEUE_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_IF_TUN_H */ /* Define if you have the header file. */ /* #undef HAVE_NETPACKET_PACKET_H */ /* Define if you have the header file. */ /* #undef HAVE_NETINET_IF_ETHER_H */ /* Define if you have the header file. */ #define HAVE_SYS_UTSNAME_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_SELECT_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_FILE_H 1 /* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ /* #undef HAVE_UTIL_H */ /* Define if you have the header file. */ /* #undef HAVE_BSD_LIBUTIL_H */ /* Define if you have the header file. (FreeBSD: openpty()) */ #define HAVE_LIBUTIL_H 1 /* Define if you have the header file. (stream opts on SunOS)*/ /* #undef HAVE_SYS_STROPTS_H */ /* Define if you have the header file. */ #define HAVE_REGEX_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_FS_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_EXT2_FS_H */ /* Define if you have the header file. */ /* #undef HAVE_READLINE_READLINE_H */ /* Define if you have the header file. */ /* #undef HAVE_READLINE_HISTORY_H */ /* Define if you have the readline library. */ /* #undef HAVE_LIBREADLINE */ /* Define if you have the m library (-lm). */ /* #undef HAVE_LIBM */ /* Define if you have the floor function */ /* #undef HAVE_FLOOR */ /* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ /* #undef _XOPEN_EXTENDED_SOURCE */ /* fdset may have component fds_bits or __fds_bits */ #define HAVE_FDS_BITS 1 /* Define if you have the sa_family_t */ #define HAVE_TYPE_SA_FAMILY_T 1 /* define if your struct sigaction has sa_sigaction */ #define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 /* Define if your struct termios has component c_ispeed */ #define HAVE_TERMIOS_ISPEED 1 /* the offset of c_ispeed in struct termios - usable in an speed_t array. Applies only when HAVE_TERMIOS_ISPEED is set */ #define ISPEED_OFFSET 9 /* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ #ifdef ISPEED_OFFSET # define OSPEED_OFFSET (ISPEED_OFFSET+1) #else /* # undef OSPEED_OFFSET */ #endif /* Define if your termios.h likes _SVID3 defined */ /* #undef _SVID3 */ /* Define if you have struct timespec (e.g. for nanosleep) */ #define HAVE_STRUCT_TIMESPEC 1 /* Define if you have struct linger */ #define HAVE_STRUCT_LINGER 1 /* Define if you have struct ip_mreq */ #define HAVE_STRUCT_IP_MREQ 1 /* Define if you have struct ip_mreqn */ /* #undef HAVE_STRUCT_IP_MREQN */ /* Define if you have struct ipv6_mreq */ #define HAVE_STRUCT_IPV6_MREQ 1 /* Define if you have struct ifreq */ #define HAVE_STRUCT_IFREQ 1 /* Define if you have struct ifreq.ifr_index */ #define HAVE_STRUCT_IFREQ_IFR_INDEX 1 /* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ /* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ /* Define if your struct sockaddr has sa_len */ #define HAVE_STRUCT_SOCKADDR_SALEN 1 /* there are several implementations of sockaddr_in6 */ #define HAVE_IP6_SOCKADDR 0 /* Define if you have struct iovec */ #define HAVE_STRUCT_IOVEC 1 /* define if your struct msghdr has msg_control */ #define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 /* define if your struct msghdr has msg_controllen */ #define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 /* define if your struct msghdr has msg_flag */ #define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 /* define if you have struct cmsghdr */ #define HAVE_STRUCT_CMSGHDR 1 /* define if you have struct in_pktinfo */ /* #undef HAVE_STRUCT_IN_PKTINFO */ /* define if your struct in_pktinfo has component ipi_spec_dst */ /* #undef HAVE_PKTINFO_IPI_SPEC_DST */ /* define if your struct ip has ip_hl; otherwise assume ip_vhl */ #define HAVE_STRUCT_IP_IP_HL 1 /* Define if you have the setenv function */ #define HAVE_SETENV 1 /* Define if you have the unsetenv function. not on HP-UX */ #define HAVE_UNSETENV 1 /* Define if you have the SSLv2_client_method function. not in new openssl */ /* #undef HAVE_SSLv2_client_method */ /* Define if you have the SSLv2_server_method function. not in new openssl */ #define HAVE_SSLv2_server_method 1 /* Define if you have the flock function */ #define HAVE_FLOCK 1 /* Define if you have the openpty function */ #define HAVE_OPENPTY 1 /* Define if you have the grantpt function */ #define HAVE_GRANTPT 1 /* Define if you have the unlockpt function */ #define HAVE_UNLOCKPT 1 /* Define if you have the ptsname function */ #define HAVE_PTSNAME 1 /* Define if you have the /dev/ptmx pseudo terminal multiplexer */ #define HAVE_DEV_PTMX 1 /* Define if you have the /dev/ptc pseudo terminal multiplexer */ /* #undef HAVE_DEV_PTC */ /* Define if you have the long long type */ #define HAVE_TYPE_LONGLONG 1 /* is socklen_t already typedef'd? */ #define HAVE_TYPE_SOCKLEN 1 /* Define if you have the struct stat64 type */ /* #undef HAVE_TYPE_STAT64 */ /* Define if you have the struct off64_t type */ /* #undef HAVE_TYPE_OFF64 */ /* is sighandler_t already typedef'd? */ /* #undef HAVE_TYPE_SIGHANDLER */ /* is uint8_t already defined? */ #define HAVE_TYPE_UINT8 1 /* is uint16_t already defined? */ #define HAVE_TYPE_UINT16 1 /* is uint32_t already defined? */ #define HAVE_TYPE_UINT32 1 /* is uint64_t already defined? */ #define HAVE_TYPE_UINT64 1 /* Define if you have the printf "Z" modifier */ /* #undef HAVE_FORMAT_Z */ /* Define the shift offset of the CRDLY mask */ #define CRDLY_SHIFT -1 /* Define the shift offset of the TABDLY mask */ #define TABDLY_SHIFT -1 /* Define the shift offset of the CSIZE mask */ #define CSIZE_SHIFT 8 /* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ #define HAVE_HOSTS_ALLOW_TABLE 1 #if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE # define HAVE_HOSTS_DENY_TABLE 1 #else /* # undef HAVE_HOSTS_DENY_TABLE */ #endif /* 1..short, 3..int, 5..long; 2,4,6..unsigned */ #define HAVE_BASIC_SIZE_T 4 /* unsigned int */ #define HAVE_BASIC_MODE_T 2 /* unsigned short */ #define HAVE_BASIC_PID_T 3 /* int */ #define HAVE_BASIC_UID_T 4 /* unsigned int */ #define HAVE_BASIC_GID_T 4 /* unsigned int */ #define HAVE_BASIC_TIME_T 5 /* long */ #define HAVE_BASIC_OFF_T 7 /* long long */ #define HAVE_BASIC_OFF64_T 0 /* unknown, taking default */ #define HAVE_BASIC_DEV_T 4 /* unsigned int */ #define HAVE_BASIC_SOCKLEN_T 4 /* unsigned int */ #define HAVE_TYPEOF_ST_INO 8 /* unsigned long long */ #define HAVE_TYPEOF_ST_NLINK 4 /* unsigned int */ #define HAVE_TYPEOF_ST_SIZE 7 /* long long */ #define HAVE_TYPEOF_ST_BLKSIZE 4 /* unsigned int */ #define HAVE_TYPEOF_ST_BLOCKS 7 /* long long */ /* #undef HAVE_TYPEOF_ST64_DEV */ /* #undef HAVE_TYPEOF_ST64_INO */ /* #undef HAVE_TYPEOF_ST64_NLINK */ /* #undef HAVE_TYPEOF_ST64_SIZE */ /* #undef HAVE_TYPEOF_ST64_BLKSIZE */ /* #undef HAVE_TYPEOF_ST64_BLOCKS */ #define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 /* long */ #define HAVE_TYPEOF_RLIM_MAX 7 /* long long */ /* Define if you have the /proc filesystem */ #define HAVE_PROC_DIR 1 /* Define if you have the /proc/$$/fd directories */ /* #undef HAVE_PROC_DIR_FD */ #define HAVE_SETGRENT 1 #define HAVE_GETGRENT 1 #define HAVE_ENDGRENT 1 #define WITH_HELP 1 #define WITH_STDIO 1 #define WITH_FDNUM 1 #define WITH_FILE 1 #define WITH_CREAT 1 #define WITH_GOPEN 1 #define WITH_TERMIOS 1 #define WITH_PIPE 1 #define WITH_UNIX 1 /* #undef WITH_ABSTRACT_UNIXSOCKET */ #define WITH_IP4 1 #define WITH_IP6 1 #define WITH_RAWIP 1 #define WITH_GENERICSOCKET 1 /* #undef WITH_INTERFACE */ #define WITH_TCP 1 #define WITH_UDP 1 #define WITH_SCTP 1 #define WITH_LISTEN 1 #define WITH_SOCKS4 1 #define WITH_SOCKS4A 1 #define WITH_PROXY 1 #define WITH_EXEC 1 #define WITH_SYSTEM 1 /* #undef WITH_READLINE */ /* #undef WITH_TUN */ #define WITH_PTY 1 #define WITH_EXT2 1 #define WITH_OPENSSL 1 #define WITH_STREAMS 1 /* #undef WITH_FIPS */ /* #undef OPENSSL_FIPS */ #define WITH_LIBWRAP 1 #define HAVE_TCPD_H 1 #define HAVE_LIBWRAP 1 #define WITH_SYCLS 1 #define WITH_FILAN 1 #define WITH_RETRY 1 #define WITH_MSGLEVEL 0 #endif /* !defined(__config_h_included) */ socat-1.7.3.1/Config/Makefile.AIX-5-30000644000201000020100000001407211453022151016345 0ustar gerhardgerhard# source: Makefile.in # Copyright Gerhard Rieger 2001-2008 # Published under the GNU General Public License V.2, see file COPYING # note: @...@ forms are filled in by configure script SHELL = /bin/sh AR = ar RANLIB = ranlib .SUFFIXES: .c .o prefix = /usr/local exec_prefix = ${prefix} BINDEST = ${exec_prefix}/bin datarootdir = ${prefix}/share MANDEST = ${datarootdir}/man srcdir = . CC = cc -qlanglvl=extc89 CCOPTS = $(CCOPT) SYSDEFS = CPPFLAGS = -I. #0 INCLS = -I. @V_INCL@ DEFS = -DHAVE_CONFIG_H LIBS = -lbsd -lssl -lcrypto LDFLAGS = INSTALL = ./install-sh -c #OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) #0 CFLAGS = -O $(CCOPTS) $(DEFS) $(INCLS) CFLAGS = -O $(CCOPTS) $(DEFS) $(CPPFLAGS) CLIBS = $(LIBS) #CLIBS = $(LIBS) -lm -lefence XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xiosignal.c xiosigchld.c xioread.c xiowrite.c \ xiolayer.c xioshutdown.c xioclose.c xioexit.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ xio-sctp.c xio-rawip.c \ xio-socks.c xio-proxy.c xio-udp.c \ xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ xio-pty.c xio-openssl.c xio-streams.c\ xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c XIOOBJS = $(XIOSRCS:.c=.o) UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c UTLOBJS = $(UTLSRCS:.c=.o) CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c OFILES = $(CFILES:.c=.o) PROGS = socat procan filan HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ xio-system.h xio-termios.h xio-readline.h \ xio-pty.h xio-openssl.h xio-streams.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html doc/socat-genericsocket.html SHFILES = daemon.sh mail.sh ftp.sh readline.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ proxy.sh socks4a-echo.sh testcert.conf OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h all: progs doc scmclean: gitclean gitclean: distclean docclean rm -f Makefile.bak configure doc: doc/socat.1 doc/socat.html docclean: rm -f doc/socat.1 doc/socat.html doc/socat.1: doc/socat.yo yodl2man -o $@ $+ doc/socat.html: doc/socat.yo cd doc; yodl2html -o socat.html socat.yo; cd .. progs: $(PROGS) depend: $(CFILES) $(HFILES) makedepend $(SYSDEFS) $(CFILES) socat: socat.o libxio.a $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o procan: $(PROCAN_OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) libxio.a: $(XIOOBJS) $(UTLOBJS) $(AR) r $@ $(XIOOBJS) $(UTLOBJS) $(RANLIB) $@ doc: doc/xio.help # strip: progs strip $(PROGS) install: progs $(srcdir)/doc/socat.1 mkdir -p $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) mkdir -p $(DESTDIR)$(MANDEST)/man1 $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ uninstall: rm -f $(DESTDIR)$(BINDEST)/socat rm -f $(DESTDIR)$(BINDEST)/procan rm -f $(DESTDIR)$(BINDEST)/filan rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 # make a GNU-zipped tar ball of the source files dist: socat.tar.gz socat.tar.bz2 socat.tar.gz: socat.tar gzip -9 socat.tar.gz socat.tar.bz2: socat.tar bzip2 -9 socat.tar.bz2 VERSION = `sed 's/"//g' VERSION` TARDIR = socat-$(VERSION) socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi tar cf - $+ |(cd $(TARDIR); tar xf -) tar cvf socat.tar $(TARDIR) rm -f $(TARDIR)/COPYING # write protected rm -r $(TARDIR) clean: rm -f *.o libxio.a socat procan filan \ socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ socat.out compile.log test.log # remove all files that are generated from the original socat distribution # note that Makefile is also removed, so you have to start with ./configure # again distclean: clean rm -f config.status config.cache config.log config.h Makefile rm -rf autom4te.cache info: socat uname -a >socat.out ./socat -V >>socat.out ./socat -hh >>socat.out # perform some tests on socat test: progs ./test.sh cert: # prepare critical files with correct permissions to avoid race cond >cert.key >cert.pem chmod 600 cert.key cert.pem # generate a private key openssl genrsa -out cert.key 1024 # generate a self signed cert openssl req -new -key cert.key -x509 -days 3653 -out cert.crt # ...enter fields # generate the pem file cat cert.key cert.crt >cert.pem #echo use cert.pem on requestors side, i.e. with option cert=cert.pem #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt socat-1.7.3.1/Config/Makefile.OpenBSD-4-30000644000201000020100000001422711453022151017157 0ustar gerhardgerhard# source: Makefile.in # Copyright Gerhard Rieger 2001-2008 # Published under the GNU General Public License V.2, see file COPYING # note: @...@ forms are filled in by configure script SHELL = /bin/sh AR = ar RANLIB = ranlib .SUFFIXES: .c .o prefix = /usr/local exec_prefix = ${prefix} BINDEST = ${exec_prefix}/bin datarootdir = ${prefix}/share MANDEST = ${datarootdir}/man srcdir = . CC = gcc CCOPTS = $(CCOPT) -Wall -Wno-parentheses SYSDEFS = -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=5 CPPFLAGS = -I. #0 INCLS = -I. @V_INCL@ DEFS = -DHAVE_CONFIG_H LIBS = -lwrap -lutil -lreadline -lcurses -lssl -lcrypto LDFLAGS = INSTALL = /usr/bin/install -c #OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) #0 CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(INCLS) CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(CPPFLAGS) CLIBS = $(LIBS) #CLIBS = $(LIBS) -lm -lefence XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xiosignal.c xiosigchld.c xioread.c xiowrite.c \ xiolayer.c xioshutdown.c xioclose.c xioexit.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ xio-sctp.c xio-rawip.c \ xio-socks.c xio-proxy.c xio-udp.c \ xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ xio-pty.c xio-openssl.c xio-streams.c\ xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c XIOOBJS = $(XIOSRCS:.c=.o) UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c UTLOBJS = $(UTLSRCS:.c=.o) CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c OFILES = $(CFILES:.c=.o) PROGS = socat procan filan HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ xio-system.h xio-termios.h xio-readline.h \ xio-pty.h xio-openssl.h xio-streams.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html SHFILES = daemon.sh mail.sh ftp.sh readline.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ proxy.sh socks4a-echo.sh testcert.conf OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h all: progs doc scmclean: gitclean gitclean: distclean docclean rm -f Makefile.bak configure doc: doc/socat.1 doc/socat.html docclean: rm -f doc/socat.1 doc/socat.html doc/socat.1: doc/socat.yo yodl2man -o $@ $+ doc/socat.html: doc/socat.yo cd doc; yodl2html -o socat.html socat.yo; cd .. progs: $(PROGS) depend: $(CFILES) $(HFILES) makedepend $(SYSDEFS) $(CFILES) socat: socat.o libxio.a $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o procan: $(PROCAN_OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) libxio.a: $(XIOOBJS) $(UTLOBJS) $(AR) r $@ $(XIOOBJS) $(UTLOBJS) $(RANLIB) $@ doc: doc/xio.help # strip: progs strip $(PROGS) install: progs $(srcdir)/doc/socat.1 mkdir -p $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) mkdir -p $(DESTDIR)$(MANDEST)/man1 $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ uninstall: rm -f $(DESTDIR)$(BINDEST)/socat rm -f $(DESTDIR)$(BINDEST)/procan rm -f $(DESTDIR)$(BINDEST)/filan rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 # make a GNU-zipped tar ball of the source files dist: socat.tar.gz socat.tar.bz2 socat.tar.gz: socat.tar gzip -9 socat.tar.gz socat.tar.bz2: socat.tar bzip2 -9 socat.tar.bz2 VERSION = `sed 's/"//g' VERSION` TARDIR = socat-$(VERSION) socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi tar cf - $+ |(cd $(TARDIR); tar xf -) tar cvf socat.tar $(TARDIR) rm -f $(TARDIR)/COPYING # write protected rm -r $(TARDIR) clean: rm -f *.o libxio.a socat procan filan \ socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ socat.out compile.log test.log # remove all files that are generated from the original socat distribution # note that Makefile is also removed, so you have to start with ./configure # again distclean: clean rm -f config.status config.cache config.log config.h Makefile rm -rf autom4te.cache info: socat uname -a >socat.out ./socat -V >>socat.out ./socat -hh >>socat.out # perform some tests on socat test: progs ./test.sh cert: # prepare critical files with correct permissions to avoid race cond >cert.key >cert.pem chmod 600 cert.key cert.pem # generate a private key openssl genrsa -out cert.key 1024 # generate a self signed cert openssl req -new -key cert.key -x509 -days 3653 -out cert.crt # ...enter fields # generate the pem file cat cert.key cert.crt >cert.pem #echo use cert.pem on requestors side, i.e. with option cert=cert.pem #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt socat-1.7.3.1/Config/config.NetBSD-5-1.h0000644000201000020100000003351312326025135016765 0ustar gerhardgerhard/* config.h. Generated from config.h.in by configure. */ /* source: config.h.in */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __config_h_included #define __config_h_included 1 /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to `int' if doesn't define. */ /* #undef gid_t */ /* Define if your struct stat has st_blksize. */ #define HAVE_ST_BLKSIZE 1 /* Define if your struct stat has st_blocks. */ #define HAVE_ST_BLOCKS 1 /* Define if your struct stat has st_rdev. */ #define HAVE_ST_RDEV 1 /* Define if you have the strftime function. */ #define HAVE_STRFTIME 1 /* Define if you have that is POSIX.1 compatible. */ #define HAVE_SYS_WAIT_H 1 /* Define to `int' if doesn't define. */ /* #undef mode_t */ /* Define to `long' if doesn't define. */ /* #undef off_t */ /* Define to `int' if doesn't define. */ /* #undef pid_t */ /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define to `unsigned' if doesn't define. */ /* #undef size_t */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to `int' if doesn't define. */ /* #undef uid_t */ /* Define if you have the putenv function. */ #define HAVE_PUTENV 1 /* Define if you have the select function. */ #define HAVE_SELECT 1 /* Define if you have the poll function. */ #define HAVE_POLL 1 /* Define if you have the socket function. */ #define HAVE_SOCKET 1 /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define if you have the strerror function. */ #define HAVE_STRERROR 1 /* Define if you have the strstr function. */ #define HAVE_STRSTR 1 /* Define if you have the strtod function. */ #define HAVE_STRTOD 1 /* Define if you have the strtol function. */ #define HAVE_STRTOL 1 /* Define if you have the strtoul function. */ #define HAVE_STRTOUL 1 /* Define if you have the uname function. */ #define HAVE_UNAME 1 /* Define if you have the getpgid function. */ #define HAVE_GETPGID 1 /* Define if you have the getsid function. */ #define HAVE_GETSID 1 /* Define if you have the nanosleep function. */ #define HAVE_NANOSLEEP 1 /* Define if you have the getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define if you have the getipnodebyname function. */ /* #undef HAVE_GETIPNODEBYNAME */ /* Define if you have the setgroups function. */ #define HAVE_SETGROUPS 1 /* Define if you have the inet_aton function. */ #define HAVE_INET_ATON 1 /* Define if you have the memrchr function. */ /* #undef HAVE_MEMRCHR */ /* Define if you have the if_indextoname function. */ #define HAVE_IF_INDEXTONAME 1 /* Define if you have the sigaction function */ #define HAVE_SIGACTION 1 /* Define if you have the stat64 function */ /* #undef HAVE_STAT64 */ /* Define if you have the fstat64 function */ /* #undef HAVE_FSTAT64 */ /* Define if you have the lstat64 function */ /* #undef HAVE_LSTAT64 */ /* Define if you have the lseek64 function */ /* #undef HAVE_LSEEK64 */ /* Define if you have the truncate64 function */ /* #undef HAVE_TRUNCATE64 */ /* Define if you have the ftruncate64 function */ /* #undef HAVE_FTRUNCATE64 */ /* Define if you have the strtoll function */ #define HAVE_STRTOLL 1 /* Define if you have the hstrerror function */ #define HAVE_HSTRERROR 1 /* Define if you have the inet_ntop function */ #define HAVE_INET_NTOP 1 /* Define if you have the hstrerror prototype */ #define HAVE_PROTOTYPE_HSTRERROR 1 /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define if you have the header file. */ #define HAVE_SYSLOG_H 1 /* Define if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define if you have the header file. */ #define HAVE_PWD_H 1 /* Define if you have the header file. */ #define HAVE_GRP_H 1 /* Define if you have the header file. */ #define HAVE_STDINT_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define if you have the header file. */ #define HAVE_SYS_POLL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define if you have the header file. */ #define HAVE_NETDB_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UN_H 1 /* Define if you have the header file. */ /* #undef HAVE_PTY_H */ /* Define if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IN_SYSTM_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP6_H 1 /* Define if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define if you have the header file. */ #define HAVE_RESOLV_H 1 /* Define if you have the header file. */ #define HAVE_TERMIOS_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_DL_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_TYPES_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_ERRQUEUE_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_IF_TUN_H */ /* Define if you have the header file. */ /* #undef HAVE_NETPACKET_PACKET_H */ /* Define if you have the header file. */ /* #undef HAVE_NETINET_IF_ETHER_H */ /* Define if you have the header file. */ #define HAVE_SYS_UTSNAME_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_SELECT_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_FILE_H 1 /* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ #define HAVE_UTIL_H 1 /* Define if you have the header file. (FreeBSD: openpty()) */ /* #undef HAVE_LIBUTIL_H */ /* Define if you have the header file. (stream opts on SunOS)*/ /* #undef HAVE_SYS_STROPTS_H */ /* Define if you have the header file. */ #define HAVE_REGEX_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_FS_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_EXT2_FS_H */ /* Define if you have the header file. */ /* #undef HAVE_READLINE_READLINE_H */ /* Define if you have the header file. */ /* #undef HAVE_READLINE_HISTORY_H */ /* Define if you have the readline library. */ /* #undef HAVE_LIBREADLINE */ /* Define if you have the m library (-lm). */ /* #undef HAVE_LIBM */ /* Define if you have the floor function */ /* #undef HAVE_FLOOR */ /* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ /* #undef _XOPEN_EXTENDED_SOURCE */ /* fdset may have component fds_bits or __fds_bits */ #define HAVE_FDS_BITS 1 /* Define if you have the sa_family_t */ #define HAVE_TYPE_SA_FAMILY_T 1 /* define if your struct sigaction has sa_sigaction */ #define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 /* Define if your struct termios has component c_ispeed */ #define HAVE_TERMIOS_ISPEED 1 /* the offset of c_ispeed in struct termios - usable in an speed_t array. Applies only when HAVE_TERMIOS_ISPEED is set */ #define ISPEED_OFFSET 9 /* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ #ifdef ISPEED_OFFSET # define OSPEED_OFFSET (ISPEED_OFFSET+1) #else /* # undef OSPEED_OFFSET */ #endif /* Define if your termios.h likes _SVID3 defined */ /* #undef _SVID3 */ /* Define if you have struct timespec (e.g. for nanosleep) */ #define HAVE_STRUCT_TIMESPEC 1 /* Define if you have struct linger */ #define HAVE_STRUCT_LINGER 1 /* Define if you have struct ip_mreq */ #define HAVE_STRUCT_IP_MREQ 1 /* Define if you have struct ip_mreqn */ /* #undef HAVE_STRUCT_IP_MREQN */ /* Define if you have struct ipv6_mreq */ #define HAVE_STRUCT_IPV6_MREQ 1 /* Define if you have struct ifreq */ #define HAVE_STRUCT_IFREQ 1 /* Define if you have struct ifreq.ifr_index */ /* #undef HAVE_STRUCT_IFREQ_IFR_INDEX */ /* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ /* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ /* Define if your struct sockaddr has sa_len */ #define HAVE_STRUCT_SOCKADDR_SALEN 1 /* there are several implementations of sockaddr_in6 */ #define HAVE_IP6_SOCKADDR 0 /* Define if you have struct iovec */ #define HAVE_STRUCT_IOVEC 1 /* define if your struct msghdr has msg_control */ #define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 /* define if your struct msghdr has msg_controllen */ #define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 /* define if your struct msghdr has msg_flag */ #define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 /* define if you have struct cmsghdr */ #define HAVE_STRUCT_CMSGHDR 1 /* define if you have struct in_pktinfo */ /* #undef HAVE_STRUCT_IN_PKTINFO */ /* define if your struct ip has ip_hl; otherwise assume ip_vhl */ #define HAVE_STRUCT_IP_IP_HL 1 /* Define if you have the setenv function */ #define HAVE_SETENV 1 /* Define if you have the unsetenv function. not on HP-UX */ #define HAVE_UNSETENV 1 /* Define if you have the flock function */ #define HAVE_FLOCK 1 /* Define if you have the openpty function */ #define HAVE_OPENPTY 1 /* Define if you have the grantpt function */ #define HAVE_GRANTPT 1 /* Define if you have the unlockpt function */ #define HAVE_UNLOCKPT 1 /* Define if you have the ptsname function */ #define HAVE_PTSNAME 1 /* Define if you have the /dev/ptmx pseudo terminal multiplexer */ #define HAVE_DEV_PTMX 1 /* Define if you have the /dev/ptc pseudo terminal multiplexer */ /* #undef HAVE_DEV_PTC */ /* Define if you have the long long type */ #define HAVE_TYPE_LONGLONG 1 /* is socklen_t already typedef'd? */ #define HAVE_TYPE_SOCKLEN 1 /* Define if you have the struct stat64 type */ /* #undef HAVE_TYPE_STAT64 */ /* Define if you have the struct off64_t type */ /* #undef HAVE_TYPE_OFF64 */ /* is sighandler_t already typedef'd? */ /* #undef HAVE_TYPE_SIGHANDLER */ /* is uint8_t already defined? */ #define HAVE_TYPE_UINT8 1 /* is uint16_t already defined? */ #define HAVE_TYPE_UINT16 1 /* is uint32_t already defined? */ #define HAVE_TYPE_UINT32 1 /* is uint64_t already defined? */ #define HAVE_TYPE_UINT64 1 /* Define if you have the printf "Z" modifier */ /* #undef HAVE_FORMAT_Z */ /* Define the shift offset of the CRDLY mask */ #define CRDLY_SHIFT -1 /* Define the shift offset of the TABDLY mask */ #define TABDLY_SHIFT -1 /* Define the shift offset of the CSIZE mask */ #define CSIZE_SHIFT 8 /* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ #define HAVE_HOSTS_ALLOW_TABLE 1 #if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE # define HAVE_HOSTS_DENY_TABLE 1 #else /* # undef HAVE_HOSTS_DENY_TABLE */ #endif /* 1..short, 3..int, 5..long; 2,4,6..unsigned */ #define HAVE_BASIC_SIZE_T 4 /* unsigned int */ #define HAVE_BASIC_MODE_T 4 /* unsigned int */ #define HAVE_BASIC_PID_T 3 /* int */ #define HAVE_BASIC_UID_T 4 /* unsigned int */ #define HAVE_BASIC_GID_T 4 /* unsigned int */ #define HAVE_BASIC_TIME_T 5 /* long */ #define HAVE_BASIC_OFF64_T 0 /* unknown, taking default */ #define HAVE_BASIC_SOCKLEN_T 4 /* unsigned int */ #define HAVE_TYPEOF_ST_DEV 4 /* unsigned int */ #define HAVE_TYPEOF_ST_INO 8 /* unsigned long long */ #define HAVE_TYPEOF_ST_NLINK 4 /* unsigned int */ #define HAVE_TYPEOF_ST_SIZE 7 /* long long */ #define HAVE_TYPEOF_ST_BLKSIZE 4 /* unsigned int */ #define HAVE_TYPEOF_ST_BLOCKS 7 /* long long */ /* #undef HAVE_TYPEOF_ST64_DEV */ /* #undef HAVE_TYPEOF_ST64_INO */ /* #undef HAVE_TYPEOF_ST64_NLINK */ /* #undef HAVE_TYPEOF_ST64_SIZE */ /* #undef HAVE_TYPEOF_ST64_BLKSIZE */ /* #undef HAVE_TYPEOF_ST64_BLOCKS */ #define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 /* long */ #define HAVE_TYPEOF_RLIM_MAX 7 /* long long */ /* Define if you have the /proc filesystem */ #define HAVE_PROC_DIR 1 /* Define if you have the /proc/$$/fd directories */ /* #undef HAVE_PROC_DIR_FD */ #define WITH_HELP 1 #define WITH_STDIO 1 #define WITH_FDNUM 1 #define WITH_FILE 1 #define WITH_CREAT 1 #define WITH_GOPEN 1 #define WITH_TERMIOS 1 #define WITH_PIPE 1 #define WITH_UNIX 1 /* #undef WITH_ABSTRACT_UNIXSOCKET */ #define WITH_IP4 1 #define WITH_IP6 1 #define WITH_RAWIP 1 #define WITH_GENERICSOCKET 1 /* #undef WITH_INTERFACE */ #define WITH_TCP 1 #define WITH_UDP 1 /* #undef WITH_SCTP */ #define WITH_LISTEN 1 #define WITH_SOCKS4 1 #define WITH_SOCKS4A 1 #define WITH_PROXY 1 #define WITH_EXEC 1 #define WITH_SYSTEM 1 /* #undef WITH_READLINE */ /* #undef WITH_TUN */ #define WITH_PTY 1 #define WITH_EXT2 1 #define WITH_OPENSSL 1 #define WITH_STREAMS 1 /* #undef WITH_FIPS */ /* #undef OPENSSL_FIPS */ #define WITH_LIBWRAP 1 #define HAVE_TCPD_H 1 #define HAVE_LIBWRAP 1 #define WITH_SYCLS 1 #define WITH_FILAN 1 #define WITH_RETRY 1 #define WITH_MSGLEVEL 0 #endif /* !defined(__config_h_included) */ socat-1.7.3.1/Config/config.SunOS-5-10.h0000644000201000020100000003353711453022151016776 0ustar gerhardgerhard/* config.h. Generated from config.h.in by configure. */ /* source: config.h.in */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __config_h_included #define __config_h_included 1 /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to `int' if doesn't define. */ /* #undef gid_t */ /* Define if your struct stat has st_blksize. */ #define HAVE_ST_BLKSIZE 1 /* Define if your struct stat has st_blocks. */ #define HAVE_ST_BLOCKS 1 /* Define if your struct stat has st_rdev. */ #define HAVE_ST_RDEV 1 /* Define if you have the strftime function. */ #define HAVE_STRFTIME 1 /* Define if you have that is POSIX.1 compatible. */ #define HAVE_SYS_WAIT_H 1 /* Define to `int' if doesn't define. */ /* #undef mode_t */ /* Define to `long' if doesn't define. */ /* #undef off_t */ /* Define to `int' if doesn't define. */ /* #undef pid_t */ /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define to `unsigned' if doesn't define. */ /* #undef size_t */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to `int' if doesn't define. */ /* #undef uid_t */ /* Define if you have the putenv function. */ #define HAVE_PUTENV 1 /* Define if you have the select function. */ #define HAVE_SELECT 1 /* Define if you have the poll function. */ #define HAVE_POLL 1 /* Define if you have the socket function. */ #define HAVE_SOCKET 1 /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define if you have the strerror function. */ #define HAVE_STRERROR 1 /* Define if you have the strstr function. */ #define HAVE_STRSTR 1 /* Define if you have the strtod function. */ #define HAVE_STRTOD 1 /* Define if you have the strtol function. */ #define HAVE_STRTOL 1 /* Define if you have the strtoul function. */ #define HAVE_STRTOUL 1 /* Define if you have the uname function. */ #define HAVE_UNAME 1 /* Define if you have the getpgid function. */ #define HAVE_GETPGID 1 /* Define if you have the getsid function. */ #define HAVE_GETSID 1 /* Define if you have the nanosleep function. */ #define HAVE_NANOSLEEP 1 /* Define if you have the getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define if you have the getipnodebyname function. */ #define HAVE_GETIPNODEBYNAME 1 /* Define if you have the setgroups function. */ #define HAVE_SETGROUPS 1 /* Define if you have the inet_aton function. */ #define HAVE_INET_ATON 1 /* Define if you have the memrchr function. */ /* #undef HAVE_MEMRCHR */ /* Define if you have the if_indextoname function. */ #define HAVE_IF_INDEXTONAME 1 /* Define if you have the sigaction function */ #define HAVE_SIGACTION 1 /* Define if you have the stat64 function */ #define HAVE_STAT64 1 /* Define if you have the fstat64 function */ #define HAVE_FSTAT64 1 /* Define if you have the lstat64 function */ #define HAVE_LSTAT64 1 /* Define if you have the lseek64 function */ #define HAVE_LSEEK64 1 /* Define if you have the truncate64 function */ #define HAVE_TRUNCATE64 1 /* Define if you have the ftruncate64 function */ #define HAVE_FTRUNCATE64 1 /* Define if you have the strtoll function */ #define HAVE_STRTOLL 1 /* Define if you have the hstrerror function */ #define HAVE_HSTRERROR 1 /* Define if you have the inet_ntop function */ #define HAVE_INET_NTOP 1 /* Define if you have the hstrerror prototype */ #define HAVE_PROTOTYPE_HSTRERROR 1 /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define if you have the header file. */ #define HAVE_SYSLOG_H 1 /* Define if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define if you have the header file. */ #define HAVE_PWD_H 1 /* Define if you have the header file. */ #define HAVE_GRP_H 1 /* Define if you have the header file. */ #define HAVE_STDINT_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define if you have the header file. */ #define HAVE_SYS_POLL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define if you have the header file. */ #define HAVE_NETDB_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UN_H 1 /* Define if you have the header file. */ /* #undef HAVE_PTY_H */ /* Define if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IN_SYSTM_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP6_H 1 /* Define if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define if you have the header file. */ #define HAVE_RESOLV_H 1 /* Define if you have the header file. */ #define HAVE_TERMIOS_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_DL_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_TYPES_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_ERRQUEUE_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_IF_TUN_H */ /* Define if you have the header file. */ /* #undef HAVE_NETPACKET_PACKET_H */ /* Define if you have the header file. */ /* #undef HAVE_NETINET_IF_ETHER_H */ /* Define if you have the header file. */ #define HAVE_SYS_UTSNAME_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_SELECT_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_FILE_H 1 /* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ /* #undef HAVE_UTIL_H */ /* Define if you have the header file. (FreeBSD: openpty()) */ /* #undef HAVE_LIBUTIL_H */ /* Define if you have the header file. (stream opts on SunOS)*/ #define HAVE_SYS_STROPTS_H 1 /* Define if you have the header file. */ #define HAVE_REGEX_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_FS_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_EXT2_FS_H */ /* Define if you have the header file. */ #define HAVE_READLINE_READLINE_H 1 /* Define if you have the header file. */ #define HAVE_READLINE_HISTORY_H 1 /* Define if you have the readline library. */ #define HAVE_LIBREADLINE 1 /* Define if you have the m library (-lm). */ /* #undef HAVE_LIBM */ /* Define if you have the floor function */ /* #undef HAVE_FLOOR */ /* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ /* #undef _XOPEN_EXTENDED_SOURCE */ /* fdset may have component fds_bits or __fds_bits */ #define HAVE_FDS_BITS 1 /* Define if you have the sa_family_t */ #define HAVE_TYPE_SA_FAMILY_T 1 /* define if your struct sigaction has sa_sigaction */ #define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 /* Define if your struct termios has component c_ispeed */ /* #undef HAVE_TERMIOS_ISPEED */ /* the offset of c_ispeed in struct termios - usable in an speed_t array. Applies only when HAVE_TERMIOS_ISPEED is set */ /* #undef ISPEED_OFFSET */ /* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ #ifdef ISPEED_OFFSET # define OSPEED_OFFSET (ISPEED_OFFSET+1) #else /* # undef OSPEED_OFFSET */ #endif /* Define if your termios.h likes _SVID3 defined */ /* #undef _SVID3 */ /* Define if you have struct timespec (e.g. for nanosleep) */ #define HAVE_STRUCT_TIMESPEC 1 /* Define if you have struct linger */ #define HAVE_STRUCT_LINGER 1 /* Define if you have struct ip_mreq */ #define HAVE_STRUCT_IP_MREQ 1 /* Define if you have struct ip_mreqn */ /* #undef HAVE_STRUCT_IP_MREQN */ /* Define if you have struct ipv6_mreq */ #define HAVE_STRUCT_IPV6_MREQ 1 /* Define if you have struct ifreq */ #define HAVE_STRUCT_IFREQ 1 /* Define if you have struct ifreq.ifr_index */ #define HAVE_STRUCT_IFREQ_IFR_INDEX 1 /* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ /* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ /* Define if your struct sockaddr has sa_len */ /* #undef HAVE_STRUCT_SOCKADDR_SALEN */ /* there are several implementations of sockaddr_in6 */ #define HAVE_IP6_SOCKADDR 0 /* Define if you have struct iovec */ #define HAVE_STRUCT_IOVEC 1 /* define if your struct msghdr has msg_control */ /* #undef HAVE_STRUCT_MSGHDR_MSGCONTROL */ /* define if your struct msghdr has msg_controllen */ /* #undef HAVE_STRUCT_MSGHDR_MSGCONTROLLEN */ /* define if your struct msghdr has msg_flag */ /* #undef HAVE_STRUCT_MSGHDR_MSGFLAGS */ /* define if you have struct cmsghdr */ #define HAVE_STRUCT_CMSGHDR 1 /* define if you have struct in_pktinfo */ /* #undef HAVE_STRUCT_IN_PKTINFO */ /* define if your struct ip has ip_hl; otherwise assume ip_vhl */ #define HAVE_STRUCT_IP_IP_HL 1 /* Define if you have the setenv function */ #define HAVE_SETENV 1 /* Define if you have the unsetenv function. not on HP-UX */ #define HAVE_UNSETENV 1 /* Define if you have the flock function */ /* #undef HAVE_FLOCK */ /* Define if you have the openpty function */ /* #undef HAVE_OPENPTY */ /* Define if you have the grantpt function */ #define HAVE_GRANTPT 1 /* Define if you have the unlockpt function */ #define HAVE_UNLOCKPT 1 /* Define if you have the ptsname function */ #define HAVE_PTSNAME 1 /* Define if you have the /dev/ptmx pseudo terminal multiplexer */ #define HAVE_DEV_PTMX 1 /* Define if you have the /dev/ptc pseudo terminal multiplexer */ /* #undef HAVE_DEV_PTC */ /* Define if you have the long long type */ #define HAVE_TYPE_LONGLONG 1 /* is socklen_t already typedef'd? */ #define HAVE_TYPE_SOCKLEN 1 /* Define if you have the struct stat64 type */ #define HAVE_TYPE_STAT64 1 /* Define if you have the struct off64_t type */ #define HAVE_TYPE_OFF64 1 /* is sighandler_t already typedef'd? */ /* #undef HAVE_TYPE_SIGHANDLER */ /* is uint8_t already defined? */ #define HAVE_TYPE_UINT8 1 /* is uint16_t already defined? */ #define HAVE_TYPE_UINT16 1 /* is uint32_t already defined? */ #define HAVE_TYPE_UINT32 1 /* is uint64_t already defined? */ #define HAVE_TYPE_UINT64 1 /* Define if you have the printf "Z" modifier */ /* #undef HAVE_FORMAT_Z */ /* Define the shift offset of the CRDLY mask */ #define CRDLY_SHIFT 9 /* Define the shift offset of the TABDLY mask */ #define TABDLY_SHIFT 11 /* Define the shift offset of the CSIZE mask */ #define CSIZE_SHIFT 4 /* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ #define HAVE_HOSTS_ALLOW_TABLE 1 #if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE # define HAVE_HOSTS_DENY_TABLE 1 #else /* # undef HAVE_HOSTS_DENY_TABLE */ #endif /* 1..short, 3..int, 5..long; 2,4,6..unsigned */ #define HAVE_BASIC_SIZE_T 4 /* unsigned int */ #define HAVE_BASIC_MODE_T 6 /* unsigned long */ #define HAVE_BASIC_PID_T 5 /* long */ #define HAVE_BASIC_UID_T 5 /* long */ #define HAVE_BASIC_GID_T 5 /* long */ #define HAVE_BASIC_TIME_T 5 /* long */ #define HAVE_BASIC_OFF64_T 7 /* long long */ #define HAVE_BASIC_SOCKLEN_T 4 /* unsigned int */ #define HAVE_TYPEOF_ST_DEV 6 /* unsigned long */ #define HAVE_TYPEOF_ST_INO 6 /* unsigned long */ #define HAVE_TYPEOF_ST_NLINK 6 /* unsigned long */ #define HAVE_TYPEOF_ST_SIZE 5 /* long */ #define HAVE_TYPEOF_ST_BLKSIZE 5 /* long */ #define HAVE_TYPEOF_ST_BLOCKS 5 /* long */ #define HAVE_TYPEOF_ST64_DEV 6 /* unsigned long */ #define HAVE_TYPEOF_ST64_INO 8 /* unsigned long long */ #define HAVE_TYPEOF_ST64_NLINK 6 /* unsigned long */ #define HAVE_TYPEOF_ST64_SIZE 7 /* long long */ #define HAVE_TYPEOF_ST64_BLKSIZE 5 /* long */ #define HAVE_TYPEOF_ST64_BLOCKS 7 /* long long */ #define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 /* long */ #define HAVE_TYPEOF_RLIM_MAX 6 /* unsigned long */ /* Define if you have the /proc filesystem */ #define HAVE_PROC_DIR 1 /* Define if you have the /proc/$$/fd directories */ #define HAVE_PROC_DIR_FD 1 #define WITH_HELP 1 #define WITH_STDIO 1 #define WITH_FDNUM 1 #define WITH_FILE 1 #define WITH_CREAT 1 #define WITH_GOPEN 1 #define WITH_TERMIOS 1 #define WITH_PIPE 1 #define WITH_UNIX 1 /* #undef WITH_ABSTRACT_UNIXSOCKET */ #define WITH_IP4 1 #define WITH_IP6 1 #define WITH_RAWIP 1 #define WITH_GENERICSOCKET 1 /* #undef WITH_INTERFACE */ #define WITH_TCP 1 #define WITH_UDP 1 #define WITH_SCTP 1 #define WITH_LISTEN 1 #define WITH_SOCKS4 1 #define WITH_SOCKS4A 1 #define WITH_PROXY 1 #define WITH_EXEC 1 #define WITH_SYSTEM 1 #define WITH_READLINE 1 /* #undef WITH_TUN */ #define WITH_PTY 1 #define WITH_EXT2 1 #define WITH_OPENSSL 1 #define WITH_STREAMS 1 /* #undef WITH_FIPS */ /* #undef OPENSSL_FIPS */ #define WITH_LIBWRAP 1 #define HAVE_TCPD_H 1 #define HAVE_LIBWRAP 1 #define WITH_SYCLS 1 #define WITH_FILAN 1 #define WITH_RETRY 1 #define WITH_MSGLEVEL 0 #endif /* !defined(__config_h_included) */ socat-1.7.3.1/Config/Makefile.FreeBSD-6-10000644000201000020100000001413211453022151017132 0ustar gerhardgerhard# source: Makefile.in # Copyright Gerhard Rieger 2001-2008 # Published under the GNU General Public License V.2, see file COPYING # note: @...@ forms are filled in by configure script SHELL = /bin/sh AR = ar RANLIB = ranlib .SUFFIXES: .c .o prefix = /usr/local exec_prefix = ${prefix} BINDEST = ${exec_prefix}/bin datarootdir = ${prefix}/share MANDEST = ${datarootdir}/man srcdir = . CC = gcc CCOPTS = $(CCOPT) -Wall -Wno-parentheses SYSDEFS = -D_LONGLONG CPPFLAGS = -I. #0 INCLS = -I. @V_INCL@ DEFS = -DHAVE_CONFIG_H LIBS = -lwrap -lutil -lreadline -lssl LDFLAGS = INSTALL = /usr/bin/install -c #OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) #0 CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(INCLS) CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(CPPFLAGS) CLIBS = $(LIBS) #CLIBS = $(LIBS) -lm -lefence XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xiosignal.c xiosigchld.c xioread.c xiowrite.c \ xiolayer.c xioshutdown.c xioclose.c xioexit.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ xio-sctp.c xio-rawip.c \ xio-socks.c xio-proxy.c xio-udp.c \ xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ xio-pty.c xio-openssl.c xio-streams.c\ xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c XIOOBJS = $(XIOSRCS:.c=.o) UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c UTLOBJS = $(UTLSRCS:.c=.o) CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c OFILES = $(CFILES:.c=.o) PROGS = socat procan filan HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ xio-system.h xio-termios.h xio-readline.h \ xio-pty.h xio-openssl.h xio-streams.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html SHFILES = daemon.sh mail.sh ftp.sh readline.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ proxy.sh socks4a-echo.sh testcert.conf OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h all: progs doc scmclean: gitclean gitclean: distclean docclean rm -f Makefile.bak configure doc: doc/socat.1 doc/socat.html docclean: rm -f doc/socat.1 doc/socat.html doc/socat.1: doc/socat.yo yodl2man -o $@ $+ doc/socat.html: doc/socat.yo cd doc; yodl2html -o socat.html socat.yo; cd .. progs: $(PROGS) depend: $(CFILES) $(HFILES) makedepend $(SYSDEFS) $(CFILES) socat: socat.o libxio.a $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o procan: $(PROCAN_OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) libxio.a: $(XIOOBJS) $(UTLOBJS) $(AR) r $@ $(XIOOBJS) $(UTLOBJS) $(RANLIB) $@ doc: doc/xio.help # strip: progs strip $(PROGS) install: progs $(srcdir)/doc/socat.1 mkdir -p $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) mkdir -p $(DESTDIR)$(MANDEST)/man1 $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ uninstall: rm -f $(DESTDIR)$(BINDEST)/socat rm -f $(DESTDIR)$(BINDEST)/procan rm -f $(DESTDIR)$(BINDEST)/filan rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 # make a GNU-zipped tar ball of the source files dist: socat.tar.gz socat.tar.bz2 socat.tar.gz: socat.tar gzip -9 socat.tar.gz socat.tar.bz2: socat.tar bzip2 -9 socat.tar.bz2 VERSION = `sed 's/"//g' VERSION` TARDIR = socat-$(VERSION) socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi tar cf - $+ |(cd $(TARDIR); tar xf -) tar cvf socat.tar $(TARDIR) rm -f $(TARDIR)/COPYING # write protected rm -r $(TARDIR) clean: rm -f *.o libxio.a socat procan filan \ socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ socat.out compile.log test.log # remove all files that are generated from the original socat distribution # note that Makefile is also removed, so you have to start with ./configure # again distclean: clean rm -f config.status config.cache config.log config.h Makefile rm -rf autom4te.cache info: socat uname -a >socat.out ./socat -V >>socat.out ./socat -hh >>socat.out # perform some tests on socat test: progs ./test.sh cert: # prepare critical files with correct permissions to avoid race cond >cert.key >cert.pem chmod 600 cert.key cert.pem # generate a private key openssl genrsa -out cert.key 1024 # generate a self signed cert openssl req -new -key cert.key -x509 -days 3653 -out cert.crt # ...enter fields # generate the pem file cat cert.key cert.crt >cert.pem #echo use cert.pem on requestors side, i.e. with option cert=cert.pem #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt socat-1.7.3.1/Config/Makefile.Cygwin-1-5-250000644000201000020100000001416411453022151017410 0ustar gerhardgerhard# source: Makefile.in # Copyright Gerhard Rieger 2001-2008 # Published under the GNU General Public License V.2, see file COPYING # note: @...@ forms are filled in by configure script SHELL = /bin/sh AR = ar RANLIB = ranlib .SUFFIXES: .c .o prefix = /usr/local exec_prefix = ${prefix} BINDEST = ${exec_prefix}/bin datarootdir = ${prefix}/share MANDEST = ${datarootdir}/man srcdir = . CC = gcc CCOPTS = $(CCOPT) -Wall -Wno-parentheses SYSDEFS = CPPFLAGS = -I. #0 INCLS = -I. @V_INCL@ DEFS = -DHAVE_CONFIG_H LIBS = -lwrap -lutil -lreadline -lssl -lcrypto LDFLAGS = INSTALL = /usr/bin/install -c #OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) #0 CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(INCLS) CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(CPPFLAGS) CLIBS = $(LIBS) #CLIBS = $(LIBS) -lm -lefence XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xiosignal.c xiosigchld.c xioread.c xiowrite.c \ xiolayer.c xioshutdown.c xioclose.c xioexit.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ xio-sctp.c xio-rawip.c \ xio-socks.c xio-proxy.c xio-udp.c \ xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ xio-pty.c xio-openssl.c xio-streams.c\ xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c XIOOBJS = $(XIOSRCS:.c=.o) UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c UTLOBJS = $(UTLSRCS:.c=.o) CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c OFILES = $(CFILES:.c=.o) PROGS = socat procan filan HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ xio-system.h xio-termios.h xio-readline.h \ xio-pty.h xio-openssl.h xio-streams.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html doc/socat-genericsocket.html SHFILES = daemon.sh mail.sh ftp.sh readline.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ proxy.sh socks4a-echo.sh testcert.conf OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h all: progs doc scmclean: gitclean gitclean: distclean docclean rm -f Makefile.bak configure doc: doc/socat.1 doc/socat.html docclean: rm -f doc/socat.1 doc/socat.html doc/socat.1: doc/socat.yo yodl2man -o $@ $+ doc/socat.html: doc/socat.yo cd doc; yodl2html -o socat.html socat.yo; cd .. progs: $(PROGS) depend: $(CFILES) $(HFILES) makedepend $(SYSDEFS) $(CFILES) socat: socat.o libxio.a $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o procan: $(PROCAN_OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) libxio.a: $(XIOOBJS) $(UTLOBJS) $(AR) r $@ $(XIOOBJS) $(UTLOBJS) $(RANLIB) $@ doc: doc/xio.help # strip: progs strip $(PROGS) install: progs $(srcdir)/doc/socat.1 mkdir -p $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) mkdir -p $(DESTDIR)$(MANDEST)/man1 $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ uninstall: rm -f $(DESTDIR)$(BINDEST)/socat rm -f $(DESTDIR)$(BINDEST)/procan rm -f $(DESTDIR)$(BINDEST)/filan rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 # make a GNU-zipped tar ball of the source files dist: socat.tar.gz socat.tar.bz2 socat.tar.gz: socat.tar gzip -9 socat.tar.gz socat.tar.bz2: socat.tar bzip2 -9 socat.tar.bz2 VERSION = `sed 's/"//g' VERSION` TARDIR = socat-$(VERSION) socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi tar cf - $+ |(cd $(TARDIR); tar xf -) tar cvf socat.tar $(TARDIR) rm -f $(TARDIR)/COPYING # write protected rm -r $(TARDIR) clean: rm -f *.o libxio.a socat procan filan \ socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ socat.out compile.log test.log # remove all files that are generated from the original socat distribution # note that Makefile is also removed, so you have to start with ./configure # again distclean: clean rm -f config.status config.cache config.log config.h Makefile rm -rf autom4te.cache info: socat uname -a >socat.out ./socat -V >>socat.out ./socat -hh >>socat.out # perform some tests on socat test: progs ./test.sh cert: # prepare critical files with correct permissions to avoid race cond >cert.key >cert.pem chmod 600 cert.key cert.pem # generate a private key openssl genrsa -out cert.key 1024 # generate a self signed cert openssl req -new -key cert.key -x509 -days 3653 -out cert.crt # ...enter fields # generate the pem file cat cert.key cert.crt >cert.pem #echo use cert.pem on requestors side, i.e. with option cert=cert.pem #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt socat-1.7.3.1/Config/config.FreeBSD-6-1.h0000644000201000020100000003346611453022151017123 0ustar gerhardgerhard/* config.h. Generated from config.h.in by configure. */ /* source: config.h.in */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __config_h_included #define __config_h_included 1 /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to `int' if doesn't define. */ /* #undef gid_t */ /* Define if your struct stat has st_blksize. */ #define HAVE_ST_BLKSIZE 1 /* Define if your struct stat has st_blocks. */ #define HAVE_ST_BLOCKS 1 /* Define if your struct stat has st_rdev. */ #define HAVE_ST_RDEV 1 /* Define if you have the strftime function. */ #define HAVE_STRFTIME 1 /* Define if you have that is POSIX.1 compatible. */ #define HAVE_SYS_WAIT_H 1 /* Define to `int' if doesn't define. */ /* #undef mode_t */ /* Define to `long' if doesn't define. */ /* #undef off_t */ /* Define to `int' if doesn't define. */ /* #undef pid_t */ /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define to `unsigned' if doesn't define. */ /* #undef size_t */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to `int' if doesn't define. */ /* #undef uid_t */ /* Define if you have the putenv function. */ #define HAVE_PUTENV 1 /* Define if you have the select function. */ #define HAVE_SELECT 1 /* Define if you have the poll function. */ #define HAVE_POLL 1 /* Define if you have the socket function. */ #define HAVE_SOCKET 1 /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define if you have the strerror function. */ #define HAVE_STRERROR 1 /* Define if you have the strstr function. */ #define HAVE_STRSTR 1 /* Define if you have the strtod function. */ #define HAVE_STRTOD 1 /* Define if you have the strtol function. */ #define HAVE_STRTOL 1 /* Define if you have the strtoul function. */ #define HAVE_STRTOUL 1 /* Define if you have the uname function. */ #define HAVE_UNAME 1 /* Define if you have the getpgid function. */ #define HAVE_GETPGID 1 /* Define if you have the getsid function. */ #define HAVE_GETSID 1 /* Define if you have the nanosleep function. */ #define HAVE_NANOSLEEP 1 /* Define if you have the getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define if you have the getipnodebyname function. */ #define HAVE_GETIPNODEBYNAME 1 /* Define if you have the setgroups function. */ #define HAVE_SETGROUPS 1 /* Define if you have the inet_aton function. */ #define HAVE_INET_ATON 1 /* Define if you have the memrchr function. */ /* #undef HAVE_MEMRCHR */ /* Define if you have the if_indextoname function. */ #define HAVE_IF_INDEXTONAME 1 /* Define if you have the sigaction function */ #define HAVE_SIGACTION 1 /* Define if you have the stat64 function */ /* #undef HAVE_STAT64 */ /* Define if you have the fstat64 function */ /* #undef HAVE_FSTAT64 */ /* Define if you have the lstat64 function */ /* #undef HAVE_LSTAT64 */ /* Define if you have the lseek64 function */ /* #undef HAVE_LSEEK64 */ /* Define if you have the truncate64 function */ /* #undef HAVE_TRUNCATE64 */ /* Define if you have the ftruncate64 function */ /* #undef HAVE_FTRUNCATE64 */ /* Define if you have the strtoll function */ #define HAVE_STRTOLL 1 /* Define if you have the hstrerror function */ #define HAVE_HSTRERROR 1 /* Define if you have the inet_ntop function */ #define HAVE_INET_NTOP 1 /* Define if you have the hstrerror prototype */ #define HAVE_PROTOTYPE_HSTRERROR 1 /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define if you have the header file. */ #define HAVE_SYSLOG_H 1 /* Define if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define if you have the header file. */ #define HAVE_PWD_H 1 /* Define if you have the header file. */ #define HAVE_GRP_H 1 /* Define if you have the header file. */ #define HAVE_STDINT_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define if you have the header file. */ #define HAVE_SYS_POLL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define if you have the header file. */ #define HAVE_NETDB_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UN_H 1 /* Define if you have the header file. */ /* #undef HAVE_PTY_H */ /* Define if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IN_SYSTM_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP6_H 1 /* Define if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define if you have the header file. */ #define HAVE_RESOLV_H 1 /* Define if you have the header file. */ #define HAVE_TERMIOS_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_DL_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_TYPES_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_ERRQUEUE_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_IF_TUN_H */ /* Define if you have the header file. */ /* #undef HAVE_NETPACKET_PACKET_H */ /* Define if you have the header file. */ /* #undef HAVE_NETINET_IF_ETHER_H */ /* Define if you have the header file. */ #define HAVE_SYS_UTSNAME_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_SELECT_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_FILE_H 1 /* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ /* #undef HAVE_UTIL_H */ /* Define if you have the header file. (FreeBSD: openpty()) */ #define HAVE_LIBUTIL_H 1 /* Define if you have the header file. (stream opts on SunOS)*/ /* #undef HAVE_SYS_STROPTS_H */ /* Define if you have the header file. */ #define HAVE_REGEX_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_FS_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_EXT2_FS_H */ /* Define if you have the header file. */ #define HAVE_READLINE_READLINE_H 1 /* Define if you have the header file. */ #define HAVE_READLINE_HISTORY_H 1 /* Define if you have the readline library. */ #define HAVE_LIBREADLINE 1 /* Define if you have the m library (-lm). */ /* #undef HAVE_LIBM */ /* Define if you have the floor function */ /* #undef HAVE_FLOOR */ /* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ /* #undef _XOPEN_EXTENDED_SOURCE */ /* fdset may have component fds_bits or __fds_bits */ #define HAVE_FDS_BITS 1 /* Define if you have the sa_family_t */ #define HAVE_TYPE_SA_FAMILY_T 1 /* define if your struct sigaction has sa_sigaction */ #define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 /* Define if your struct termios has component c_ispeed */ #define HAVE_TERMIOS_ISPEED 1 /* the offset of c_ispeed in struct termios - usable in an speed_t array. Applies only when HAVE_TERMIOS_ISPEED is set */ #define ISPEED_OFFSET 9 /* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ #ifdef ISPEED_OFFSET # define OSPEED_OFFSET (ISPEED_OFFSET+1) #else /* # undef OSPEED_OFFSET */ #endif /* Define if your termios.h likes _SVID3 defined */ /* #undef _SVID3 */ /* Define if you have struct timespec (e.g. for nanosleep) */ #define HAVE_STRUCT_TIMESPEC 1 /* Define if you have struct linger */ #define HAVE_STRUCT_LINGER 1 /* Define if you have struct ip_mreq */ #define HAVE_STRUCT_IP_MREQ 1 /* Define if you have struct ip_mreqn */ /* #undef HAVE_STRUCT_IP_MREQN */ /* Define if you have struct ipv6_mreq */ #define HAVE_STRUCT_IPV6_MREQ 1 /* Define if you have struct ifreq */ #define HAVE_STRUCT_IFREQ 1 /* Define if you have struct ifreq.ifr_index */ #define HAVE_STRUCT_IFREQ_IFR_INDEX 1 /* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ /* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ /* Define if your struct sockaddr has sa_len */ #define HAVE_STRUCT_SOCKADDR_SALEN 1 /* there are several implementations of sockaddr_in6 */ #define HAVE_IP6_SOCKADDR 0 /* Define if you have struct iovec */ #define HAVE_STRUCT_IOVEC 1 /* define if your struct msghdr has msg_control */ #define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 /* define if your struct msghdr has msg_controllen */ #define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 /* define if your struct msghdr has msg_flag */ #define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 /* define if you have struct cmsghdr */ #define HAVE_STRUCT_CMSGHDR 1 /* define if you have struct in_pktinfo */ /* #undef HAVE_STRUCT_IN_PKTINFO */ /* define if your struct ip has ip_hl; otherwise assume ip_vhl */ #define HAVE_STRUCT_IP_IP_HL 1 /* Define if you have the setenv function */ #define HAVE_SETENV 1 /* Define if you have the unsetenv function. not on HP-UX */ #define HAVE_UNSETENV 1 /* Define if you have the flock function */ #define HAVE_FLOCK 1 /* Define if you have the openpty function */ #define HAVE_OPENPTY 1 /* Define if you have the grantpt function */ #define HAVE_GRANTPT 1 /* Define if you have the unlockpt function */ #define HAVE_UNLOCKPT 1 /* Define if you have the ptsname function */ #define HAVE_PTSNAME 1 /* Define if you have the /dev/ptmx pseudo terminal multiplexer */ /* #undef HAVE_DEV_PTMX */ /* Define if you have the /dev/ptc pseudo terminal multiplexer */ /* #undef HAVE_DEV_PTC */ /* Define if you have the long long type */ #define HAVE_TYPE_LONGLONG 1 /* is socklen_t already typedef'd? */ #define HAVE_TYPE_SOCKLEN 1 /* Define if you have the struct stat64 type */ /* #undef HAVE_TYPE_STAT64 */ /* Define if you have the struct off64_t type */ /* #undef HAVE_TYPE_OFF64 */ /* is sighandler_t already typedef'd? */ /* #undef HAVE_TYPE_SIGHANDLER */ /* is uint8_t already defined? */ #define HAVE_TYPE_UINT8 1 /* is uint16_t already defined? */ #define HAVE_TYPE_UINT16 1 /* is uint32_t already defined? */ #define HAVE_TYPE_UINT32 1 /* is uint64_t already defined? */ #define HAVE_TYPE_UINT64 1 /* Define if you have the printf "Z" modifier */ /* #undef HAVE_FORMAT_Z */ /* Define the shift offset of the CRDLY mask */ #define CRDLY_SHIFT -1 /* Define the shift offset of the TABDLY mask */ #define TABDLY_SHIFT -1 /* Define the shift offset of the CSIZE mask */ #define CSIZE_SHIFT 8 /* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ #define HAVE_HOSTS_ALLOW_TABLE 1 #if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE # define HAVE_HOSTS_DENY_TABLE 1 #else /* # undef HAVE_HOSTS_DENY_TABLE */ #endif /* 1..short, 3..int, 5..long; 2,4,6..unsigned */ #define HAVE_BASIC_SIZE_T 4 /* unsigned int */ #define HAVE_BASIC_MODE_T 2 /* unsigned short */ #define HAVE_BASIC_PID_T 3 /* int */ #define HAVE_BASIC_UID_T 4 /* unsigned int */ #define HAVE_BASIC_GID_T 4 /* unsigned int */ #define HAVE_BASIC_TIME_T 3 /* int */ #define HAVE_BASIC_OFF64_T 0 /* unknown, taking default */ #define HAVE_BASIC_SOCKLEN_T 4 /* unsigned int */ #define HAVE_TYPEOF_ST_DEV 4 /* unsigned int */ #define HAVE_TYPEOF_ST_INO 4 /* unsigned int */ #define HAVE_TYPEOF_ST_NLINK 2 /* unsigned short */ #define HAVE_TYPEOF_ST_SIZE 7 /* long long */ #define HAVE_TYPEOF_ST_BLKSIZE 4 /* unsigned int */ #define HAVE_TYPEOF_ST_BLOCKS 7 /* long long */ /* #undef HAVE_TYPEOF_ST64_DEV */ /* #undef HAVE_TYPEOF_ST64_INO */ /* #undef HAVE_TYPEOF_ST64_NLINK */ /* #undef HAVE_TYPEOF_ST64_SIZE */ /* #undef HAVE_TYPEOF_ST64_BLKSIZE */ /* #undef HAVE_TYPEOF_ST64_BLOCKS */ #define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 /* long */ #define HAVE_TYPEOF_RLIM_MAX 7 /* long long */ /* Define if you have the /proc filesystem */ #define HAVE_PROC_DIR 1 /* Define if you have the /proc/$$/fd directories */ /* #undef HAVE_PROC_DIR_FD */ #define WITH_HELP 1 #define WITH_STDIO 1 #define WITH_FDNUM 1 #define WITH_FILE 1 #define WITH_CREAT 1 #define WITH_GOPEN 1 #define WITH_TERMIOS 1 #define WITH_PIPE 1 #define WITH_UNIX 1 /* #undef WITH_ABSTRACT_UNIXSOCKET */ #define WITH_IP4 1 #define WITH_IP6 1 #define WITH_RAWIP 1 #define WITH_GENERICSOCKET 1 /* #undef WITH_INTERFACE */ #define WITH_TCP 1 #define WITH_UDP 1 #define WITH_SCTP 1 #define WITH_LISTEN 1 #define WITH_SOCKS4 1 #define WITH_SOCKS4A 1 #define WITH_PROXY 1 #define WITH_EXEC 1 #define WITH_SYSTEM 1 #define WITH_READLINE 1 /* #undef WITH_TUN */ #define WITH_PTY 1 #define WITH_EXT2 1 #define WITH_OPENSSL 1 #define WITH_STREAMS 1 /* #undef WITH_FIPS */ /* #undef OPENSSL_FIPS */ #define WITH_LIBWRAP 1 #define HAVE_TCPD_H 1 #define HAVE_LIBWRAP 1 #define WITH_SYCLS 1 #define WITH_FILAN 1 #define WITH_RETRY 1 #define WITH_MSGLEVEL 0 #endif /* !defined(__config_h_included) */ socat-1.7.3.1/Config/config.OpenBSD-4-3.h0000644000201000020100000003351011453022151017131 0ustar gerhardgerhard/* config.h. Generated from config.h.in by configure. */ /* source: config.h.in */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __config_h_included #define __config_h_included 1 /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to `int' if doesn't define. */ /* #undef gid_t */ /* Define if your struct stat has st_blksize. */ #define HAVE_ST_BLKSIZE 1 /* Define if your struct stat has st_blocks. */ #define HAVE_ST_BLOCKS 1 /* Define if your struct stat has st_rdev. */ #define HAVE_ST_RDEV 1 /* Define if you have the strftime function. */ #define HAVE_STRFTIME 1 /* Define if you have that is POSIX.1 compatible. */ #define HAVE_SYS_WAIT_H 1 /* Define to `int' if doesn't define. */ /* #undef mode_t */ /* Define to `long' if doesn't define. */ /* #undef off_t */ /* Define to `int' if doesn't define. */ /* #undef pid_t */ /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define to `unsigned' if doesn't define. */ /* #undef size_t */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to `int' if doesn't define. */ /* #undef uid_t */ /* Define if you have the putenv function. */ #define HAVE_PUTENV 1 /* Define if you have the select function. */ #define HAVE_SELECT 1 /* Define if you have the poll function. */ #define HAVE_POLL 1 /* Define if you have the socket function. */ #define HAVE_SOCKET 1 /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define if you have the strerror function. */ #define HAVE_STRERROR 1 /* Define if you have the strstr function. */ #define HAVE_STRSTR 1 /* Define if you have the strtod function. */ #define HAVE_STRTOD 1 /* Define if you have the strtol function. */ #define HAVE_STRTOL 1 /* Define if you have the strtoul function. */ #define HAVE_STRTOUL 1 /* Define if you have the uname function. */ #define HAVE_UNAME 1 /* Define if you have the getpgid function. */ #define HAVE_GETPGID 1 /* Define if you have the getsid function. */ #define HAVE_GETSID 1 /* Define if you have the nanosleep function. */ #define HAVE_NANOSLEEP 1 /* Define if you have the getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define if you have the getipnodebyname function. */ /* #undef HAVE_GETIPNODEBYNAME */ /* Define if you have the setgroups function. */ #define HAVE_SETGROUPS 1 /* Define if you have the inet_aton function. */ #define HAVE_INET_ATON 1 /* Define if you have the memrchr function. */ #define HAVE_MEMRCHR 1 /* Define if you have the if_indextoname function. */ #define HAVE_IF_INDEXTONAME 1 /* Define if you have the sigaction function */ #define HAVE_SIGACTION 1 /* Define if you have the stat64 function */ /* #undef HAVE_STAT64 */ /* Define if you have the fstat64 function */ /* #undef HAVE_FSTAT64 */ /* Define if you have the lstat64 function */ /* #undef HAVE_LSTAT64 */ /* Define if you have the lseek64 function */ /* #undef HAVE_LSEEK64 */ /* Define if you have the truncate64 function */ /* #undef HAVE_TRUNCATE64 */ /* Define if you have the ftruncate64 function */ /* #undef HAVE_FTRUNCATE64 */ /* Define if you have the strtoll function */ #define HAVE_STRTOLL 1 /* Define if you have the hstrerror function */ #define HAVE_HSTRERROR 1 /* Define if you have the inet_ntop function */ #define HAVE_INET_NTOP 1 /* Define if you have the hstrerror prototype */ #define HAVE_PROTOTYPE_HSTRERROR 1 /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define if you have the header file. */ #define HAVE_SYSLOG_H 1 /* Define if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define if you have the header file. */ #define HAVE_PWD_H 1 /* Define if you have the header file. */ #define HAVE_GRP_H 1 /* Define if you have the header file. */ #define HAVE_STDINT_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define if you have the header file. */ #define HAVE_SYS_POLL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define if you have the header file. */ #define HAVE_NETDB_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UN_H 1 /* Define if you have the header file. */ /* #undef HAVE_PTY_H */ /* Define if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IN_SYSTM_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP6_H 1 /* Define if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define if you have the header file. */ #define HAVE_RESOLV_H 1 /* Define if you have the header file. */ #define HAVE_TERMIOS_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_DL_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_TYPES_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_ERRQUEUE_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_IF_TUN_H */ /* Define if you have the header file. */ /* #undef HAVE_NETPACKET_PACKET_H */ /* Define if you have the header file. */ /* #undef HAVE_NETINET_IF_ETHER_H */ /* Define if you have the header file. */ #define HAVE_SYS_UTSNAME_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_SELECT_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_FILE_H 1 /* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ #define HAVE_UTIL_H 1 /* Define if you have the header file. (FreeBSD: openpty()) */ /* #undef HAVE_LIBUTIL_H */ /* Define if you have the header file. (stream opts on SunOS)*/ /* #undef HAVE_SYS_STROPTS_H */ /* Define if you have the header file. */ #define HAVE_REGEX_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_FS_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_EXT2_FS_H */ /* Define if you have the header file. */ #define HAVE_READLINE_READLINE_H 1 /* Define if you have the header file. */ #define HAVE_READLINE_HISTORY_H 1 /* Define if you have the readline library. */ #define HAVE_LIBREADLINE 1 /* Define if you have the m library (-lm). */ /* #undef HAVE_LIBM */ /* Define if you have the floor function */ /* #undef HAVE_FLOOR */ /* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ /* #undef _XOPEN_EXTENDED_SOURCE */ /* fdset may have component fds_bits or __fds_bits */ #define HAVE_FDS_BITS 1 /* Define if you have the sa_family_t */ #define HAVE_TYPE_SA_FAMILY_T 1 /* define if your struct sigaction has sa_sigaction */ #define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 /* Define if your struct termios has component c_ispeed */ #define HAVE_TERMIOS_ISPEED 1 /* the offset of c_ispeed in struct termios - usable in an speed_t array. Applies only when HAVE_TERMIOS_ISPEED is set */ #define ISPEED_OFFSET 9 /* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ #ifdef ISPEED_OFFSET # define OSPEED_OFFSET (ISPEED_OFFSET+1) #else /* # undef OSPEED_OFFSET */ #endif /* Define if your termios.h likes _SVID3 defined */ /* #undef _SVID3 */ /* Define if you have struct timespec (e.g. for nanosleep) */ #define HAVE_STRUCT_TIMESPEC 1 /* Define if you have struct linger */ #define HAVE_STRUCT_LINGER 1 /* Define if you have struct ip_mreq */ #define HAVE_STRUCT_IP_MREQ 1 /* Define if you have struct ip_mreqn */ /* #undef HAVE_STRUCT_IP_MREQN */ /* Define if you have struct ipv6_mreq */ #define HAVE_STRUCT_IPV6_MREQ 1 /* Define if you have struct ifreq */ #define HAVE_STRUCT_IFREQ 1 /* Define if you have struct ifreq.ifr_index */ /* #undef HAVE_STRUCT_IFREQ_IFR_INDEX */ /* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ /* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ /* Define if your struct sockaddr has sa_len */ #define HAVE_STRUCT_SOCKADDR_SALEN 1 /* there are several implementations of sockaddr_in6 */ #define HAVE_IP6_SOCKADDR 0 /* Define if you have struct iovec */ /* #undef HAVE_STRUCT_IOVEC */ /* define if your struct msghdr has msg_control */ #define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 /* define if your struct msghdr has msg_controllen */ #define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 /* define if your struct msghdr has msg_flag */ #define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 /* define if you have struct cmsghdr */ #define HAVE_STRUCT_CMSGHDR 1 /* define if you have struct in_pktinfo */ /* #undef HAVE_STRUCT_IN_PKTINFO */ /* define if your struct ip has ip_hl; otherwise assume ip_vhl */ #define HAVE_STRUCT_IP_IP_HL 1 /* Define if you have the setenv function */ #define HAVE_SETENV 1 /* Define if you have the unsetenv function. not on HP-UX */ #define HAVE_UNSETENV 1 /* Define if you have the flock function */ #define HAVE_FLOCK 1 /* Define if you have the openpty function */ #define HAVE_OPENPTY 1 /* Define if you have the grantpt function */ /* #undef HAVE_GRANTPT */ /* Define if you have the unlockpt function */ /* #undef HAVE_UNLOCKPT */ /* Define if you have the ptsname function */ /* #undef HAVE_PTSNAME */ /* Define if you have the /dev/ptmx pseudo terminal multiplexer */ /* #undef HAVE_DEV_PTMX */ /* Define if you have the /dev/ptc pseudo terminal multiplexer */ /* #undef HAVE_DEV_PTC */ /* Define if you have the long long type */ #define HAVE_TYPE_LONGLONG 1 /* is socklen_t already typedef'd? */ #define HAVE_TYPE_SOCKLEN 1 /* Define if you have the struct stat64 type */ /* #undef HAVE_TYPE_STAT64 */ /* Define if you have the struct off64_t type */ /* #undef HAVE_TYPE_OFF64 */ /* is sighandler_t already typedef'd? */ /* #undef HAVE_TYPE_SIGHANDLER */ /* is uint8_t already defined? */ #define HAVE_TYPE_UINT8 1 /* is uint16_t already defined? */ #define HAVE_TYPE_UINT16 1 /* is uint32_t already defined? */ #define HAVE_TYPE_UINT32 1 /* is uint64_t already defined? */ #define HAVE_TYPE_UINT64 1 /* Define if you have the printf "Z" modifier */ /* #undef HAVE_FORMAT_Z */ /* Define the shift offset of the CRDLY mask */ #define CRDLY_SHIFT -1 /* Define the shift offset of the TABDLY mask */ #define TABDLY_SHIFT -1 /* Define the shift offset of the CSIZE mask */ #define CSIZE_SHIFT 8 /* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ #define HAVE_HOSTS_ALLOW_TABLE 1 #if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE # define HAVE_HOSTS_DENY_TABLE 1 #else /* # undef HAVE_HOSTS_DENY_TABLE */ #endif /* 1..short, 3..int, 5..long; 2,4,6..unsigned */ #define HAVE_BASIC_SIZE_T 6 /* unsigned long */ #define HAVE_BASIC_MODE_T 4 /* unsigned int */ #define HAVE_BASIC_PID_T 3 /* int */ #define HAVE_BASIC_UID_T 4 /* unsigned int */ #define HAVE_BASIC_GID_T 4 /* unsigned int */ #define HAVE_BASIC_TIME_T 3 /* int */ #define HAVE_BASIC_OFF64_T 0 /* unknown, taking default */ #define HAVE_BASIC_SOCKLEN_T 4 /* unsigned int */ #define HAVE_TYPEOF_ST_DEV 3 /* int */ #define HAVE_TYPEOF_ST_INO 4 /* unsigned int */ #define HAVE_TYPEOF_ST_NLINK 4 /* unsigned int */ #define HAVE_TYPEOF_ST_SIZE 7 /* long long */ #define HAVE_TYPEOF_ST_BLKSIZE 4 /* unsigned int */ #define HAVE_TYPEOF_ST_BLOCKS 7 /* long long */ /* #undef HAVE_TYPEOF_ST64_DEV */ /* #undef HAVE_TYPEOF_ST64_INO */ /* #undef HAVE_TYPEOF_ST64_NLINK */ /* #undef HAVE_TYPEOF_ST64_SIZE */ /* #undef HAVE_TYPEOF_ST64_BLKSIZE */ /* #undef HAVE_TYPEOF_ST64_BLOCKS */ #define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 /* long */ #define HAVE_TYPEOF_RLIM_MAX 8 /* unsigned long long */ /* Define if you have the /proc filesystem */ /* #undef HAVE_PROC_DIR */ /* Define if you have the /proc/$$/fd directories */ /* #undef HAVE_PROC_DIR_FD */ #define WITH_HELP 1 #define WITH_STDIO 1 #define WITH_FDNUM 1 #define WITH_FILE 1 #define WITH_CREAT 1 #define WITH_GOPEN 1 #define WITH_TERMIOS 1 #define WITH_PIPE 1 #define WITH_UNIX 1 /* #undef WITH_ABSTRACT_UNIXSOCKET */ #define WITH_IP4 1 #define WITH_IP6 1 #define WITH_RAWIP 1 #define WITH_GENERICSOCKET 1 /* #undef WITH_INTERFACE */ #define WITH_TCP 1 #define WITH_UDP 1 /* #undef WITH_SCTP */ #define WITH_LISTEN 1 #define WITH_SOCKS4 1 #define WITH_SOCKS4A 1 #define WITH_PROXY 1 #define WITH_EXEC 1 #define WITH_SYSTEM 1 #define WITH_READLINE 1 /* #undef WITH_TUN */ #define WITH_PTY 1 #define WITH_EXT2 1 #define WITH_OPENSSL 1 #define WITH_STREAMS 1 /* #undef WITH_FIPS */ /* #undef OPENSSL_FIPS */ #define WITH_LIBWRAP 1 #define HAVE_TCPD_H 1 #define HAVE_LIBWRAP 1 #define WITH_SYCLS 1 #define WITH_FILAN 1 #define WITH_RETRY 1 #define WITH_MSGLEVEL 0 #endif /* !defined(__config_h_included) */ socat-1.7.3.1/Config/config.Linux-2-6-24.h0000644000201000020100000003346711453022151017235 0ustar gerhardgerhard/* config.h. Generated from config.h.in by configure. */ /* source: config.h.in */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __config_h_included #define __config_h_included 1 /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to `int' if doesn't define. */ /* #undef gid_t */ /* Define if your struct stat has st_blksize. */ #define HAVE_ST_BLKSIZE 1 /* Define if your struct stat has st_blocks. */ #define HAVE_ST_BLOCKS 1 /* Define if your struct stat has st_rdev. */ #define HAVE_ST_RDEV 1 /* Define if you have the strftime function. */ #define HAVE_STRFTIME 1 /* Define if you have that is POSIX.1 compatible. */ #define HAVE_SYS_WAIT_H 1 /* Define to `int' if doesn't define. */ /* #undef mode_t */ /* Define to `long' if doesn't define. */ /* #undef off_t */ /* Define to `int' if doesn't define. */ /* #undef pid_t */ /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define to `unsigned' if doesn't define. */ /* #undef size_t */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to `int' if doesn't define. */ /* #undef uid_t */ /* Define if you have the putenv function. */ #define HAVE_PUTENV 1 /* Define if you have the select function. */ #define HAVE_SELECT 1 /* Define if you have the poll function. */ #define HAVE_POLL 1 /* Define if you have the socket function. */ #define HAVE_SOCKET 1 /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define if you have the strerror function. */ #define HAVE_STRERROR 1 /* Define if you have the strstr function. */ #define HAVE_STRSTR 1 /* Define if you have the strtod function. */ #define HAVE_STRTOD 1 /* Define if you have the strtol function. */ #define HAVE_STRTOL 1 /* Define if you have the strtoul function. */ #define HAVE_STRTOUL 1 /* Define if you have the uname function. */ #define HAVE_UNAME 1 /* Define if you have the getpgid function. */ #define HAVE_GETPGID 1 /* Define if you have the getsid function. */ #define HAVE_GETSID 1 /* Define if you have the nanosleep function. */ #define HAVE_NANOSLEEP 1 /* Define if you have the getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define if you have the getipnodebyname function. */ /* #undef HAVE_GETIPNODEBYNAME */ /* Define if you have the setgroups function. */ #define HAVE_SETGROUPS 1 /* Define if you have the inet_aton function. */ #define HAVE_INET_ATON 1 /* Define if you have the memrchr function. */ #define HAVE_MEMRCHR 1 /* Define if you have the if_indextoname function. */ #define HAVE_IF_INDEXTONAME 1 /* Define if you have the sigaction function */ #define HAVE_SIGACTION 1 /* Define if you have the stat64 function */ #define HAVE_STAT64 1 /* Define if you have the fstat64 function */ #define HAVE_FSTAT64 1 /* Define if you have the lstat64 function */ #define HAVE_LSTAT64 1 /* Define if you have the lseek64 function */ #define HAVE_LSEEK64 1 /* Define if you have the truncate64 function */ #define HAVE_TRUNCATE64 1 /* Define if you have the ftruncate64 function */ #define HAVE_FTRUNCATE64 1 /* Define if you have the strtoll function */ #define HAVE_STRTOLL 1 /* Define if you have the hstrerror function */ #define HAVE_HSTRERROR 1 /* Define if you have the inet_ntop function */ #define HAVE_INET_NTOP 1 /* Define if you have the hstrerror prototype */ #define HAVE_PROTOTYPE_HSTRERROR 1 /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define if you have the header file. */ #define HAVE_SYSLOG_H 1 /* Define if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define if you have the header file. */ #define HAVE_PWD_H 1 /* Define if you have the header file. */ #define HAVE_GRP_H 1 /* Define if you have the header file. */ #define HAVE_STDINT_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define if you have the header file. */ #define HAVE_SYS_POLL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define if you have the header file. */ #define HAVE_NETDB_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UN_H 1 /* Define if you have the header file. */ #define HAVE_PTY_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IN_SYSTM_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP6_H 1 /* Define if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define if you have the header file. */ #define HAVE_RESOLV_H 1 /* Define if you have the header file. */ #define HAVE_TERMIOS_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define if you have the header file. */ /* #undef HAVE_NET_IF_DL_H */ /* Define if you have the header file. */ #define HAVE_LINUX_TYPES_H 1 /* Define if you have the header file. */ #define HAVE_LINUX_ERRQUEUE_H 1 /* Define if you have the header file. */ #define HAVE_LINUX_IF_TUN_H 1 /* Define if you have the header file. */ #define HAVE_NETPACKET_PACKET_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IF_ETHER_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UTSNAME_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_SELECT_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_FILE_H 1 /* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ /* #undef HAVE_UTIL_H */ /* Define if you have the header file. (FreeBSD: openpty()) */ /* #undef HAVE_LIBUTIL_H */ /* Define if you have the header file. (stream opts on SunOS)*/ #define HAVE_SYS_STROPTS_H 1 /* Define if you have the header file. */ #define HAVE_REGEX_H 1 /* Define if you have the header file. */ #define HAVE_LINUX_FS_H 1 /* Define if you have the header file. */ #define HAVE_LINUX_EXT2_FS_H 1 /* Define if you have the header file. */ #define HAVE_READLINE_READLINE_H 1 /* Define if you have the header file. */ #define HAVE_READLINE_HISTORY_H 1 /* Define if you have the readline library. */ #define HAVE_LIBREADLINE 1 /* Define if you have the m library (-lm). */ /* #undef HAVE_LIBM */ /* Define if you have the floor function */ /* #undef HAVE_FLOOR */ /* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ /* #undef _XOPEN_EXTENDED_SOURCE */ /* fdset may have component fds_bits or __fds_bits */ #define HAVE_FDS_BITS 1 /* Define if you have the sa_family_t */ #define HAVE_TYPE_SA_FAMILY_T 1 /* define if your struct sigaction has sa_sigaction */ #define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 /* Define if your struct termios has component c_ispeed */ #define HAVE_TERMIOS_ISPEED 1 /* the offset of c_ispeed in struct termios - usable in an speed_t array. Applies only when HAVE_TERMIOS_ISPEED is set */ #define ISPEED_OFFSET 13 /* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ #ifdef ISPEED_OFFSET # define OSPEED_OFFSET (ISPEED_OFFSET+1) #else /* # undef OSPEED_OFFSET */ #endif /* Define if your termios.h likes _SVID3 defined */ /* #undef _SVID3 */ /* Define if you have struct timespec (e.g. for nanosleep) */ #define HAVE_STRUCT_TIMESPEC 1 /* Define if you have struct linger */ #define HAVE_STRUCT_LINGER 1 /* Define if you have struct ip_mreq */ #define HAVE_STRUCT_IP_MREQ 1 /* Define if you have struct ip_mreqn */ #define HAVE_STRUCT_IP_MREQN 1 /* Define if you have struct ipv6_mreq */ #define HAVE_STRUCT_IPV6_MREQ 1 /* Define if you have struct ifreq */ #define HAVE_STRUCT_IFREQ 1 /* Define if you have struct ifreq.ifr_index */ /* #undef HAVE_STRUCT_IFREQ_IFR_INDEX */ /* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ #define HAVE_STRUCT_IFREQ_IFR_IFINDEX 1 /* Define if your struct sockaddr has sa_len */ /* #undef HAVE_STRUCT_SOCKADDR_SALEN */ /* there are several implementations of sockaddr_in6 */ #define HAVE_IP6_SOCKADDR 0 /* Define if you have struct iovec */ #define HAVE_STRUCT_IOVEC 1 /* define if your struct msghdr has msg_control */ #define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 /* define if your struct msghdr has msg_controllen */ #define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 /* define if your struct msghdr has msg_flag */ #define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 /* define if you have struct cmsghdr */ #define HAVE_STRUCT_CMSGHDR 1 /* define if you have struct in_pktinfo */ #define HAVE_STRUCT_IN_PKTINFO 1 /* define if your struct ip has ip_hl; otherwise assume ip_vhl */ #define HAVE_STRUCT_IP_IP_HL 1 /* Define if you have the setenv function */ #define HAVE_SETENV 1 /* Define if you have the unsetenv function. not on HP-UX */ #define HAVE_UNSETENV 1 /* Define if you have the flock function */ #define HAVE_FLOCK 1 /* Define if you have the openpty function */ #define HAVE_OPENPTY 1 /* Define if you have the grantpt function */ #define HAVE_GRANTPT 1 /* Define if you have the unlockpt function */ #define HAVE_UNLOCKPT 1 /* Define if you have the ptsname function */ #define HAVE_PTSNAME 1 /* Define if you have the /dev/ptmx pseudo terminal multiplexer */ #define HAVE_DEV_PTMX 1 /* Define if you have the /dev/ptc pseudo terminal multiplexer */ /* #undef HAVE_DEV_PTC */ /* Define if you have the long long type */ #define HAVE_TYPE_LONGLONG 1 /* is socklen_t already typedef'd? */ #define HAVE_TYPE_SOCKLEN 1 /* Define if you have the struct stat64 type */ #define HAVE_TYPE_STAT64 1 /* Define if you have the struct off64_t type */ #define HAVE_TYPE_OFF64 1 /* is sighandler_t already typedef'd? */ #define HAVE_TYPE_SIGHANDLER 1 /* is uint8_t already defined? */ #define HAVE_TYPE_UINT8 1 /* is uint16_t already defined? */ #define HAVE_TYPE_UINT16 1 /* is uint32_t already defined? */ #define HAVE_TYPE_UINT32 1 /* is uint64_t already defined? */ #define HAVE_TYPE_UINT64 1 /* Define if you have the printf "Z" modifier */ #define HAVE_FORMAT_Z 1 /* Define the shift offset of the CRDLY mask */ #define CRDLY_SHIFT 9 /* Define the shift offset of the TABDLY mask */ #define TABDLY_SHIFT 11 /* Define the shift offset of the CSIZE mask */ #define CSIZE_SHIFT 4 /* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ #define HAVE_HOSTS_ALLOW_TABLE 1 #if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE # define HAVE_HOSTS_DENY_TABLE 1 #else /* # undef HAVE_HOSTS_DENY_TABLE */ #endif /* 1..short, 3..int, 5..long; 2,4,6..unsigned */ #define HAVE_BASIC_SIZE_T 4 /* unsigned int */ #define HAVE_BASIC_MODE_T 4 /* unsigned int */ #define HAVE_BASIC_PID_T 3 /* int */ #define HAVE_BASIC_UID_T 4 /* unsigned int */ #define HAVE_BASIC_GID_T 4 /* unsigned int */ #define HAVE_BASIC_TIME_T 5 /* long */ #define HAVE_BASIC_OFF64_T 7 /* long long */ #define HAVE_BASIC_SOCKLEN_T 4 /* unsigned int */ #define HAVE_TYPEOF_ST_DEV 8 /* unsigned long long */ #define HAVE_TYPEOF_ST_INO 6 /* unsigned long */ #define HAVE_TYPEOF_ST_NLINK 4 /* unsigned int */ #define HAVE_TYPEOF_ST_SIZE 5 /* long */ #define HAVE_TYPEOF_ST_BLKSIZE 5 /* long */ #define HAVE_TYPEOF_ST_BLOCKS 5 /* long */ #define HAVE_TYPEOF_ST64_DEV 8 /* unsigned long long */ #define HAVE_TYPEOF_ST64_INO 8 /* unsigned long long */ #define HAVE_TYPEOF_ST64_NLINK 4 /* unsigned int */ #define HAVE_TYPEOF_ST64_SIZE 7 /* long long */ #define HAVE_TYPEOF_ST64_BLKSIZE 5 /* long */ #define HAVE_TYPEOF_ST64_BLOCKS 7 /* long long */ #define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 /* long */ #define HAVE_TYPEOF_RLIM_MAX 6 /* unsigned long */ /* Define if you have the /proc filesystem */ #define HAVE_PROC_DIR 1 /* Define if you have the /proc/$$/fd directories */ #define HAVE_PROC_DIR_FD 1 #define WITH_HELP 1 #define WITH_STDIO 1 #define WITH_FDNUM 1 #define WITH_FILE 1 #define WITH_CREAT 1 #define WITH_GOPEN 1 #define WITH_TERMIOS 1 #define WITH_PIPE 1 #define WITH_UNIX 1 #define WITH_ABSTRACT_UNIXSOCKET 1 #define WITH_IP4 1 #define WITH_IP6 1 #define WITH_RAWIP 1 #define WITH_GENERICSOCKET 1 #define WITH_INTERFACE 1 #define WITH_TCP 1 #define WITH_UDP 1 #define WITH_SCTP 1 #define WITH_LISTEN 1 #define WITH_SOCKS4 1 #define WITH_SOCKS4A 1 #define WITH_PROXY 1 #define WITH_EXEC 1 #define WITH_SYSTEM 1 #define WITH_READLINE 1 #define WITH_TUN 1 #define WITH_PTY 1 #define WITH_EXT2 1 #define WITH_OPENSSL 1 #define WITH_STREAMS 1 /* #undef WITH_FIPS */ /* #undef OPENSSL_FIPS */ #define WITH_LIBWRAP 1 #define HAVE_TCPD_H 1 #define HAVE_LIBWRAP 1 #define WITH_SYCLS 1 #define WITH_FILAN 1 #define WITH_RETRY 1 #define WITH_MSGLEVEL 0 #endif /* !defined(__config_h_included) */ socat-1.7.3.1/Config/Makefile.NetBSD-5-10000644000201000020100000001410212326025135017000 0ustar gerhardgerhard# source: Makefile.in # Copyright Gerhard Rieger 2001-2008 # Published under the GNU General Public License V.2, see file COPYING # note: @...@ forms are filled in by configure script SHELL = /bin/sh AR = ar RANLIB = ranlib .SUFFIXES: .c .o prefix = /usr/local exec_prefix = ${prefix} BINDEST = ${exec_prefix}/bin datarootdir = ${prefix}/share MANDEST = ${datarootdir}/man srcdir = . CC = gcc CCOPTS = $(CCOPT) -Wall -Wno-parentheses SYSDEFS = CPPFLAGS = -I. #0 INCLS = -I. @V_INCL@ DEFS = -DHAVE_CONFIG_H LIBS = -lwrap -lutil -lssl LDFLAGS = INSTALL = /usr/bin/install -c #OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) #0 CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(INCLS) CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(CPPFLAGS) CLIBS = $(LIBS) #CLIBS = $(LIBS) -lm -lefence XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xiosignal.c xiosigchld.c xioread.c xiowrite.c \ xiolayer.c xioshutdown.c xioclose.c xioexit.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ xio-sctp.c xio-rawip.c \ xio-socks.c xio-proxy.c xio-udp.c \ xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ xio-pty.c xio-openssl.c xio-streams.c\ xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c XIOOBJS = $(XIOSRCS:.c=.o) UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c UTLOBJS = $(UTLSRCS:.c=.o) CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c OFILES = $(CFILES:.c=.o) PROGS = socat procan filan HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ xio-system.h xio-termios.h xio-readline.h \ xio-pty.h xio-openssl.h xio-streams.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html SHFILES = daemon.sh mail.sh ftp.sh readline.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ proxy.sh socks4a-echo.sh testcert.conf OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h all: progs doc scmclean: gitclean gitclean: distclean docclean rm -f Makefile.bak configure doc: doc/socat.1 doc/socat.html docclean: rm -f doc/socat.1 doc/socat.html doc/socat.1: doc/socat.yo yodl2man -o $@ $+ doc/socat.html: doc/socat.yo cd doc; yodl2html -o socat.html socat.yo; cd .. progs: $(PROGS) depend: $(CFILES) $(HFILES) makedepend $(SYSDEFS) $(CFILES) socat: socat.o libxio.a $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o procan: $(PROCAN_OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) libxio.a: $(XIOOBJS) $(UTLOBJS) $(AR) r $@ $(XIOOBJS) $(UTLOBJS) $(RANLIB) $@ doc: doc/xio.help # strip: progs strip $(PROGS) install: progs $(srcdir)/doc/socat.1 mkdir -p $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) mkdir -p $(DESTDIR)$(MANDEST)/man1 $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ uninstall: rm -f $(DESTDIR)$(BINDEST)/socat rm -f $(DESTDIR)$(BINDEST)/procan rm -f $(DESTDIR)$(BINDEST)/filan rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 # make a GNU-zipped tar ball of the source files dist: socat.tar.gz socat.tar.bz2 socat.tar.gz: socat.tar gzip -9 socat.tar.gz socat.tar.bz2: socat.tar bzip2 -9 socat.tar.bz2 VERSION = `sed 's/"//g' VERSION` TARDIR = socat-$(VERSION) socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi tar cf - $+ |(cd $(TARDIR); tar xf -) tar cvf socat.tar $(TARDIR) rm -f $(TARDIR)/COPYING # write protected rm -r $(TARDIR) clean: rm -f *.o libxio.a socat procan filan \ socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ socat.out compile.log test.log # remove all files that are generated from the original socat distribution # note that Makefile is also removed, so you have to start with ./configure # again distclean: clean rm -f config.status config.cache config.log config.h Makefile rm -rf autom4te.cache info: socat uname -a >socat.out ./socat -V >>socat.out ./socat -hh >>socat.out # perform some tests on socat test: progs ./test.sh cert: # prepare critical files with correct permissions to avoid race cond >cert.key >cert.pem chmod 600 cert.key cert.pem # generate a private key openssl genrsa -out cert.key 1024 # generate a self signed cert openssl req -new -key cert.key -x509 -days 3653 -out cert.crt # ...enter fields # generate the pem file cat cert.key cert.crt >cert.pem #echo use cert.pem on requestors side, i.e. with option cert=cert.pem #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt socat-1.7.3.1/Config/Makefile.DragonFly-2-8-20000644000201000020100000001444311662777020017772 0ustar gerhardgerhard# source: Makefile.in # Copyright Gerhard Rieger 2001-2009 # Published under the GNU General Public License V.2, see file COPYING # note: @...@ forms are filled in by configure script SHELL = /bin/sh AR = ar RANLIB = ranlib .SUFFIXES: .c .o prefix = /usr/local exec_prefix = ${prefix} BINDEST = ${exec_prefix}/bin datarootdir = ${prefix}/share MANDEST = ${datarootdir}/man srcdir = . CC = gcc CCOPTS = $(CCOPT) SYSDEFS = CPPFLAGS = -I. #0 INCLS = -I. @V_INCL@ DEFS = -DHAVE_CONFIG_H LIBS = -lwrap -lutil -lssl LDFLAGS = INSTALL = /usr/bin/install -c #OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) #0 CFLAGS = -O -D_GNU_SOURCE -Wall -Wno-parentheses $(CCOPTS) $(DEFS) $(INCLS) CFLAGS = -O -D_GNU_SOURCE -Wall -Wno-parentheses $(CCOPTS) $(DEFS) $(CPPFLAGS) CLIBS = $(LIBS) #CLIBS = $(LIBS) -lm -lefence XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xiosignal.c xiosigchld.c xioread.c xiowrite.c \ xiolayer.c xioshutdown.c xioclose.c xioexit.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ xio-sctp.c xio-rawip.c \ xio-socks.c xio-proxy.c xio-udp.c \ xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ xio-pty.c xio-openssl.c xio-streams.c\ xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c XIOOBJS = $(XIOSRCS:.c=.o) UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c UTLOBJS = $(UTLSRCS:.c=.o) CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c OFILES = $(CFILES:.c=.o) PROGS = socat procan filan HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ xio-system.h xio-termios.h xio-readline.h \ xio-pty.h xio-openssl.h xio-streams.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html doc/socat-genericsocket.html SHFILES = daemon.sh mail.sh ftp.sh readline.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ proxy.sh socks4a-echo.sh testcert.conf OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h \ Config/Makefile.AIX-5-3 Config/config.AIX-5-3.h \ Config/Makefile.Cygwin-1-5-25 Config/config.Cygwin-1-5-25.h \ Config/Makefile.MacOSX-10-5 Config/config.MacOSX-10-5.h all: progs doc scmclean: gitclean gitclean: distclean docclean rm -f Makefile.bak configure doc: doc/socat.1 doc/socat.html docclean: rm -f doc/socat.1 doc/socat.html doc/socat.1: doc/socat.yo yodl2man -o $@ $+ doc/socat.html: doc/socat.yo cd doc; yodl2html -o socat.html socat.yo; cd .. progs: $(PROGS) depend: $(CFILES) $(HFILES) makedepend $(SYSDEFS) $(CFILES) socat: socat.o libxio.a $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o procan: $(PROCAN_OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) libxio.a: $(XIOOBJS) $(UTLOBJS) $(AR) r $@ $(XIOOBJS) $(UTLOBJS) $(RANLIB) $@ doc: doc/xio.help # strip: progs strip $(PROGS) install: progs $(srcdir)/doc/socat.1 mkdir -p $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) mkdir -p $(DESTDIR)$(MANDEST)/man1 $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ uninstall: rm -f $(DESTDIR)$(BINDEST)/socat rm -f $(DESTDIR)$(BINDEST)/procan rm -f $(DESTDIR)$(BINDEST)/filan rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 # make a GNU-zipped tar ball of the source files dist: socat.tar.gz socat.tar.bz2 socat.tar.gz: socat.tar gzip -9 socat.tar.gz socat.tar.bz2: socat.tar bzip2 -9 socat.tar.bz2 VERSION = `sed 's/"//g' VERSION` TARDIR = socat-$(VERSION) socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi tar cf - $+ |(cd $(TARDIR); tar xf -) tar cvf socat.tar $(TARDIR) rm -f $(TARDIR)/COPYING # write protected rm -r $(TARDIR) clean: rm -f *.o libxio.a socat procan filan \ socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ socat.out compile.log test.log # remove all files that are generated from the original socat distribution # note that Makefile is also removed, so you have to start with ./configure # again distclean: clean rm -f config.status config.cache config.log config.h Makefile rm -rf autom4te.cache info: socat uname -a >socat.out ./socat -V >>socat.out ./socat -hh >>socat.out # perform some tests on socat test: progs ./test.sh cert: # prepare critical files with correct permissions to avoid race cond >cert.key >cert.pem chmod 600 cert.key cert.pem # generate a private key openssl genrsa -out cert.key 1024 # generate a self signed cert openssl req -new -key cert.key -x509 -days 3653 -out cert.crt # ...enter fields # generate the pem file cat cert.key cert.crt >cert.pem #echo use cert.pem on requestors side, i.e. with option cert=cert.pem #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt socat-1.7.3.1/Config/Makefile.MacOSX-10-50000644000201000020100000001430211453022151017070 0ustar gerhardgerhard# source: Makefile.in # Copyright Gerhard Rieger 2001-2008 # Published under the GNU General Public License V.2, see file COPYING # note: @...@ forms are filled in by configure script SHELL = /bin/sh AR = ar RANLIB = ranlib .SUFFIXES: .c .o prefix = /usr/local exec_prefix = ${prefix} BINDEST = ${exec_prefix}/bin datarootdir = ${prefix}/share MANDEST = ${datarootdir}/man srcdir = . CC = gcc CCOPTS = $(CCOPT) -Wall -Wno-parentheses SYSDEFS = -D__DYNAMIC__ CPPFLAGS = -I. -I/usr/local/include #0 INCLS = -I. @V_INCL@ DEFS = -DHAVE_CONFIG_H LIBS = -lwrap -lutil -lresolv -lreadline -lssl -lcrypto LDFLAGS = INSTALL = /usr/bin/install -c #OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) #0 CFLAGS = -O -D_GNU_SOURCE -L/usr/local/lib $(CCOPTS) $(DEFS) $(INCLS) CFLAGS = -O -D_GNU_SOURCE -L/usr/local/lib $(CCOPTS) $(DEFS) $(CPPFLAGS) CLIBS = $(LIBS) #CLIBS = $(LIBS) -lm -lefence XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xiosignal.c xiosigchld.c xioread.c xiowrite.c \ xiolayer.c xioshutdown.c xioclose.c xioexit.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ xio-sctp.c xio-rawip.c \ xio-socks.c xio-proxy.c xio-udp.c \ xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ xio-pty.c xio-openssl.c xio-streams.c\ xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c XIOOBJS = $(XIOSRCS:.c=.o) UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c UTLOBJS = $(UTLSRCS:.c=.o) CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c OFILES = $(CFILES:.c=.o) PROGS = socat procan filan HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ xio-system.h xio-termios.h xio-readline.h \ xio-pty.h xio-openssl.h xio-streams.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html doc/socat-genericsocket.html SHFILES = daemon.sh mail.sh ftp.sh readline.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ proxy.sh socks4a-echo.sh testcert.conf OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h all: progs doc scmclean: gitclean gitclean: distclean docclean rm -f Makefile.bak configure doc: doc/socat.1 doc/socat.html docclean: rm -f doc/socat.1 doc/socat.html doc/socat.1: doc/socat.yo yodl2man -o $@ $+ doc/socat.html: doc/socat.yo cd doc; yodl2html -o socat.html socat.yo; cd .. progs: $(PROGS) depend: $(CFILES) $(HFILES) makedepend $(SYSDEFS) $(CFILES) socat: socat.o libxio.a $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o procan: $(PROCAN_OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) libxio.a: $(XIOOBJS) $(UTLOBJS) $(AR) r $@ $(XIOOBJS) $(UTLOBJS) $(RANLIB) $@ doc: doc/xio.help # strip: progs strip $(PROGS) install: progs $(srcdir)/doc/socat.1 mkdir -p $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) mkdir -p $(DESTDIR)$(MANDEST)/man1 $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ uninstall: rm -f $(DESTDIR)$(BINDEST)/socat rm -f $(DESTDIR)$(BINDEST)/procan rm -f $(DESTDIR)$(BINDEST)/filan rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 # make a GNU-zipped tar ball of the source files dist: socat.tar.gz socat.tar.bz2 socat.tar.gz: socat.tar gzip -9 socat.tar.gz socat.tar.bz2: socat.tar bzip2 -9 socat.tar.bz2 VERSION = `sed 's/"//g' VERSION` TARDIR = socat-$(VERSION) socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi tar cf - $+ |(cd $(TARDIR); tar xf -) tar cvf socat.tar $(TARDIR) rm -f $(TARDIR)/COPYING # write protected rm -r $(TARDIR) clean: rm -f *.o libxio.a socat procan filan \ socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ socat.out compile.log test.log # remove all files that are generated from the original socat distribution # note that Makefile is also removed, so you have to start with ./configure # again distclean: clean rm -f config.status config.cache config.log config.h Makefile rm -rf autom4te.cache info: socat uname -a >socat.out ./socat -V >>socat.out ./socat -hh >>socat.out # perform some tests on socat test: progs ./test.sh cert: # prepare critical files with correct permissions to avoid race cond >cert.key >cert.pem chmod 600 cert.key cert.pem # generate a private key openssl genrsa -out cert.key 1024 # generate a self signed cert openssl req -new -key cert.key -x509 -days 3653 -out cert.crt # ...enter fields # generate the pem file cat cert.key cert.crt >cert.pem #echo use cert.pem on requestors side, i.e. with option cert=cert.pem #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt socat-1.7.3.1/Config/config.Cygwin-1-5-25.h0000644000201000020100000003352111453022151017364 0ustar gerhardgerhard/* config.h. Generated from config.h.in by configure. */ /* source: config.h.in */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __config_h_included #define __config_h_included 1 /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to `int' if doesn't define. */ /* #undef gid_t */ /* Define if your struct stat has st_blksize. */ #define HAVE_ST_BLKSIZE 1 /* Define if your struct stat has st_blocks. */ #define HAVE_ST_BLOCKS 1 /* Define if your struct stat has st_rdev. */ #define HAVE_ST_RDEV 1 /* Define if you have the strftime function. */ #define HAVE_STRFTIME 1 /* Define if you have that is POSIX.1 compatible. */ #define HAVE_SYS_WAIT_H 1 /* Define to `int' if doesn't define. */ /* #undef mode_t */ /* Define to `long' if doesn't define. */ /* #undef off_t */ /* Define to `int' if doesn't define. */ /* #undef pid_t */ /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define to `unsigned' if doesn't define. */ /* #undef size_t */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to `int' if doesn't define. */ /* #undef uid_t */ /* Define if you have the putenv function. */ #define HAVE_PUTENV 1 /* Define if you have the select function. */ #define HAVE_SELECT 1 /* Define if you have the poll function. */ #define HAVE_POLL 1 /* Define if you have the socket function. */ #define HAVE_SOCKET 1 /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define if you have the strerror function. */ #define HAVE_STRERROR 1 /* Define if you have the strstr function. */ #define HAVE_STRSTR 1 /* Define if you have the strtod function. */ #define HAVE_STRTOD 1 /* Define if you have the strtol function. */ #define HAVE_STRTOL 1 /* Define if you have the strtoul function. */ #define HAVE_STRTOUL 1 /* Define if you have the uname function. */ #define HAVE_UNAME 1 /* Define if you have the getpgid function. */ #define HAVE_GETPGID 1 /* Define if you have the getsid function. */ #define HAVE_GETSID 1 /* Define if you have the nanosleep function. */ #define HAVE_NANOSLEEP 1 /* Define if you have the getaddrinfo function. */ /* #undef HAVE_GETADDRINFO */ /* Define if you have the getipnodebyname function. */ /* #undef HAVE_GETIPNODEBYNAME */ /* Define if you have the setgroups function. */ #define HAVE_SETGROUPS 1 /* Define if you have the inet_aton function. */ #define HAVE_INET_ATON 1 /* Define if you have the memrchr function. */ /* #undef HAVE_MEMRCHR */ /* Define if you have the if_indextoname function. */ /* #undef HAVE_IF_INDEXTONAME */ /* Define if you have the sigaction function */ #define HAVE_SIGACTION 1 /* Define if you have the stat64 function */ /* #undef HAVE_STAT64 */ /* Define if you have the fstat64 function */ /* #undef HAVE_FSTAT64 */ /* Define if you have the lstat64 function */ /* #undef HAVE_LSTAT64 */ /* Define if you have the lseek64 function */ /* #undef HAVE_LSEEK64 */ /* Define if you have the truncate64 function */ /* #undef HAVE_TRUNCATE64 */ /* Define if you have the ftruncate64 function */ /* #undef HAVE_FTRUNCATE64 */ /* Define if you have the strtoll function */ #define HAVE_STRTOLL 1 /* Define if you have the hstrerror function */ #define HAVE_HSTRERROR 1 /* Define if you have the inet_ntop function */ #define HAVE_INET_NTOP 1 /* Define if you have the hstrerror prototype */ #define HAVE_PROTOTYPE_HSTRERROR 1 /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define if you have the header file. */ #define HAVE_SYSLOG_H 1 /* Define if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define if you have the header file. */ #define HAVE_PWD_H 1 /* Define if you have the header file. */ #define HAVE_GRP_H 1 /* Define if you have the header file. */ #define HAVE_STDINT_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define if you have the header file. */ #define HAVE_SYS_POLL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define if you have the header file. */ #define HAVE_NETDB_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UN_H 1 /* Define if you have the header file. */ #define HAVE_PTY_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IN_SYSTM_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define if you have the header file. */ /* #undef HAVE_NETINET_IP6_H */ /* Define if you have the header file. */ /* #undef HAVE_ARPA_NAMESER_H */ /* Define if you have the header file. */ /* #undef HAVE_RESOLV_H */ /* Define if you have the header file. */ #define HAVE_TERMIOS_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define if you have the header file. */ /* #undef HAVE_NET_IF_DL_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_TYPES_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_ERRQUEUE_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_IF_TUN_H */ /* Define if you have the header file. */ /* #undef HAVE_NETPACKET_PACKET_H */ /* Define if you have the header file. */ /* #undef HAVE_NETINET_IF_ETHER_H */ /* Define if you have the header file. */ #define HAVE_SYS_UTSNAME_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_SELECT_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_FILE_H 1 /* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ /* #undef HAVE_UTIL_H */ /* Define if you have the header file. (FreeBSD: openpty()) */ /* #undef HAVE_LIBUTIL_H */ /* Define if you have the header file. (stream opts on SunOS)*/ /* #undef HAVE_SYS_STROPTS_H */ /* Define if you have the header file. */ #define HAVE_REGEX_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_FS_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_EXT2_FS_H */ /* Define if you have the header file. */ #define HAVE_READLINE_READLINE_H 1 /* Define if you have the header file. */ #define HAVE_READLINE_HISTORY_H 1 /* Define if you have the readline library. */ #define HAVE_LIBREADLINE 1 /* Define if you have the m library (-lm). */ /* #undef HAVE_LIBM */ /* Define if you have the floor function */ /* #undef HAVE_FLOOR */ /* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ /* #undef _XOPEN_EXTENDED_SOURCE */ /* fdset may have component fds_bits or __fds_bits */ #define HAVE_FDS_BITS 1 /* Define if you have the sa_family_t */ #define HAVE_TYPE_SA_FAMILY_T 1 /* define if your struct sigaction has sa_sigaction */ #define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 /* Define if your struct termios has component c_ispeed */ #define HAVE_TERMIOS_ISPEED 1 /* the offset of c_ispeed in struct termios - usable in an speed_t array. Applies only when HAVE_TERMIOS_ISPEED is set */ #define ISPEED_OFFSET 9 /* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ #ifdef ISPEED_OFFSET # define OSPEED_OFFSET (ISPEED_OFFSET+1) #else /* # undef OSPEED_OFFSET */ #endif /* Define if your termios.h likes _SVID3 defined */ /* #undef _SVID3 */ /* Define if you have struct timespec (e.g. for nanosleep) */ #define HAVE_STRUCT_TIMESPEC 1 /* Define if you have struct linger */ #define HAVE_STRUCT_LINGER 1 /* Define if you have struct ip_mreq */ #define HAVE_STRUCT_IP_MREQ 1 /* Define if you have struct ip_mreqn */ /* #undef HAVE_STRUCT_IP_MREQN */ /* Define if you have struct ipv6_mreq */ /* #undef HAVE_STRUCT_IPV6_MREQ */ /* Define if you have struct ifreq */ #define HAVE_STRUCT_IFREQ 1 /* Define if you have struct ifreq.ifr_index */ /* #undef HAVE_STRUCT_IFREQ_IFR_INDEX */ /* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ /* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ /* Define if your struct sockaddr has sa_len */ /* #undef HAVE_STRUCT_SOCKADDR_SALEN */ /* there are several implementations of sockaddr_in6 */ /* #undef HAVE_IP6_SOCKADDR */ /* Define if you have struct iovec */ #define HAVE_STRUCT_IOVEC 1 /* define if your struct msghdr has msg_control */ #define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 /* define if your struct msghdr has msg_controllen */ #define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 /* define if your struct msghdr has msg_flag */ #define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 /* define if you have struct cmsghdr */ #define HAVE_STRUCT_CMSGHDR 1 /* define if you have struct in_pktinfo */ /* #undef HAVE_STRUCT_IN_PKTINFO */ /* define if your struct ip has ip_hl; otherwise assume ip_vhl */ #define HAVE_STRUCT_IP_IP_HL 1 /* Define if you have the setenv function */ #define HAVE_SETENV 1 /* Define if you have the unsetenv function. not on HP-UX */ #define HAVE_UNSETENV 1 /* Define if you have the flock function */ #define HAVE_FLOCK 1 /* Define if you have the openpty function */ #define HAVE_OPENPTY 1 /* Define if you have the grantpt function */ #define HAVE_GRANTPT 1 /* Define if you have the unlockpt function */ #define HAVE_UNLOCKPT 1 /* Define if you have the ptsname function */ #define HAVE_PTSNAME 1 /* Define if you have the /dev/ptmx pseudo terminal multiplexer */ #define HAVE_DEV_PTMX 1 /* Define if you have the /dev/ptc pseudo terminal multiplexer */ /* #undef HAVE_DEV_PTC */ /* Define if you have the long long type */ #define HAVE_TYPE_LONGLONG 1 /* is socklen_t already typedef'd? */ #define HAVE_TYPE_SOCKLEN 1 /* Define if you have the struct stat64 type */ /* #undef HAVE_TYPE_STAT64 */ /* Define if you have the struct off64_t type */ /* #undef HAVE_TYPE_OFF64 */ /* is sighandler_t already typedef'd? */ /* #undef HAVE_TYPE_SIGHANDLER */ /* is uint8_t already defined? */ #define HAVE_TYPE_UINT8 1 /* is uint16_t already defined? */ #define HAVE_TYPE_UINT16 1 /* is uint32_t already defined? */ #define HAVE_TYPE_UINT32 1 /* is uint64_t already defined? */ #define HAVE_TYPE_UINT64 1 /* Define if you have the printf "Z" modifier */ /* #undef HAVE_FORMAT_Z */ /* Define the shift offset of the CRDLY mask */ #define CRDLY_SHIFT 7 /* Define the shift offset of the TABDLY mask */ #define TABDLY_SHIFT 11 /* Define the shift offset of the CSIZE mask */ #define CSIZE_SHIFT 4 /* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ #define HAVE_HOSTS_ALLOW_TABLE 1 #if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE # define HAVE_HOSTS_DENY_TABLE 1 #else /* # undef HAVE_HOSTS_DENY_TABLE */ #endif /* 1..short, 3..int, 5..long; 2,4,6..unsigned */ #define HAVE_BASIC_SIZE_T 4 /* unsigned int */ #define HAVE_BASIC_MODE_T 4 /* unsigned int */ #define HAVE_BASIC_PID_T 3 /* int */ #define HAVE_BASIC_UID_T 6 /* unsigned long */ #define HAVE_BASIC_GID_T 6 /* unsigned long */ #define HAVE_BASIC_TIME_T 5 /* long */ #define HAVE_BASIC_OFF64_T 0 /* unknown, taking default */ #define HAVE_BASIC_SOCKLEN_T 3 /* int */ #define HAVE_TYPEOF_ST_DEV 6 /* unsigned long */ #define HAVE_TYPEOF_ST_INO 8 /* unsigned long long */ #define HAVE_TYPEOF_ST_NLINK 2 /* unsigned short */ #define HAVE_TYPEOF_ST_SIZE 7 /* long long */ #define HAVE_TYPEOF_ST_BLKSIZE 5 /* long */ #define HAVE_TYPEOF_ST_BLOCKS 7 /* long long */ /* #undef HAVE_TYPEOF_ST64_DEV */ /* #undef HAVE_TYPEOF_ST64_INO */ /* #undef HAVE_TYPEOF_ST64_NLINK */ /* #undef HAVE_TYPEOF_ST64_SIZE */ /* #undef HAVE_TYPEOF_ST64_BLKSIZE */ /* #undef HAVE_TYPEOF_ST64_BLOCKS */ #define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 /* long */ #define HAVE_TYPEOF_RLIM_MAX 6 /* unsigned long */ /* Define if you have the /proc filesystem */ #define HAVE_PROC_DIR 1 /* Define if you have the /proc/$$/fd directories */ #define HAVE_PROC_DIR_FD 1 #define WITH_HELP 1 #define WITH_STDIO 1 #define WITH_FDNUM 1 #define WITH_FILE 1 #define WITH_CREAT 1 #define WITH_GOPEN 1 #define WITH_TERMIOS 1 #define WITH_PIPE 1 #define WITH_UNIX 1 /* #undef WITH_ABSTRACT_UNIXSOCKET */ #define WITH_IP4 1 /* #undef WITH_IP6 */ #define WITH_RAWIP 1 #define WITH_GENERICSOCKET 1 /* #undef WITH_INTERFACE */ #define WITH_TCP 1 #define WITH_UDP 1 /* #undef WITH_SCTP */ #define WITH_LISTEN 1 #define WITH_SOCKS4 1 #define WITH_SOCKS4A 1 #define WITH_PROXY 1 #define WITH_EXEC 1 #define WITH_SYSTEM 1 #define WITH_READLINE 1 /* #undef WITH_TUN */ #define WITH_PTY 1 #define WITH_EXT2 1 #define WITH_OPENSSL 1 #define WITH_STREAMS 1 /* #undef WITH_FIPS */ /* #undef OPENSSL_FIPS */ #define WITH_LIBWRAP 1 #define HAVE_TCPD_H 1 #define HAVE_LIBWRAP 1 #define WITH_SYCLS 1 #define WITH_FILAN 1 #define WITH_RETRY 1 #define WITH_MSGLEVEL 0 #endif /* !defined(__config_h_included) */ socat-1.7.3.1/Config/config.AIX-5-3.h0000644000201000020100000003427111453022151016326 0ustar gerhardgerhard/* config.h. Generated from config.h.in by configure. */ /* source: config.h.in */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __config_h_included #define __config_h_included 1 /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to `int' if doesn't define. */ /* #undef gid_t */ /* Define if your struct stat has st_blksize. */ #define HAVE_ST_BLKSIZE 1 /* Define if your struct stat has st_blocks. */ #define HAVE_ST_BLOCKS 1 /* Define if your struct stat has st_rdev. */ #define HAVE_ST_RDEV 1 /* Define if you have the strftime function. */ #define HAVE_STRFTIME 1 /* Define if you have that is POSIX.1 compatible. */ #define HAVE_SYS_WAIT_H 1 /* Define to `int' if doesn't define. */ /* #undef mode_t */ /* Define to `long' if doesn't define. */ /* #undef off_t */ /* Define to `int' if doesn't define. */ /* #undef pid_t */ /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define to `unsigned' if doesn't define. */ /* #undef size_t */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to `int' if doesn't define. */ /* #undef uid_t */ /* Define if you have the putenv function. */ #define HAVE_PUTENV 1 /* Define if you have the select function. */ #define HAVE_SELECT 1 /* Define if you have the poll function. */ #define HAVE_POLL 1 /* Define if you have the socket function. */ #define HAVE_SOCKET 1 /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define if you have the strerror function. */ #define HAVE_STRERROR 1 /* Define if you have the strstr function. */ #define HAVE_STRSTR 1 /* Define if you have the strtod function. */ #define HAVE_STRTOD 1 /* Define if you have the strtol function. */ #define HAVE_STRTOL 1 /* Define if you have the strtoul function. */ #define HAVE_STRTOUL 1 /* Define if you have the uname function. */ #define HAVE_UNAME 1 /* Define if you have the getpgid function. */ #define HAVE_GETPGID 1 /* Define if you have the getsid function. */ #define HAVE_GETSID 1 /* Define if you have the nanosleep function. */ #define HAVE_NANOSLEEP 1 /* Define if you have the getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define if you have the getipnodebyname function. */ #define HAVE_GETIPNODEBYNAME 1 /* Define if you have the setgroups function. */ #define HAVE_SETGROUPS 1 /* Define if you have the inet_aton function. */ #define HAVE_INET_ATON 1 /* Define if you have the memrchr function. */ /* #undef HAVE_MEMRCHR */ /* Define if you have the if_indextoname function. */ #define HAVE_IF_INDEXTONAME 1 /* Define if you have the sigaction function */ #define HAVE_SIGACTION 1 /* Define if you have the stat64 function */ #define HAVE_STAT64 1 /* Define if you have the fstat64 function */ #define HAVE_FSTAT64 1 /* Define if you have the lstat64 function */ #define HAVE_LSTAT64 1 /* Define if you have the lseek64 function */ #define HAVE_LSEEK64 1 /* Define if you have the truncate64 function */ #define HAVE_TRUNCATE64 1 /* Define if you have the ftruncate64 function */ #define HAVE_FTRUNCATE64 1 /* Define if you have the strtoll function */ #define HAVE_STRTOLL 1 /* Define if you have the hstrerror function */ #define HAVE_HSTRERROR 1 /* Define if you have the inet_ntop function */ #define HAVE_INET_NTOP 1 /* Define if you have the hstrerror prototype */ #define HAVE_PROTOTYPE_HSTRERROR 1 /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define if you have the header file. */ #define HAVE_SYSLOG_H 1 /* Define if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define if you have the header file. */ #define HAVE_PWD_H 1 /* Define if you have the header file. */ #define HAVE_GRP_H 1 /* Define if you have the header file. */ #define HAVE_STDINT_H 1 /* Define if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define if you have the header file. */ #define HAVE_SYS_POLL_H 1 /* Define if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define if you have the header file. */ #define HAVE_NETDB_H 1 /* Define if you have the header file. */ #define HAVE_SYS_UN_H 1 /* Define if you have the header file. */ /* #undef HAVE_PTY_H */ /* Define if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IN_SYSTM_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define if you have the header file. */ #define HAVE_NETINET_IP6_H 1 /* Define if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define if you have the header file. */ #define HAVE_RESOLV_H 1 /* Define if you have the header file. */ #define HAVE_TERMIOS_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define if you have the header file. */ #define HAVE_NET_IF_DL_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_TYPES_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_ERRQUEUE_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_IF_TUN_H */ /* Define if you have the header file. */ /* #undef HAVE_NETPACKET_PACKET_H */ /* Define if you have the header file. */ /* #undef HAVE_NETINET_IF_ETHER_H */ /* Define if you have the header file. */ #define HAVE_SYS_UTSNAME_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_SELECT_H 1 /* Define if you have the header file. (AIX) */ #define HAVE_SYS_FILE_H 1 /* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ /* #undef HAVE_UTIL_H */ /* Define if you have the header file. (FreeBSD: openpty()) */ /* #undef HAVE_LIBUTIL_H */ /* Define if you have the header file. (stream opts on SunOS)*/ #define HAVE_SYS_STROPTS_H 1 /* Define if you have the header file. */ #define HAVE_REGEX_H 1 /* Define if you have the header file. */ /* #undef HAVE_LINUX_FS_H */ /* Define if you have the header file. */ /* #undef HAVE_LINUX_EXT2_FS_H */ /* Define if you have the header file. */ /* #undef HAVE_READLINE_READLINE_H */ /* Define if you have the header file. */ /* #undef HAVE_READLINE_HISTORY_H */ /* Define if you have the readline library. */ /* #undef HAVE_LIBREADLINE */ /* Define if you have the m library (-lm). */ /* #undef HAVE_LIBM */ /* Define if you have the floor function */ /* #undef HAVE_FLOOR */ /* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ /* #undef _XOPEN_EXTENDED_SOURCE */ /* fdset may have component fds_bits or __fds_bits */ #define HAVE_FDS_BITS 1 /* Define if you have the sa_family_t */ #define HAVE_TYPE_SA_FAMILY_T 1 /* define if your struct sigaction has sa_sigaction */ #define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 /* Define if your struct termios has component c_ispeed */ /* #undef HAVE_TERMIOS_ISPEED */ /* the offset of c_ispeed in struct termios - usable in an speed_t array. Applies only when HAVE_TERMIOS_ISPEED is set */ /* #undef ISPEED_OFFSET */ /* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ #ifdef ISPEED_OFFSET # define OSPEED_OFFSET (ISPEED_OFFSET+1) #else /* # undef OSPEED_OFFSET */ #endif /* Define if your termios.h likes _SVID3 defined */ /* #undef _SVID3 */ /* Define if you have struct timespec (e.g. for nanosleep) */ #define HAVE_STRUCT_TIMESPEC 1 /* Define if you have struct linger */ #define HAVE_STRUCT_LINGER 1 /* Define if you have struct ip_mreq */ #define HAVE_STRUCT_IP_MREQ 1 /* Define if you have struct ip_mreqn */ /* #undef HAVE_STRUCT_IP_MREQN */ /* Define if you have struct ipv6_mreq */ #define HAVE_STRUCT_IPV6_MREQ 1 /* Define if you have struct ifreq */ #define HAVE_STRUCT_IFREQ 1 /* Define if you have struct ifreq.ifr_index */ /* #undef HAVE_STRUCT_IFREQ_IFR_INDEX */ /* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ /* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ /* Define if your struct sockaddr has sa_len */ #define HAVE_STRUCT_SOCKADDR_SALEN 1 /* there are several implementations of sockaddr_in6 */ #define HAVE_IP6_SOCKADDR 0 /* Define if you have struct iovec */ #define HAVE_STRUCT_IOVEC 1 /* define if your struct msghdr has msg_control */ #define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 /* define if your struct msghdr has msg_controllen */ #define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 /* define if your struct msghdr has msg_flag */ #define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 /* define if you have struct cmsghdr */ #define HAVE_STRUCT_CMSGHDR 1 /* define if you have struct in_pktinfo */ /* #undef HAVE_STRUCT_IN_PKTINFO */ /* define if your struct ip has ip_hl; otherwise assume ip_vhl */ #define HAVE_STRUCT_IP_IP_HL 1 /* Define if you have the setenv function */ #define HAVE_SETENV 1 /* Define if you have the unsetenv function. not on HP-UX */ #define HAVE_UNSETENV 1 /* Define if you have the flock function */ /* #undef HAVE_FLOCK */ #define HAVE_FLOCK 1 /* Define if you have the openpty function */ /* #undef HAVE_OPENPTY */ /* Define if you have the grantpt function */ #define HAVE_GRANTPT 1 /* Define if you have the unlockpt function */ #define HAVE_UNLOCKPT 1 /* Define if you have the ptsname function */ #define HAVE_PTSNAME 1 /* Define if you have the /dev/ptmx pseudo terminal multiplexer */ /* #undef HAVE_DEV_PTMX */ /* Define if you have the /dev/ptc pseudo terminal multiplexer */ #define HAVE_DEV_PTC 1 /* Define if you have the long long type */ #define HAVE_TYPE_LONGLONG 1 /* is socklen_t already typedef'd? */ #define HAVE_TYPE_SOCKLEN 1 /* Define if you have the struct stat64 type */ #define HAVE_TYPE_STAT64 1 /* Define if you have the struct off64_t type */ #define HAVE_TYPE_OFF64 1 /* is sighandler_t already typedef'd? */ /* #undef HAVE_TYPE_SIGHANDLER */ /* is uint8_t already defined? */ #define HAVE_TYPE_UINT8 1 /* is uint16_t already defined? */ #define HAVE_TYPE_UINT16 1 /* is uint32_t already defined? */ #define HAVE_TYPE_UINT32 1 /* is uint64_t already defined? */ #define HAVE_TYPE_UINT64 1 /* Define if you have the printf "Z" modifier */ /* #undef HAVE_FORMAT_Z */ /* Define the shift offset of the CRDLY mask */ #define CRDLY_SHIFT 8 /* Define the shift offset of the TABDLY mask */ #define TABDLY_SHIFT 10 /* Define the shift offset of the CSIZE mask */ #define CSIZE_SHIFT 4 /* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ /* #undef HAVE_HOSTS_ALLOW_TABLE */ #if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE # define HAVE_HOSTS_DENY_TABLE 1 #else /* # undef HAVE_HOSTS_DENY_TABLE */ #endif /* 1..short, 3..int, 5..long; 2,4,6..unsigned */ #define HAVE_BASIC_SIZE_T 0 /* unknown, taking default */ #define HAVE_BASIC_MODE_T 0 /* unknown, taking default */ #define HAVE_BASIC_PID_T 0 /* unknown, taking default */ #define HAVE_BASIC_UID_T 0 /* unknown, taking default */ #define HAVE_BASIC_GID_T 0 /* unknown, taking default */ #define HAVE_BASIC_TIME_T 0 /* unknown, taking default */ #define HAVE_BASIC_OFF64_T 0 /* unknown, taking default */ #define HAVE_BASIC_SOCKLEN_T 0 /* unknown, taking default */ #define HAVE_TYPEOF_ST_DEV 0 /* unknown, taking default */ #define HAVE_TYPEOF_ST_INO 0 /* unknown, taking default */ #define HAVE_TYPEOF_ST_NLINK 0 /* unknown, taking default */ #define HAVE_TYPEOF_ST_SIZE 0 /* unknown, taking default */ #define HAVE_TYPEOF_ST_BLKSIZE 0 /* unknown, taking default */ #define HAVE_TYPEOF_ST_BLOCKS 0 /* unknown, taking default */ #define HAVE_TYPEOF_ST64_DEV 0 /* unknown, taking default */ #define HAVE_TYPEOF_ST64_INO 0 /* unknown, taking default */ #define HAVE_TYPEOF_ST64_NLINK 0 /* unknown, taking default */ #define HAVE_TYPEOF_ST64_SIZE 0 /* unknown, taking default */ #define HAVE_TYPEOF_ST64_BLKSIZE 0 /* unknown, taking default */ #define HAVE_TYPEOF_ST64_BLOCKS 0 /* unknown, taking default */ #define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 0 /* unknown, taking default */ #define HAVE_TYPEOF_RLIM_MAX 0 /* unknown, taking default */ /* Define if you have the /proc filesystem */ #define HAVE_PROC_DIR 1 /* Define if you have the /proc/$$/fd directories */ #define HAVE_PROC_DIR_FD 1 #define WITH_HELP 1 #define WITH_STDIO 1 #define WITH_FDNUM 1 #define WITH_FILE 1 #define WITH_CREAT 1 #define WITH_GOPEN 1 #define WITH_TERMIOS 1 #define WITH_PIPE 1 #define WITH_UNIX 1 /* #undef WITH_ABSTRACT_UNIXSOCKET */ #define WITH_IP4 1 #define WITH_IP6 1 #define WITH_RAWIP 1 #define WITH_GENERICSOCKET 1 /* #undef WITH_INTERFACE */ #define WITH_TCP 1 #define WITH_UDP 1 #define WITH_SCTP 1 #define WITH_LISTEN 1 #define WITH_SOCKS4 1 #define WITH_SOCKS4A 1 #define WITH_PROXY 1 #define WITH_EXEC 1 #define WITH_SYSTEM 1 /* #undef WITH_READLINE */ /* #undef WITH_TUN */ #define WITH_PTY 1 #define WITH_EXT2 1 #define WITH_OPENSSL 1 #define WITH_STREAMS 1 /* #undef WITH_FIPS */ /* #undef OPENSSL_FIPS */ /* #undef WITH_LIBWRAP */ /* #undef HAVE_TCPD_H */ /* #undef HAVE_LIBWRAP */ #define WITH_SYCLS 1 #define WITH_FILAN 1 #define WITH_RETRY 1 #define WITH_MSGLEVEL 0 #endif /* !defined(__config_h_included) */ socat-1.7.3.1/xio-ip.h0000644000201000020100000000372011453022152014133 0ustar gerhardgerhard/* source: xio-ip.h */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ip_h_included #define __xio_ip_h_included 1 extern const struct optdesc opt_ip_options; extern const struct optdesc opt_ip_pktinfo; extern const struct optdesc opt_ip_recvtos; extern const struct optdesc opt_ip_recvttl; extern const struct optdesc opt_ip_recvopts; extern const struct optdesc opt_ip_retopts; extern const struct optdesc opt_ip_tos; extern const struct optdesc opt_ip_ttl; extern const struct optdesc opt_ip_hdrincl; extern const struct optdesc opt_ip_recverr; extern const struct optdesc opt_ip_mtu_discover; extern const struct optdesc opt_ip_mtu; extern const struct optdesc opt_ip_freebind; extern const struct optdesc opt_ip_router_alert; extern const struct optdesc opt_ip_multicast_ttl; extern const struct optdesc opt_ip_multicast_loop; extern const struct optdesc opt_ip_multicast_if; extern const struct optdesc opt_ip_pktoptions; extern const struct optdesc opt_ip_add_membership; extern const struct optdesc opt_ip_recvdstaddr; extern const struct optdesc opt_ip_recvif; extern const struct optdesc opt_res_debug; extern const struct optdesc opt_res_aaonly; extern const struct optdesc opt_res_usevc; extern const struct optdesc opt_res_primary; extern const struct optdesc opt_res_igntc; extern const struct optdesc opt_res_recurse; extern const struct optdesc opt_res_defnames; extern const struct optdesc opt_res_stayopen; extern const struct optdesc opt_res_dnsrch; extern int xiogetaddrinfo(const char *node, const char *service, int family, int socktype, int protocol, union sockaddr_union *sa, socklen_t *socklen, unsigned long res_opts0, unsigned long res_opts1); extern int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, char *typbuff, int typlen, char *nambuff, int namlen, char *envbuff, int envlen, char *valbuff, int vallen); #endif /* !defined(__xio_ip_h_included) */ socat-1.7.3.1/xio-tcp.h0000644000201000020100000000331411453022152014310 0ustar gerhardgerhard/* source: xio-tcp.h */ /* Copyright Gerhard Rieger 2001-2006 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_tcp_h_included #define __xio_tcp_h_included 1 extern const struct addrdesc addr_tcp_connect; extern const struct addrdesc addr_tcp_listen; extern const struct addrdesc addr_tcp4_connect; extern const struct addrdesc addr_tcp4_listen; extern const struct addrdesc addr_tcp6_connect; extern const struct addrdesc addr_tcp6_listen; extern const struct optdesc opt_tcp_nodelay; extern const struct optdesc opt_tcp_maxseg; extern const struct optdesc opt_tcp_maxseg_late; extern const struct optdesc opt_tcp_cork; extern const struct optdesc opt_tcp_stdurg; extern const struct optdesc opt_tcp_rfc1323; extern const struct optdesc opt_tcp_keepidle; extern const struct optdesc opt_tcp_keepintvl; extern const struct optdesc opt_tcp_keepcnt; extern const struct optdesc opt_tcp_syncnt; extern const struct optdesc opt_tcp_linger2; extern const struct optdesc opt_tcp_defer_accept; extern const struct optdesc opt_tcp_window_clamp; extern const struct optdesc opt_tcp_info; extern const struct optdesc opt_tcp_quickack; extern const struct optdesc opt_tcp_noopt; extern const struct optdesc opt_tcp_nopush; extern const struct optdesc opt_tcp_md5sig; extern const struct optdesc opt_tcp_sack_disable; extern const struct optdesc opt_tcp_signature_enable; extern const struct optdesc opt_tcp_abort_threshold; extern const struct optdesc opt_tcp_conn_abort_threshold; extern const struct optdesc opt_tcp_keepinit; extern const struct optdesc opt_tcp_paws; extern const struct optdesc opt_tcp_sackena; extern const struct optdesc opt_tcp_tsoptena; #endif /* !defined(__xio_tcp_h_included) */ socat-1.7.3.1/VERSION0000644000201000020100000000001212652637420013630 0ustar gerhardgerhard"1.7.3.1" socat-1.7.3.1/xiohelp.c0000644000201000020100000001132712161506654014406 0ustar gerhardgerhard/* source: xiohelp.c */ /* Copyright Gerhard Rieger 2001-2009 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for the help function */ #include "xiosysincludes.h" #include "xioopen.h" #include "xiohelp.h" #if WITH_HELP /* keep consistent with xioopts.h:enum e_types ! */ static const char *optiontypenames[] = { "CONST", "BIN", "BOOL", "BYTE", "INT", "LONG", "STRING", "PTRDIFF", "SHORT", "SIZE_T", "SOCKADDR", "UNSIGNED-INT", "UNSIGNED-LONG","UNSIGNED-SHORT","MODE_T", "GID_T", "UID_T", "INT[3]", "STRUCT-TIMEVAL", "STRUCT-TIMESPEC", "DOUBLE", "STRING-NULL", "LONG-LONG", "OFF_T", "OFF64_T", "INT:INT", "INT:INTP", "INT:BIN", "INT:STRING", "INT:INT:INT", "INT:INT:BIN", "INT:INT:STRING", "IP4NAME", #if HAVE_STRUCT_LINGER "STRUCT-LINGER", #endif #if HAVE_STRUCT_IP_MREQN "STRUCT-IP_MREQN", #elif HAVE_STRUCT_IP_MREQ "STRUCT-IP_MREQ", #endif } ; /* keep consistent with xioopts.h:#define GROUP_* ! */ static const char *addressgroupnames[] = { "FD", "FIFO", "CHR", "BLK", "REG", "SOCKET", "READLINE", "undef", "NAMED", "OPEN", "EXEC", "FORK", "LISTEN", "DEVICE", "CHILD", "RETRY", "TERMIOS", "RANGE", "PTY", "PARENT", "UNIX", "IP4", "IP6", "INTERFACE", "UDP", "TCP", "SOCKS4", "OPENSSL", "PROCESS", "APPL", "HTTP", "SCTP" } ; /* keep consistent with xioopts.h:enum ephase ! */ static char *optionphasenames[] = { "ALL", "INIT", "EARLY", "PREOPEN", "OPEN", "PASTOPEN", "PRESOCKET", "SOCKET", "PASTSOCKET", "PREBIGEN", "BIGEN", "PASTBIGEN", "FD", "PREBIND", "BIND", "PASTBIND", "PRELISTEN", "LISTEN", "PASTLISTEN", "PRECONNECT", "CONNECT", "PASTCONNECT", "PREACCEPT", "ACCEPT", "PASTACCEPT", "CONNECTED", "PREFORK", "FORK", "PASTFORK", "LATE", "LATE2", "PREEXEC", "EXEC", "SPECIFIC", NULL } ; /* print a line about a single option */ static int xiohelp_option(FILE *of, const struct optname *on, const char *name) { int j; unsigned int groups; bool occurred; fprintf(of, " %s\tgroups=", name); groups = on->desc->group; occurred = false; for (j = 0; j < 32; ++j) { if (groups & 1) { if (occurred) { fputc(',', of); } fprintf(of, "%s", addressgroupnames[j]); occurred = true; } groups >>= 1; } fprintf(of, "\tphase=%s", optionphasenames[on->desc->phase]); fprintf(of, "\ttype=%s", optiontypenames[on->desc->type]); fputc('\n', of); return 0; } int xioopenhelp(FILE *of, int level /* 0..only addresses, 1..and options */ ) { const struct addrname *an; const struct optname *on; int i, j; unsigned int groups; bool occurred; fputs(" bi-address:\n", of); fputs(" pipe[,]\tgroups=FD,FIFO\n", of); if (level == 2) { fputs(" echo is an alias for pipe\n", of); fputs(" fifo is an alias for pipe\n", of); } fputs(" !!\n", of); fputs(" \n", of); fputs(" single-address:\n", of); fputs(" [,]\n", of); fputs(" address-head:\n", of); an = &addressnames[0]; i = 0; while (addressnames[i].name) { if (!strcmp(an->name, an->desc->defname)) { /* it is a canonical address name */ fprintf(of, " %s", an->name); if (an->desc->syntax) { fputs(an->desc->syntax, of); } fputs("\tgroups=", of); groups = an->desc->groups; occurred = false; for (j = 0; j < 32; ++j) { if (groups & 1) { if (occurred) { fputc(',', of); } fprintf(of, "%s", addressgroupnames[j]); occurred = true; } groups >>= 1; } fputc('\n', of); } else if (level == 2) { fprintf(of, " %s is an alias name for %s\n", an->name, an->desc->defname); } ++an; ++i; } if (level == 2) { fputs(" is a short form for fd:\n", of); fputs(" is a short form for gopen:\n", of); } if (level <= 0) return 0; fputs(" opts:\n", of); fputs(" {,}:\n", of); fputs(" opt:\n", of); on = optionnames; while (on->name != NULL) { if (on->desc->nickname!= NULL && !strcmp(on->name, on->desc->nickname)) { if (level == 2) { fprintf(of, " %s is an alias for %s\n", on->name, on->desc->defname); } else { xiohelp_option(of, on, on->name); } } else if (on->desc->nickname == NULL && !strcmp(on->name, on->desc->defname)) { xiohelp_option(of, on, on->name); } else if (level == 2) { if (!strcmp(on->name, on->desc->defname)) { xiohelp_option(of, on, on->name); } else { fprintf(of, " %s is an alias for %s\n", on->name, on->desc->defname); } } ++on; } fflush(of); return 0; } #endif /* WITH_HELP */ socat-1.7.3.1/xioinitialize.c0000644000201000020100000001541412161511320015602 0ustar gerhardgerhard/* source: xioinitialize.c */ /* Copyright Gerhard Rieger 2001-2011 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for the initialize function */ #include "xiosysincludes.h" #include "xioopen.h" #include "xiolockfile.h" #include "xio-openssl.h" /* xio_reset_fips_mode() */ static int xioinitialized; xiofile_t *sock[XIO_MAXSOCK]; int (*xiohook_newchild)(void); /* xio calls this function from a new child process */ int num_child = 0; /* returns 0 on success or != if an error occurred */ int xioinitialize(void) { if (xioinitialized) return 0; /* configure and .h's cannot guarantee this */ assert(sizeof(uint8_t)==1); assert(sizeof(uint16_t)==2); assert(sizeof(uint32_t)==4); /* assertions regarding O_ flags - important for XIO_READABLE() etc. */ assert(O_RDONLY==0); assert(O_WRONLY==1); assert(O_RDWR==2); assert(SHUT_RD==0); assert(SHUT_WR==1); assert(SHUT_RDWR==2); /* some assertions about termios */ #if WITH_TERMIOS #if defined(CRDLY) && CRDLY_SHIFT >= 0 assert(3 << opt_crdly.arg3 == CRDLY); #endif #if defined(TABDLY) && TABDLY_SHIFT >= 0 assert(3 << opt_tabdly.arg3 == TABDLY); #endif #if CSIZE_SHIFT >= 0 assert(3 << opt_csize.arg3 == CSIZE); #endif { union { struct termios termarg; tcflag_t flags[4]; #if HAVE_TERMIOS_ISPEED speed_t speeds[sizeof(struct termios)/sizeof(speed_t)]; #endif } tdata; tdata.termarg.c_iflag = 0x12345678; tdata.termarg.c_oflag = 0x23456789; tdata.termarg.c_cflag = 0x3456789a; tdata.termarg.c_lflag = 0x456789ab; assert(tdata.termarg.c_iflag == tdata.flags[0]); assert(tdata.termarg.c_oflag == tdata.flags[1]); assert(tdata.termarg.c_cflag == tdata.flags[2]); assert(tdata.termarg.c_lflag == tdata.flags[3]); #if HAVE_TERMIOS_ISPEED && (ISPEED_OFFSET != -1) && (OSPEED_OFFSET != -1) #if defined(ISPEED_OFFSET) && (ISPEED_OFFSET != -1) #if defined(OSPEED_OFFSET) && (OSPEED_OFFSET != -1) tdata.termarg.c_ispeed = 0x56789abc; tdata.termarg.c_ospeed = 0x6789abcd; assert(tdata.termarg.c_ispeed == tdata.speeds[ISPEED_OFFSET]); assert(tdata.termarg.c_ospeed == tdata.speeds[OSPEED_OFFSET]); #endif #endif #endif } #endif /* these dependencies required in applyopts() for OFUNC_FCNTL */ assert(F_GETFD == F_SETFD-1); assert(F_GETFL == F_SETFL-1); { const char *default_ip; default_ip = getenv("SOCAT_DEFAULT_LISTEN_IP"); if (default_ip != NULL) { switch (default_ip[0]) { case '4': case '6': xioopts.default_ip = default_ip[0]; break; } } } { const char *preferred_ip; preferred_ip = getenv("SOCAT_PREFERRED_RESOLVE_IP"); if (preferred_ip != NULL) { switch (preferred_ip[0]) { case '4': case '6': xioopts.preferred_ip = preferred_ip[0]; break; default: xioopts.preferred_ip = '0'; break; } } } if (Atexit(xioexit) < 0) { Error("atexit(xioexit) failed"); return -1; } xioinitialized = 1; return 0; } /* call this function when option -lp (reset program name) has been applied */ int xioinitialize2(void) { pid_t pid = Getpid(); xiosetenvulong("PID", pid, 1); xiosetenvulong("PPID", pid, 1); return 0; } /* well, this function is not for initialization, but I could not find a better place for it it is called in the child process after fork it drops the locks of the xiofile's so only the parent owns them */ void xiodroplocks(void) { int i; for (i = 0; i < XIO_MAXSOCK; ++i) { if (sock[i] != NULL && sock[i]->tag != XIO_TAG_INVALID) { xiofiledroplock(sock[i]); } } } /* consider an invokation like this: socat -u exec:'some program that accepts data' tcp-l:...,fork we do not want the program to be killed by the first tcp-l sub process, it's better if it survives all sub processes. Thus, it must not be killed when the sub process delivers EOF. Also, a socket that is reused in sub processes should not be shut down (affects the connection), but closed (affects only sub processes copy of file descriptor) */ static int xio_nokill(xiofile_t *sock) { int result = 0; switch (sock->tag) { case XIO_TAG_INVALID: default: return -1; case XIO_TAG_DUAL: if ((result = xio_nokill((xiofile_t *)sock->dual.stream[0])) != 0) return result; result = xio_nokill((xiofile_t *)sock->dual.stream[1]); break; case XIO_TAG_RDONLY: case XIO_TAG_WRONLY: case XIO_TAG_RDWR: /* here is the core of this function */ switch (sock->stream.howtoend) { case END_SHUTDOWN_KILL: sock->stream.howtoend = END_CLOSE; break; case END_CLOSE_KILL: sock->stream.howtoend = END_CLOSE; break; case END_SHUTDOWN: sock->stream.howtoend = END_CLOSE; break; default: break; } break; } return result; } /* call this function immediately after fork() in child process */ /* it performs some neccessary actions returns 0 on success or != 0 if an error occurred */ int xio_forked_inchild(void) { int result = 0; int i; for (i=0; i/]") }; /* "if-name"=tun3 // "route"=address/netmask // "ip6-route"=address/netmask // "iff-broadcast" // "iff-debug" // "iff-promisc" // see .../linux/if.h */ #if LATER /* sub options for route option */ #define IFOPT_ROUTE 1 static const struct optdesc opt_route_tos = { "route", NULL, IFOPT_ROUTE, }; static const struct optname xio_route_options[] = { {"tos", &xio_route_tos } } ; #endif static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3) { char *tundevice = NULL; char *tunname = NULL, *tuntype = NULL; int pf = /*! PF_UNSPEC*/ PF_INET; struct xiorange network; bool no_pi = false; const char *namedargv[] = { "tun", NULL, NULL }; int rw = (xioflags & XIO_ACCMODE); bool exists; struct ifreq ifr; int sockfd; char *ifaddr; int result; if (argc > 2 || argc < 0) { Error2("%s: wrong number of parameters (%d instead of 0 or 1)", argv[0], argc-1); } if (retropt_string(opts, OPT_TUN_DEVICE, &tundevice) != 0) { tundevice = strdup("/dev/net/tun"); } /*! socket option here? */ retropt_socket_pf(opts, &pf); namedargv[1] = tundevice; /* open the tun cloning device */ if ((result = _xioopen_named_early(2, namedargv, xfd, groups, &exists, opts)) < 0) { return result; } /*========================= the tunnel interface =========================*/ Notice("creating tunnel network interface"); if ((result = _xioopen_open(tundevice, rw, opts)) < 0) return result; xfd->stream.fd = result; /* prepare configuration of the new network interface */ memset(&ifr, 0,sizeof(ifr)); if (retropt_string(opts, OPT_TUN_NAME, &tunname) == 0) { strncpy(ifr.ifr_name, tunname, IFNAMSIZ); /* ok */ free(tunname); } else { ifr.ifr_name[0] = '\0'; } ifr.ifr_flags = IFF_TUN; if (retropt_string(opts, OPT_TUN_TYPE, &tuntype) == 0) { if (!strcmp(tuntype, "tap")) { ifr.ifr_flags = IFF_TAP; } else if (strcmp(tuntype, "tun")) { Error1("unknown tun-type \"%s\"", tuntype); } } if (retropt_bool(opts, OPT_IFF_NO_PI, &no_pi) == 0) { if (no_pi) { ifr.ifr_flags |= IFF_NO_PI; #if 0 /* not neccessary for now */ } else { ifr.ifr_flags &= ~IFF_NO_PI; #endif } } if (Ioctl(xfd->stream.fd, TUNSETIFF, &ifr) < 0) { Error3("ioctl(%d, TUNSETIFF, {\"%s\"}: %s", xfd->stream.fd, ifr.ifr_name, strerror(errno)); Close(xfd->stream.fd); } /*===================== setting interface properties =====================*/ /* we seem to need a socket for manipulating the interface */ if ((sockfd = Socket(PF_INET, SOCK_DGRAM, 0)) < 0) { Error1("socket(PF_INET, SOCK_DGRAM, 0): %s", strerror(errno)); sockfd = xfd->stream.fd; /* desparate fallback attempt */ } /*--------------------- setting interface address and netmask ------------*/ if (argc == 2) { if ((ifaddr = strdup(argv[1])) == NULL) { Error1("strdup(\"%s\"): out of memory", argv[1]); return STAT_RETRYLATER; } if ((result = xioparsenetwork(ifaddr, pf, &network)) != STAT_OK) { /*! recover */ return result; } socket_init(pf, (union sockaddr_union *)&ifr.ifr_addr); ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr = network.netaddr.ip4.sin_addr; if (Ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) { Error4("ioctl(%d, SIOCSIFADDR, {\"%s\", \"%s\"}: %s", sockfd, ifr.ifr_name, ifaddr, strerror(errno)); } ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr = network.netmask.ip4.sin_addr; if (Ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) { Error4("ioctl(%d, SIOCSIFNETMASK, {\"0x%08u\", \"%s\"}, %s", sockfd, ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr, ifaddr, strerror(errno)); } free(ifaddr); } /*--------------------- setting interface flags --------------------------*/ applyopts_single(&xfd->stream, opts, PH_FD); if (Ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { Error3("ioctl(%d, SIOCGIFFLAGS, {\"%s\"}: %s", sockfd, ifr.ifr_name, strerror(errno)); } Debug2("\"%s\": system set flags: 0x%hx", ifr.ifr_name, ifr.ifr_flags); ifr.ifr_flags |= xfd->stream.para.tun.iff_opts[0]; ifr.ifr_flags &= ~xfd->stream.para.tun.iff_opts[1]; Debug2("\"%s\": xio merged flags: 0x%hx", ifr.ifr_name, ifr.ifr_flags); if (Ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) { Error4("ioctl(%d, SIOCSIFFLAGS, {\"%s\", %hd}: %s", sockfd, ifr.ifr_name, ifr.ifr_flags, strerror(errno)); } ifr.ifr_flags = 0; if (Ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { Error3("ioctl(%d, SIOCGIFFLAGS, {\"%s\"}: %s", sockfd, ifr.ifr_name, strerror(errno)); } Debug2("\"%s\": resulting flags: 0x%hx", ifr.ifr_name, ifr.ifr_flags); #if LATER applyopts_named(tundevice, opts, PH_FD); #endif applyopts(xfd->stream.fd, opts, PH_FD); applyopts_cloexec(xfd->stream.fd, opts); applyopts_fchown(xfd->stream.fd, opts); if ((result = _xio_openlate(&xfd->stream, opts)) < 0) return result; return 0; } #endif /* WITH_TUN */ socat-1.7.3.1/SECURITY0000644000201000020100000000347107546750417013776 0ustar gerhardgerhard Tips for using socat in secured environments: * Configure socat to only enable the required features, e.g. to protect your filesystem from any accesses through socat: make distclean ./configure --disable-file --disable-creat --disable-gopen \ --disable-pipe --disable-unix --disable-exec --disable-system use "socat -V" to see what features are still enabled; see ./configure --help for more options to disable * Do NOT install socat SUID root or so when you have untrusted users or unprivileged daemons on your machine, because the full install of socat can override arbitrary files and execute arbitrary programs! * Set logging to "-d -d" (in special cases even higher) * With files, protect against symlink attacks with nofollow (Linux), and avoid accessing files in world-writable directories like /tmp * When listening, use bind option (except UNIX domain sockets) * When listening, use range option (currently only for IP4 sockets) * When using socat with system, exec, or in a shell script, know what you do * With system and exec, use absolute pathes or set the path option * When starting programs with socat, consider using the chroot option (this requires root, so use the substuser option too). * Start socat as root only if required; if so, use substuser option Note: starting a SUID program after applying substuser or setuid gives the process the SUID owner, which might give root privileges again. * Socat, like netcat, is what intruders like to have on their victims machine: once they have gained a toehold they try to establish a versatile connection back to their attack base, and they want to attack other systems. For both purposes, socat could be helpful. Therefore, it might be useful to install socat with owner/permissions root:socatgrp/750, and to make all trusted users members of group socatgrp. socat-1.7.3.1/xio-rawip.c0000644000201000020100000002524511453022152014646 0ustar gerhardgerhard/* source: xio-rawip.c */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of raw IP type */ #include "xiosysincludes.h" #if (WITH_IP4 || WITH_IP6) && WITH_RAWIP #include "xioopen.h" #include "xio-socket.h" #include "xio-ip.h" #include "xio-ip6.h" #include "xio-tcpwrap.h" #include "xio-rawip.h" static int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned 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, unsigned 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, unsigned 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, unsigned groups, int pf, int socktype, int ipproto); static int _xioopen_rawip_sendto(const char *hostname, const char *protname, struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int *pf); const struct addrdesc addr_rawip_sendto = { "ip-sendto", 3, xioopen_rawip_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6, PF_UNSPEC, 0, 0 HELP("::") }; const struct addrdesc addr_rawip_datagram= { "ip-datagram", 3, xioopen_rawip_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_RANGE, PF_UNSPEC, 0, 0 HELP("::") }; const struct addrdesc addr_rawip_recvfrom= { "ip-recvfrom", 3, xioopen_rawip_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_CHILD|GROUP_RANGE, PF_UNSPEC, SOCK_RAW, 0 HELP(":") }; const struct addrdesc addr_rawip_recv = { "ip-recv", 1, xioopen_rawip_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_RANGE, PF_UNSPEC, SOCK_RAW, 0 HELP(":") }; #if WITH_IP4 const struct addrdesc addr_rawip4_sendto = { "ip4-sendto", 3, xioopen_rawip_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4, PF_INET, 0, 0 HELP("::") }; const struct addrdesc addr_rawip4_datagram= { "ip4-datagram", 3, xioopen_rawip_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_RANGE, PF_INET, 0, 0 HELP("::") }; const struct addrdesc addr_rawip4_recvfrom= { "ip4-recvfrom", 3, xioopen_rawip_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_CHILD|GROUP_RANGE, PF_INET, SOCK_RAW, 0 HELP(":") }; const struct addrdesc addr_rawip4_recv = { "ip4-recv", 1, xioopen_rawip_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_RANGE, PF_INET, SOCK_RAW, 0 HELP(":") }; #endif #if WITH_IP6 const struct addrdesc addr_rawip6_sendto = { "ip6-sendto", 3, xioopen_rawip_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6, PF_INET6, 0, 0 HELP("::") }; const struct addrdesc addr_rawip6_datagram= { "ip6-datagram", 3, xioopen_rawip_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_RANGE, PF_INET6, 0, 0 HELP("::") }; const struct addrdesc addr_rawip6_recvfrom= { "ip6-recvfrom", 3, xioopen_rawip_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_CHILD|GROUP_RANGE, PF_INET6, SOCK_RAW, 0 HELP(":") }; const struct addrdesc addr_rawip6_recv = { "ip6-recv", 1, xioopen_rawip_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_RANGE, PF_INET6, SOCK_RAW, 0 HELP(":") }; #endif /* 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, unsigned groups, int pf, int dummy2, int dummy3) { int result; if (argc != 3) { Error2("%s: wrong number of parameters (%d instead of 2)", argv[0], argc-1); return STAT_NORETRY; } if ((result = _xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd, groups, &pf)) != STAT_OK) { return result; } _xio_openlate(&xxfd->stream, opts); return STAT_OK; } /* applies and consumes the following options: PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE OFUNC_OFFSET OPT_PROTOCOL_FAMILY, OPT_BIND, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC */ static int _xioopen_rawip_sendto(const char *hostname, const char *protname, struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int *pf) { char *garbage; xiosingle_t *xfd = &xxfd->stream; union sockaddr_union us; socklen_t uslen; int feats = 1; /* option bind supports only address, not port */ int socktype = SOCK_RAW; int ipproto; bool needbind = false; int result; if ((ipproto = strtoul(protname, &garbage, 0)) >= 256) { Error3("xioopen_rawip_sendto(\"%s:%s\",,): protocol number exceeds 255 (%u)", hostname, protname, ipproto); return STAT_NORETRY; } else if (*garbage) { Warn2("xioopen_rawip_sendto(\"%s:%s\",,): trailing garbage in protocol specification", hostname, protname); /*return STAT_NORETRY;*/ } xfd->howtoend = END_SHUTDOWN; retropt_int(opts, OPT_PROTOCOL_FAMILY, pf); /* ...res_opts[] */ if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); xfd->salen = sizeof(xfd->peersa); if ((result = xiogetaddrinfo(hostname, NULL, *pf, socktype, ipproto, &xfd->peersa, &xfd->salen, xfd->para.socket.ip.res_opts[0], xfd->para.socket.ip.res_opts[1])) != STAT_OK) { return result; } if (*pf == PF_UNSPEC) { *pf = xfd->peersa.soa.sa_family; } uslen = socket_init(*pf, &us); xfd->dtype = XIODATA_RECVFROM_SKIPIP; if (retropt_bind(opts, *pf, socktype, ipproto, &us.soa, &uslen, feats, xfd->para.socket.ip.res_opts[0], xfd->para.socket.ip.res_opts[1]) != STAT_NOACTION) { needbind = true; } return _xioopen_dgram_sendto(needbind?&us:NULL, uslen, opts, xioflags, xfd, groups, *pf, socktype, ipproto); } /* we expect the form: address:protocol */ static int xioopen_rawip_datagram(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int pf, int dummy2, int dummy3) { xiosingle_t *xfd = &xxfd->stream; char *rangename; int result; if (argc != 3) { Error2("%s: wrong number of parameters (%d instead of 2)", argv[0], argc-1); return STAT_NORETRY; } if ((result = _xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd, groups, &pf)) != STAT_OK) { return result; } xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; if (pf == PF_INET) { xfd->dtype |= XIOREAD_RECV_SKIPIP; } xfd->para.socket.la.soa.sa_family = xfd->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) < 0) { free(rangename); return STAT_NORETRY; } xfd->para.socket.dorange = true; xfd->dtype |= XIOREAD_RECV_CHECKRANGE; free(rangename); } #if WITH_LIBWRAP xio_retropt_tcpwrap(xfd, opts); #endif /* WITH_LIBWRAP */ _xio_openlate(xfd, opts); return STAT_OK; } static int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int pf, int socktype, int dummy3) { const char *protname = argv[1]; char *garbage; union sockaddr_union us; socklen_t uslen = sizeof(us); int ipproto; bool needbind = false; int result; if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); return STAT_NORETRY; } if ((ipproto = strtoul(protname, &garbage, 0)) >= 256) { Error2("xioopen_rawip_recvfrom(\"%s\",,): protocol number exceeds 255 (%u)", protname, ipproto); return STAT_NORETRY; } else if (*garbage) { Warn1("xioopen_rawip_recvfrom(\"%s\",,): trailing garbage in protocol specification", protname); /*return STAT_NORETRY;*/ } xfd->stream.howtoend = END_NONE; retropt_socket_pf(opts, &pf); if (pf == PF_UNSPEC) { #if WITH_IP4 && WITH_IP6 pf = xioopts.default_ip=='6'?PF_INET6:PF_INET; #elif WITH_IP6 pf = PF_INET6; #else pf = PF_INET; #endif } if (retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, 1, xfd->stream.para.socket.ip.res_opts[0], xfd->stream.para.socket.ip.res_opts[1]) != STAT_NOACTION) { needbind = true; } xfd->stream.dtype = XIODATA_RECVFROM_SKIPIP_ONE; if ((result = _xioopen_dgram_recvfrom(&xfd->stream, xioflags, needbind?&us.soa:NULL, uslen, opts, pf, socktype, ipproto, E_ERROR)) != STAT_OK) { return result; } _xio_openlate(&xfd->stream, opts); return STAT_OK; } static int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int pf, int socktype, int dummy3) { const char *protname = argv[1]; char *garbage; bool needbind = false; union sockaddr_union us; socklen_t uslen = sizeof(us); int ipproto; int result; if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); return STAT_NORETRY; } if ((ipproto = strtoul(protname, &garbage, 0)) >= 256) { Error2("xioopen_rawip_recv(\"%s\",,): protocol number exceeds 255 (%u)", protname, ipproto); return STAT_NORETRY; } else if (*garbage) { Warn1("xioopen_rawip_recv(\"%s\",,): trailing garbage in protocol specification", protname); /*return STAT_NORETRY;*/ } retropt_socket_pf(opts, &pf); if (pf == PF_UNSPEC) { #if WITH_IP4 && WITH_IP6 pf = xioopts.default_ip=='6'?PF_INET6:PF_INET; #elif WITH_IP6 pf = PF_INET6; #else pf = PF_INET; #endif } if (retropt_bind(opts, pf, socktype, ipproto, &/*us.soa*/xfd->stream.para.socket.la.soa, &uslen, 1, xfd->stream.para.socket.ip.res_opts[0], xfd->stream.para.socket.ip.res_opts[1]) == STAT_OK) { needbind = true; } else { /* pf is required during xioread checks */ xfd->stream.para.socket.la.soa.sa_family = pf; } xfd->stream.dtype = XIODATA_RECV_SKIPIP; result = _xioopen_dgram_recv(&xfd->stream, xioflags, needbind?&/*us.soa*/xfd->stream.para.socket.la.soa:NULL, uslen, opts, pf, socktype, ipproto, E_ERROR); _xio_openlate(&xfd->stream, opts); return result; } #endif /* (WITH_IP4 || WITH_IP6) && WITH_RAWIP */ socat-1.7.3.1/xio-named.c0000644000201000020100000001536612455415361014626 0ustar gerhardgerhard/* source: xio-named.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for filesystem entry functions */ #include "xiosysincludes.h" #if _WITH_NAMED #include "xioopen.h" #include "xio-named.h" #if WITH_NAMED const struct optdesc opt_group_early = { "group-early", NULL, OPT_GROUP_EARLY, GROUP_NAMED, PH_PREOPEN, TYPE_GIDT, OFUNC_SPEC }; const struct optdesc opt_perm_early = { "perm-early", NULL, OPT_PERM_EARLY, GROUP_NAMED, PH_PREOPEN, TYPE_MODET,OFUNC_SPEC }; const struct optdesc opt_user_early = { "user-early", NULL, OPT_USER_EARLY, GROUP_NAMED, PH_PREOPEN, TYPE_UIDT, OFUNC_SPEC }; /*0 const struct optdesc opt_force = { "force", NULL, OPT_FORCE, GROUP_NAMED, PH_???, TYPE_BOOL, OFUNC_SPEC };*/ const struct optdesc opt_unlink = { "unlink", NULL, OPT_UNLINK, GROUP_NAMED, PH_PREOPEN, TYPE_BOOL, OFUNC_SPEC }; const struct optdesc opt_unlink_early= { "unlink-early",NULL, OPT_UNLINK_EARLY,GROUP_NAMED, PH_EARLY, TYPE_BOOL, OFUNC_SPEC }; const struct optdesc opt_unlink_late = { "unlink-late", NULL, OPT_UNLINK_LATE, GROUP_NAMED, PH_PASTOPEN, TYPE_BOOL, OFUNC_SPEC }; const struct optdesc opt_unlink_close = { "unlink-close", NULL, OPT_UNLINK_CLOSE, GROUP_NAMED, PH_LATE, TYPE_BOOL, OFUNC_SPEC }; const struct optdesc opt_umask = { "umask", NULL, OPT_UMASK, GROUP_NAMED, PH_EARLY, TYPE_MODET, OFUNC_SPEC }; #endif /* WITH_NAMED */ /* applies to filesystem entry all options belonging to phase */ int applyopts_named(const char *filename, struct opt *opts, unsigned int phase) { struct opt *opt; if (!opts) return 0; opt = opts; while (opt->desc != ODESC_END) { if (opt->desc == ODESC_DONE || opt->desc->phase != phase && phase != PH_ALL || !(opt->desc->group & GROUP_NAMED)) { ++opt; continue; } switch (opt->desc->optcode) { case OPT_GROUP_EARLY: case OPT_GROUP: if (Chown(filename, -1, opt->value.u_gidt) < 0) { Error3("chown(\"%s\", -1, "F_gid"): %s", filename, opt->value.u_gidt, strerror(errno)); } break; case OPT_USER_EARLY: case OPT_USER: if (Chown(filename, opt->value.u_uidt, -1) < 0) { Error3("chown(\"%s\", "F_uid", -1): %s", filename, opt->value.u_uidt, strerror(errno)); } break; case OPT_PERM_EARLY: case OPT_PERM: if (Chmod(filename, opt->value.u_modet) < 0) { Error3("chmod(\"%s\", "F_mode"): %s", filename, opt->value.u_modet, strerror(errno)); } break; case OPT_UNLINK_EARLY: case OPT_UNLINK: case OPT_UNLINK_LATE: if (Unlink(filename) < 0) { if (errno == ENOENT) { Warn2("unlink(\"%s\"): %s", filename, strerror(errno)); } else { Error2("unlink(\"%s\"): %s", filename, strerror(errno)); } } break; case OPT_UMASK: if (Umask(opt->value.u_modet) < 0) { /* linux docu says it always succeeds, but who believes it? */ Error2("umask("F_mode"): %s", opt->value.u_modet, strerror(errno)); } break; default: Error1("applyopts_named(): option \"%s\" not implemented", opt->desc->defname); break; } opt->desc = ODESC_DONE; ++opt; } return 0; } /* perform actions that are common to all NAMED group addresses: checking if the entry exists, parsing options, ev.removing old filesystem entry or setting early owners and permissions. It applies options of PH_EARLY and PH_PREOPEN. 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, int groups, bool *exists, struct opt *opts) { const char *path = argv[1]; #if HAVE_STAT64 struct stat64 statbuf; #else struct stat statbuf; #endif /* !HAVE_STAT64 */ bool opt_unlink_early = false; if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0]?argv[0]:"", argc); } statbuf.st_mode = 0; /* find the appropriate groupbits */ if ( #if HAVE_STAT64 Stat64(path, &statbuf) < 0 #else Stat(path, &statbuf) < 0 #endif /* !HAVE_STAT64 */ ) { if (errno != ENOENT) { Error2("stat(\"%s\"): %s", path, strerror(errno)); return STAT_RETRYLATER; } *exists = false; } else { *exists = true; } if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); if (*exists && opt_unlink_early) { Info1("\"%s\" already exists; removing it", path); if (Unlink(path) < 0) { Error2("unlink(\"%s\"): %s", path, strerror(errno)); } else { *exists = false; } } applyopts_named(path, opts, PH_EARLY); applyopts(-1, opts, PH_EARLY); if (*exists) { applyopts_named(path, opts, PH_PREOPEN); } else { dropopts(opts, PH_PREOPEN); } return statbuf.st_mode; } /* retrieve the OPEN group options and perform the open() call. returns the file descriptor or a negative value. Applies options of phases PREOPEN, OPEN, PASTOPEN, and FD */ int _xioopen_open(const char *path, int rw, struct opt *opts) { mode_t mode = 0666; flags_t flags = rw; bool flag; int fd; applyopts_named(path, opts, PH_PREOPEN); /* this only applies pure OPEN flags, not mixed OPEN/FCNTL options */ applyopts_flags(opts, GROUP_OPEN, &flags); /* we have to handle mixed OPEN/FCNTL flags specially */ if (retropt_bool(opts, OPT_O_APPEND, &flag) >= 0 && flag) flags |= O_APPEND; if (retropt_bool(opts, OPT_O_NONBLOCK, &flag) >= 0 && flag) flags |= O_NONBLOCK; #ifdef O_ASYNC if (retropt_bool(opts, OPT_O_ASYNC, &flag) >= 0 && flag) flags |= O_ASYNC; #endif if (retropt_bool(opts, OPT_O_TRUNC, &flag) >= 0 && flag) flags |= O_TRUNC; #ifdef O_BINARY if (retropt_bool(opts, OPT_O_BINARY, &flag) >= 0 && flag) flags |= O_BINARY; #endif #ifdef O_TEXT if (retropt_bool(opts, OPT_O_TEXT, &flag) >= 0 && flag) flags |= O_TEXT; #endif #ifdef O_NOINHERIT if (retropt_bool(opts, OPT_O_NOINHERIT, &flag) >= 0 && flag) flags |= O_NOINHERIT; #endif #ifdef O_NOATIME if (retropt_bool(opts, OPT_O_NOATIME, &flag) >= 0 && flag) flags |= O_NOATIME; #endif retropt_modet(opts, OPT_PERM, &mode); if ((fd = Open(path, flags, mode)) < 0) { Error4("open(\"%s\", 0%lo, 0%03o): %s", path, flags, mode, strerror(errno)); return STAT_RETRYLATER; } /*0 Info4("open(\"%s\", 0%o, 0%03o) -> %d", path, flags, mode, fd);*/ applyopts_named(path, opts, PH_PASTOPEN); #if 0 applyopts_named(path, opts, PH_FD); applyopts(fd, opts, PH_FD); applyopts_cloexec(fd, opts); #endif return fd; } #endif /* _WITH_NAMED */ socat-1.7.3.1/readline-test.sh0000755000201000020100000000234411453022152015655 0ustar gerhardgerhard#! /bin/bash # source: readline-test.sh # Copyright Gerhard Rieger 2003-2008 # Published under the GNU General Public License V.2, see file COPYING # script that simulates a simple program with authentication. # is just for testing the readline features # perform the test with something like: # ./socat readline,history=$HOME/.history,noecho='^Password: ' system:./readline-test.sh,pty,setsid,ctty,stderr,sigint,sigquit,echo=0,raw BANNER='readline feature test program' USERPROMPT='Authentication required\nUsername: ' PWDPROMPT='Password: ' PROMPT='prog> ' # degenerated user database CREDUSER="user" CREDPASS="password" if [ $(echo "x\c") = "x" ]; then ECHO="echo" elif [ $(echo -e "x\c") = "x" ]; then ECHO="echo -e" fi #trap "$ECHO $0 got SIGINT" INT trap "$ECHO $0 got SIGINT" INT trap "$ECHO $0 got SIGQUIT" QUIT # print banner $ECHO "$BANNER" # on (some) ksh read -p does not mean prompt $ECHO "$USERPROMPT\c"; read -r USERNAME $ECHO "$PWDPROMPT\c"; read -rs PASSWORD $ECHO if [ "$USERNAME" != "$CREDUSER" -o "$PASSWORD" != "$CREDPASS" ]; then $ECHO "Authentication failed" >&2 exit -1 fi while $ECHO "$PROMPT\c"; read -r COMMAND; do if [ "$COMMAND" = "exit" ]; then break; fi $ECHO "executing $COMMAND" done socat-1.7.3.1/xio-process.h0000644000201000020100000000262512455415361015217 0ustar gerhardgerhard/* source: xio-process.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_process_h_included #define __xio_process_h_included 1 extern const struct optdesc opt_setgid_early; extern const struct optdesc opt_setgid; extern const struct optdesc opt_setuid_early; extern const struct optdesc opt_setuid; extern const struct optdesc opt_substuser_early; extern const struct optdesc opt_substuser; #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT) extern const struct optdesc opt_substuser_delayed; #endif extern const struct optdesc opt_chroot_early; extern const struct optdesc opt_chroot; extern const struct optdesc opt_setsid; extern const struct optdesc opt_setpgid; /* for option substuser-delayed, save info for later application */ extern bool delayeduser; extern uid_t delayeduser_uid; /* numeric user id to switch to */ extern gid_t delayeduser_gid; /* numeric group id to switch to */ extern gid_t delayeduser_gids[NGROUPS]; /* num.supplementary group ids */ extern int delayeduser_ngids; /* number of suppl. gids */ extern char *delayeduser_name; /* name of user to switch to */ extern char *delayeduser_dir; /* home directory of user to switch to */ extern char *delayeduser_shell; /* login shell of user to switch to */ extern int _xioopen_setdelayeduser(void); #endif /* !defined(__xio_process_h_included) */ socat-1.7.3.1/xiowrite.c0000644000201000020100000000751612455415362014616 0ustar gerhardgerhard/* source: xiowrite.c */ /* Copyright Gerhard Rieger 2001-2011 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source of the extended write function */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-readline.h" #include "xio-openssl.h" /* ... note that the write() call can block even if the select()/poll() call reported the FD writeable: in case the FD is not nonblocking and a lock defers the operation. on return value < 0: errno reflects the value from write() */ ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) { ssize_t writt; struct single *pipe; int _errno; if (file->tag == XIO_TAG_INVALID) { Error1("xiowrite(): invalid xiofile descriptor %p", file); errno = EINVAL; return -1; } if (file->tag == XIO_TAG_DUAL) { pipe = file->dual.stream[1]; if (pipe->tag == XIO_TAG_INVALID) { Error1("xiowrite(): invalid xiofile sub descriptor %p[1]", file); errno = EINVAL; return -1; } } else { pipe = &file->stream; } #if WITH_READLINE /* try to extract a prompt from the write data */ if ((pipe->dtype & XIODATA_READMASK) == XIOREAD_READLINE) { xioscan_readline(pipe, buff, bytes); } #endif /* WITH_READLINE */ switch (pipe->dtype & XIODATA_WRITEMASK) { case XIOWRITE_STREAM: writt = writefull(pipe->fd, buff, bytes); if (writt < 0) { _errno = errno; switch (_errno) { case EPIPE: case ECONNRESET: if (pipe->cool_write) { Notice4("write(%d, %p, "F_Zu"): %s", pipe->fd, buff, bytes, strerror(_errno)); break; } /*PASSTRHOUGH*/ default: Error4("write(%d, %p, "F_Zu"): %s", pipe->fd, buff, bytes, strerror(_errno)); } errno = _errno; return -1; } break; #if _WITH_SOCKET case XIOWRITE_SENDTO: /*union { char space[sizeof(struct sockaddr_un)]; struct sockaddr sa; } from;*/ /*socklen_t fromlen;*/ do { writt = Sendto(pipe->fd, buff, bytes, 0, &pipe->peersa.soa, pipe->salen); } while (writt < 0 && errno == EINTR); if (writt < 0) { char infobuff[256]; _errno = errno; Error6("sendto(%d, %p, "F_Zu", 0, %s, "F_socklen"): %s", pipe->fd, buff, bytes, sockaddr_info(&pipe->peersa.soa, pipe->salen, infobuff, sizeof(infobuff)), pipe->salen, strerror(_errno)); errno = _errno; return -1; } if ((size_t)writt < bytes) { char infobuff[256]; Warn7("sendto(%d, %p, "F_Zu", 0, %s, "F_socklen") only wrote "F_Zu" of "F_Zu" bytes", pipe->fd, buff, bytes, sockaddr_info(&pipe->peersa.soa, pipe->salen, infobuff, sizeof(infobuff)), pipe->salen, writt, bytes); } else { } { char infobuff[256]; union sockaddr_union us; socklen_t uslen = sizeof(us); Getsockname(pipe->fd, &us.soa, &uslen); Notice1("local address: %s", sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff))); } break; #endif /* _WITH_SOCKET */ case XIOWRITE_PIPE: writt = Write(pipe->para.bipipe.fdout, buff, bytes); _errno = errno; if (writt < 0) { Error4("write(%d, %p, "F_Zu"): %s", pipe->para.bipipe.fdout, buff, bytes, strerror(_errno)); errno = _errno; return -1; } break; case XIOWRITE_2PIPE: writt = Write(pipe->para.exec.fdout, buff, bytes); _errno = errno; if (writt < 0) { Error4("write(%d, %p, "F_Zu"): %s", pipe->para.exec.fdout, buff, bytes, strerror(_errno)); errno = _errno; return -1; } break; #if WITH_OPENSSL case XIOWRITE_OPENSSL: /* this function prints its own error messages */ return xiowrite_openssl(pipe, buff, bytes); #endif /* WITH_OPENSSL */ default: Error1("xiowrite(): bad data type specification %d", pipe->dtype); errno = EINVAL; return -1; } return writt; } socat-1.7.3.1/socat.spec0000644000201000020100000000252412652637420014557 0ustar gerhardgerhard %define majorver 1.7 %define minorver 3.1 Summary: socat - multipurpose relay Name: socat Version: %{majorver}.%{minorver} Release: 1 License: GPL Group: Applications/Communications Source0: http://www.dest-unreach.org/socat/download/socat-%{version}.tar.bz2 Requires: readline Requires: openssl BuildRoot: /var/tmp/%{name}-buildroot %description socat is a relay for bidirectional data transfer between two independent data channels. Each of these data channels may be a file, pipe, device (terminal or modem etc.), socket (UNIX, IP4, IP6 - raw, UDP, TCP), a file descriptor (stdin etc.), a program, or an arbitrary combination of two of these. %prep %setup -n %{name}-%{version} %build # the CPPFLAGS setting is required for RedHat Linux if [ -d /usr/kerberos/include ]; then CPPFLAGS="-I/usr/kerberos/include" ./configure --prefix=%{_prefix} --mandir=%{_mandir} else ./configure --prefix=%{_prefix} --mandir=%{_mandir} fi make %install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT%{_bindir} mkdir -p $RPM_BUILD_ROOT%{_mandir}/man1 make install DESTDIR=$RPM_BUILD_ROOT %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %doc README CHANGES EXAMPLES SECURITY doc/xio.help doc/socat.html FAQ BUGREPORTS %doc COPYING COPYING.OpenSSL FILES PORTING DEVELOPMENT %{_bindir}/socat %{_bindir}/procan %{_bindir}/filan %{_mandir}/man1/socat.1* socat-1.7.3.1/procan-cdefs.c0000644000201000020100000001025612455415361015302 0ustar gerhardgerhard/* source: procan-cdefs.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* a function that prints compile time parameters */ /* the set of parameters is only a small subset of the available defines and will be extended on demand */ #include "xiosysincludes.h" #include "mytypes.h" #include "compat.h" #include "error.h" #include "procan.h" int procan_cdefs(FILE *outfile) { /* basic C/system constants */ #ifdef FD_SETSIZE fprintf(outfile, "#define FD_SETSIZE %u\n", FD_SETSIZE); #endif #ifdef NFDBITS fprintf(outfile, "#define NFDBITS %d\n", (int)NFDBITS); #endif #ifdef O_RDONLY fprintf(outfile, "#define O_RDONLY %u\n", O_RDONLY); #endif #ifdef O_WRONLY fprintf(outfile, "#define O_WRONLY %u\n", O_WRONLY); #endif #ifdef O_RDWR fprintf(outfile, "#define O_RDWR %u\n", O_RDWR); #endif #ifdef SHUT_RD fprintf(outfile, "#define SHUT_RD %u\n", SHUT_RD); #endif #ifdef SHUT_WR fprintf(outfile, "#define SHUT_WR %u\n", SHUT_WR); #endif #ifdef SHUT_RDWR fprintf(outfile, "#define SHUT_RDWR %u\n", SHUT_RDWR); #endif /* termios constants */ #ifdef CRDLY fprintf(outfile, "#define CRDLY 0%011o\n", CRDLY); #endif #ifdef CR0 fprintf(outfile, "#define CR0 0%011o\n", CR0); #endif #ifdef CR1 fprintf(outfile, "#define CR1 0%011o\n", CR1); #endif #ifdef CR2 fprintf(outfile, "#define CR2 0%011o\n", CR2); #endif #ifdef CR3 fprintf(outfile, "#define CR3 0%011o\n", CR3); #endif #ifdef TABDLY fprintf(outfile, "#define TABDLY 0%011o\n", TABDLY); #endif #ifdef TAB0 fprintf(outfile, "#define TAB0 0%011o\n", TAB0); #endif #ifdef TAB1 fprintf(outfile, "#define TAB1 0%011o\n", TAB1); #endif #ifdef TAB2 fprintf(outfile, "#define TAB2 0%011o\n", TAB2); #endif #ifdef TAB3 fprintf(outfile, "#define TAB3 0%011o\n", TAB3); #endif #ifdef CSIZE fprintf(outfile, "#define CSIZE 0%011o\n", CSIZE); #endif #ifdef TIOCEXCL fprintf(outfile, "#define TIOCEXCL 0x%lx\n", (unsigned long)TIOCEXCL); #endif /* stdio constants */ #ifdef FOPEN_MAX fprintf(outfile, "#define FOPEN_MAX %u\n", FOPEN_MAX); #endif /* socket constants */ #ifdef PF_UNIX fprintf(outfile, "#define PF_UNIX %d\n", PF_UNIX); #elif defined(PF_LOCAL) fprintf(outfile, "#define PF_LOCAL %d\n", PF_LOCAL); #endif #ifdef PF_INET fprintf(outfile, "#define PF_INET %d\n", PF_INET); #endif #ifdef PF_INET6 fprintf(outfile, "#define PF_INET6 %d\n", PF_INET6); #endif #ifdef PF_APPLETALK fprintf(outfile, "#define PF_APPLETALK %d\n", PF_APPLETALK); #endif #ifdef PF_PACKET fprintf(outfile, "#define PF_PACKET %d\n", PF_PACKET); #endif #ifdef SOCK_STREAM fprintf(outfile, "#define SOCK_STREAM %d\n", SOCK_STREAM); #endif #ifdef SOCK_DGRAM fprintf(outfile, "#define SOCK_DGRAM %d\n", SOCK_DGRAM); #endif #ifdef SOCK_RAW fprintf(outfile, "#define SOCK_RAW %d\n", SOCK_RAW); #endif #ifdef SOCK_SEQPACKET fprintf(outfile, "#define SOCK_SEQPACKET %d\n", SOCK_SEQPACKET); #endif #ifdef SOCK_PACKET fprintf(outfile, "#define SOCK_PACKET %d\n", SOCK_PACKET); #endif #ifdef IPPROTO_IP fprintf(outfile, "#define IPPROTO_IP %d\n", IPPROTO_IP); #endif #ifdef IPPROTO_TCP fprintf(outfile, "#define IPPROTO_TCP %d\n", IPPROTO_TCP); #endif #ifdef IPPROTO_UDP fprintf(outfile, "#define IPPROTO_UDP %d\n", IPPROTO_UDP); #endif #ifdef IPPROTO_SCTP fprintf(outfile, "#define IPPROTO_SCTP %d\n", IPPROTO_SCTP); #endif #ifdef IPPROTO_DCCP fprintf(outfile, "#define IPPROTO_DCCP %d\n", IPPROTO_DCCP); #endif #ifdef SOL_SOCKET fprintf(outfile, "#define SOL_SOCKET 0x%x\n", SOL_SOCKET); #endif #ifdef SOL_PACKET fprintf(outfile, "#define SOL_PACKET 0x%x\n", SOL_PACKET); #endif #ifdef SOL_IP fprintf(outfile, "#define SOL_IP 0x%x\n", SOL_IP); #endif #ifdef SOL_IPV6 fprintf(outfile, "#define SOL_IPV6 0x%x\n", SOL_IPV6); #endif #ifdef SOL_TCP fprintf(outfile, "#define SOL_TCP 0x%x\n", SOL_TCP); #endif #ifdef SOL_UDP fprintf(outfile, "#define SOL_UDP 0x%x\n", SOL_UDP); #endif #ifdef SOL_SCTP fprintf(outfile, "#define SOL_SCTP 0x%x\n", SOL_SCTP); #endif #ifdef SOL_DCCP fprintf(outfile, "#define SOL_DCCP 0x%x\n", SOL_DCCP); #endif #ifdef SO_REUSEADDR fprintf(outfile, "#define SO_REUSEADDR %d\n", SO_REUSEADDR); #endif return 0; } socat-1.7.3.1/xiolockfile.h0000644000201000020100000000107711453022152015241 0ustar gerhardgerhard/* source: xiolockfile.h */ /* Copyright Gerhard Rieger 2005 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xiolockfile_h_included #define __xiolockfile_h_included 1 /* preferred lock handling functions */ extern int xiolock(xiolock_t *lock); extern int xiounlock(const char *lockfile); /* more "internal" functions */ extern int xiogetlock(const char *lockfile); extern int xiowaitlock(const char *lockfile, struct timespec *intervall); extern int xiofiledroplock(xiofile_t *xfd); #endif /* !defined(__xiolockfile_h_included) */ socat-1.7.3.1/configure.ac0000777000201000020100000000000012455415361017362 2configure.inustar gerhardgerhardsocat-1.7.3.1/BUGREPORTS0000644000201000020100000000135207371453372014213 0ustar gerhardgerhard * If you have found a bug, i.e. socat SIGSEGV'ed, terminated abnormally without error message, did not comply to the documentation, or behaves different from your expectations, please send the following infos to socat@dest-unreach.org, as available: . output of "make info" in socat.out (you may remove the hostname in the first line to keep your privacy) . config.log . run your example with "socat -d -d -d -d -D ..." options, and include the log output . describe what you've done, and why you think socat did wrong * If you fixed a bug: Please do as described in the above paragraph, and include the modified files (or a patch file) * If you have contributions, problems etc: send available info and a description to the above address. socat-1.7.3.1/xio-listen.c0000644000201000020100000002637312460670272015040 0ustar gerhardgerhard/* source: xio-listen.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for listen socket options */ #include "xiosysincludes.h" #if WITH_LISTEN #include "xioopen.h" #include "xio-named.h" #include "xio-socket.h" #include "xio-ip.h" #include "xio-ip4.h" #include "xio-listen.h" #include "xio-tcpwrap.h" /***** LISTEN options *****/ const struct optdesc opt_backlog = { "backlog", NULL, OPT_BACKLOG, GROUP_LISTEN, PH_LISTEN, TYPE_INT, OFUNC_SPEC }; const struct optdesc opt_fork = { "fork", NULL, OPT_FORK, GROUP_CHILD, PH_PASTACCEPT, TYPE_BOOL, OFUNC_SPEC }; const struct optdesc opt_max_children = { "max-children", NULL, OPT_MAX_CHILDREN, GROUP_CHILD, PH_PASTACCEPT, TYPE_INT, OFUNC_SPEC }; /**/ #if (WITH_UDP || WITH_TCP) const struct optdesc opt_range = { "range", NULL, OPT_RANGE, GROUP_RANGE, PH_ACCEPT, TYPE_STRING, OFUNC_SPEC }; #endif /* applies and consumes the following option: PH_INIT, PH_PASTSOCKET, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_EARLY, PH_PREOPEN, PH_FD, PH_CONNECTED, PH_LATE, PH_LATE2 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, struct opt *opts, struct opt *opts0, int pf, int socktype, int proto) { int level; int result; #if WITH_RETRY if (xfd->forever || xfd->retry) { level = E_INFO; } else #endif /* WITH_RETRY */ level = E_ERROR; while (true) { /* loop over failed attempts */ /* tcp listen; this can fork() for us; it only returns on error or on successful establishment of tcp connection */ result = _xioopen_listen(xfd, xioflags, (struct sockaddr *)us, uslen, opts, pf, socktype, proto, level); /*! not sure if we should try again on retry/forever */ switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: if (xfd->forever || xfd->retry) { dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); if (result == STAT_RETRYLATER) { Nanosleep(&xfd->intervall, NULL); } dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); --xfd->retry; continue; } return STAT_NORETRY; #endif /* WITH_RETRY */ default: return result; } break; } /* drop out on success */ return result; } /* creates the listening socket, bind, applies options; waits for incoming connection, checks its source address and port. Depending on fork option, it may fork a subprocess. pf specifies the syntax expected for range option. In the case of generic socket it is 0 (expecting raw binary data), and the real pf can be obtained from us->af_family; for other socket types pf == us->af_family Returns 0 if a connection was accepted; with fork option, this is always in a subprocess! Other return values indicate a problem; this can happen in the master process or in a subprocess. This function does not retry. If you need retries, handle this in a loop in the calling function (and always provide the options...) After fork, we set the forever/retry of the child process to 0 applies and consumes the following option: PH_INIT, PH_PASTSOCKET, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_EARLY, PH_PREOPEN, PH_FD, PH_CONNECTED, PH_LATE, PH_LATE2 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, struct opt *opts, int pf, int socktype, int proto, int level) { struct sockaddr sa; socklen_t salen; int backlog = 5; /* why? 1 seems to cause problems under some load */ char *rangename; bool dofork = false; int maxchildren = 0; char infobuff[256]; char lisname[256]; union sockaddr_union _peername; union sockaddr_union _sockname; union sockaddr_union *pa = &_peername; /* peer address */ union sockaddr_union *la = &_sockname; /* local address */ socklen_t pas = sizeof(_peername); /* peer address size */ socklen_t las = sizeof(_sockname); /* local address size */ int result; retropt_bool(opts, OPT_FORK, &dofork); if (dofork) { if (!(xioflags & XIO_MAYFORK)) { Error("option fork not allowed here"); return STAT_NORETRY; } xfd->flags |= XIO_DOESFORK; } retropt_int(opts, OPT_MAX_CHILDREN, &maxchildren); if (! dofork && maxchildren) { Error("option max-children not allowed without option fork"); return STAT_NORETRY; } if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; if (dofork) { xiosetchilddied(); /* set SIGCHLD handler */ } if ((xfd->fd = xiosocket(opts, us->sa_family, socktype, proto, level)) < 0) { return STAT_RETRYLATER; } applyopts_cloexec(xfd->fd, opts); applyopts(xfd->fd, opts, PH_PREBIND); applyopts(xfd->fd, opts, PH_BIND); if (Bind(xfd->fd, (struct sockaddr *)us, uslen) < 0) { Msg4(level, "bind(%d, {%s}, "F_socklen"): %s", xfd->fd, sockaddr_info(us, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); Close(xfd->fd); return STAT_RETRYLATER; } #if WITH_UNIX if (us->sa_family == AF_UNIX) { applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD); } #endif /* 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) { Warn4("getsockname(%d, %p, {%d}): %s", xfd->fd, &us, uslen, strerror(errno)); } applyopts(xfd->fd, opts, PH_PASTBIND); #if WITH_UNIX if (us->sa_family == AF_UNIX) { /*applyopts_early(((struct sockaddr_un *)us)->sun_path, opts);*/ applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_EARLY); applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN); } #endif /* WITH_UNIX */ #if WITH_IP4 /*|| WITH_IP6*/ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &xfd->para.socket.range) < 0) { free(rangename); return STAT_NORETRY; } free(rangename); xfd->para.socket.dorange = true; } #endif #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP xio_retropt_tcpwrap(xfd, 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; } retropt_bool(opts, OPT_LOWPORT, &xfd->para.socket.ip.lowport); #endif /* WITH_TCP || WITH_UDP */ applyopts(xfd->fd, opts, PH_PRELISTEN); retropt_int(opts, OPT_BACKLOG, &backlog); if (Listen(xfd->fd, backlog) < 0) { Error3("listen(%d, %d): %s", xfd->fd, backlog, strerror(errno)); return STAT_RETRYLATER; } if (xioopts.logopt == 'm') { Info("starting accept loop, switching to syslog"); diag_set('y', xioopts.syslogfac); xioopts.logopt = 'y'; } else { Info("starting accept loop"); } while (true) { /* but we only loop if fork option is set */ char peername[256]; char sockname[256]; int ps; /* peer socket */ pa = &_peername; la = &_sockname; salen = sizeof(struct sockaddr); do { /*? int level = E_ERROR;*/ Notice1("listening on %s", sockaddr_info(us, uslen, lisname, sizeof(lisname))); ps = Accept(xfd->fd, (struct sockaddr *)&sa, &salen); if (ps >= 0) { /*0 Info4("accept(%d, %p, {"F_Zu"}) -> %d", xfd->fd, &sa, salen, ps);*/ break; /* success, break out of loop */ } if (errno == EINTR) { continue; } if (errno == ECONNABORTED) { Notice4("accept(%d, %p, {"F_socklen"}): %s", xfd->fd, &sa, salen, strerror(errno)); continue; } Msg4(level, "accept(%d, %p, {"F_socklen"}): %s", xfd->fd, &sa, salen, strerror(errno)); Close(xfd->fd); return STAT_RETRYLATER; } while (true); applyopts_cloexec(ps, opts); if (Getpeername(ps, &pa->soa, &pas) < 0) { Warn4("getpeername(%d, %p, {"F_socklen"}): %s", ps, pa, pas, strerror(errno)); pa = NULL; } if (Getsockname(ps, &la->soa, &las) < 0) { Warn4("getsockname(%d, %p, {"F_socklen"}): %s", ps, la, las, strerror(errno)); la = NULL; } Notice2("accepting connection from %s on %s", pa? sockaddr_info(&pa->soa, pas, peername, sizeof(peername)):"NULL", la? sockaddr_info(&la->soa, las, sockname, sizeof(sockname)):"NULL"); if (pa != NULL && la != NULL && xiocheckpeer(xfd, pa, la) < 0) { if (Shutdown(ps, 2) < 0) { Info2("shutdown(%d, 2): %s", ps, strerror(errno)); } Close(ps); continue; } if (pa != NULL) Info1("permitting connection from %s", sockaddr_info((struct sockaddr *)pa, pas, infobuff, sizeof(infobuff))); if (dofork) { pid_t pid; /* mostly int; only used with fork */ sigset_t mask_sigchld; /* we must prevent that the current packet triggers another fork; therefore we wait for a signal from the recent child: USR1 indicates that is has consumed the last packet; CHLD means it has terminated */ /* block SIGCHLD and SIGUSR1 until parent is ready to react */ sigemptyset(&mask_sigchld); sigaddset(&mask_sigchld, SIGCHLD); Sigprocmask(SIG_BLOCK, &mask_sigchld, NULL); if ((pid = xio_fork(false, level==E_ERROR?level:E_WARN)) < 0) { Close(xfd->fd); Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL); return STAT_RETRYLATER; } if (pid == 0) { /* child */ pid_t cpid = Getpid(); Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL); 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)); } xfd->fd = ps; #if WITH_RETRY /* !? */ xfd->forever = false; xfd->retry = 0; level = E_ERROR; #endif /* WITH_RETRY */ break; } /* server: continue loop with listen */ /* shutdown() closes the socket even for the child process, but close() does what we want */ if (Close(ps) < 0) { Info2("close(%d): %s", ps, strerror(errno)); } /* now we are ready to handle signals */ Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL); while (maxchildren) { if (num_child < maxchildren) break; Notice("maxchildren are active, waiting"); /* UINT_MAX would even be nicer, but Openindiana works only with 31 bits */ while (!Sleep(INT_MAX)) ; /* any signal lets us continue */ } Info("still listening"); } else { if (Close(xfd->fd) < 0) { Info2("close(%d): %s", xfd->fd, strerror(errno)); } xfd->fd = ps; break; } } applyopts(xfd->fd, opts, PH_FD); applyopts(xfd->fd, opts, PH_PASTSOCKET); applyopts(xfd->fd, opts, PH_CONNECTED); if ((result = _xio_openlate(xfd, opts)) < 0) return result; /* set the env vars describing the local and remote sockets */ if (la != NULL) xiosetsockaddrenv("SOCK", la, las, proto); if (pa != NULL) xiosetsockaddrenv("PEER", pa, pas, proto); return 0; } #endif /* WITH_LISTEN */ socat-1.7.3.1/utils.c0000644000201000020100000001120412460670272014070 0ustar gerhardgerhard/* source: utils.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* useful additions to C library */ #include "config.h" #include "sysincludes.h" #include "compat.h" /* socklen_t */ #include "mytypes.h" #include "sycls.h" #include "utils.h" #if !HAVE_PROTOTYPE_LIB_memrchr /* GNU extension, available since glibc 2.1.91 */ void *memrchr(const void *s, int c, size_t n) { const unsigned char *t = ((unsigned char *)s)+n; while (--t >= (unsigned char *)s) { if (*t == c) break; } if (t < (unsigned char *)s) return NULL; return (void *)t; } #endif /* !HAVE_PROTOTYPE_LIB_memrchr */ void *memdup(const void *src, size_t n) { void *dest; if ((dest = Malloc(n)) == NULL) { return NULL; } memcpy(dest, src, n); return dest; } /* search the keyword-table for a match of the leading part of name. */ /* returns the pointer to the matching field of the keyword or NULL if no keyword was found. */ const struct wordent *keyw(const struct wordent *keywds, const char *name, unsigned int nkeys) { unsigned int lower, upper, mid; int r; lower = 0; upper = nkeys; while (upper - lower > 1) { mid = (upper + lower) >> 1; if (!(r = strcasecmp(keywds[mid].name, name))) { return &keywds[mid]; } if (r < 0) lower = mid; else upper = mid; } if (nkeys > 0 && !(strcasecmp(keywds[lower].name, name))) { return &keywds[lower]; } return NULL; } /* Linux: setenv(), AIX (4.3?): putenv() */ #if !HAVE_SETENV int setenv(const char *name, const char *value, int overwrite) { int result; char *env; if (!overwrite) { if (getenv(name)) return 0; /* already exists */ } if ((env = Malloc(strlen(name)+strlen(value)+2)) == NULL) { return -1; } sprintf(env, "%s=%s", name, value); if ((result = putenv(env)) != 0) { /* AIX docu says "... nonzero ..." */ free(env); result = -1; } /* linux "man putenv" says: ...this string becomes part of the environment*/ return result; } #endif /* !HAVE_SETENV */ /* sanitizes an "untrusted" character. output buffer must provide at least 4 characters space. Does not append \0. returns length of output (currently: max 4) */ static size_t sanitize_char(char c, char *o, int style) { int hn; /* high nibble */ int ln; /* low nibble */ int n; /* written chars */ if (isprint(c)) { *o = c; return 1; } *o++ = '\\'; n = 2; switch (c) { case '\0': *o++ = '0'; break; case '\a': *o++ = 'a'; break; case '\b': *o++ = 'b'; break; case '\t': *o++ = 't'; break; case '\n': *o++ = 'n'; break; case '\v': *o++ = 'v'; break; case '\f': *o++ = 'f'; break; case '\r': *o++ = 'r'; break; case '\'': *o++ = '\''; break; case '\"': *o++ = '"'; break; case '\\': *o++ = '\\'; break; default: *o++ = 'x'; hn = (c>>4)&0x0f; ln = c&0x0f; *o++ = (hn>=10 ? (('A'-1)+(hn-10)) : ('0'+hn)); *o++ = (ln>=10 ? (('A'-1)+(ln-10)) : ('0'+ln)); n = 4; } return n; } /* sanitizes "untrusted" text, replacing special control characters with the C string version (eg."\n"), and replacing unprintable chars with hex representation ("\xAB"). text can grow to four times of input, so keep output buffer long enough! returns a pointer to the first untouched byte of the output buffer. Output is not \0 terminated. */ char *sanitize_string(const char *data, /* input data */ size_t bytes, /* length of input data, >=0 */ char *coded, /* output buffer, must be long enough */ int style ) { int c; while (bytes > 0) { c = *(unsigned char *)data++; coded += sanitize_char(c, coded, style); --bytes; } return coded; } /* copies a substring out of a given buff returns scratch, \0 terminated; scratch must provide len+1 bytes */ char *xiosubstr(char *scratch, const char *str, size_t from, size_t len) { char *scratch0 = scratch; str += from; while (len--) { *scratch++ = *str++; } *scratch = '\0'; return scratch0; } /* since version 1.7.2.4 socat supports C-99 behaviour of snprintf but still can handle the old glibc case with -1 return on truncation. Do not rely on exact return value in case of truncation */ int xio_snprintf(char *str, size_t size, const char *format, ...) { va_list ap; int result; va_start(ap, format); result = vsnprintf(str, size, format, ap); #if ! HAVE_C99_SNPRINTF if (result < 0) { result = size+63; /* indicate truncation with just some guess */ } #endif /* !HAVE_C99_SNPRINTF */ va_end(ap); return result; } socat-1.7.3.1/COPYING0000644000201000020100000004325412455415361013631 0ustar gerhardgerhard GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. socat-1.7.3.1/xio-udp.c0000644000201000020100000005051312455415362014324 0ustar gerhardgerhard/* source: xio-udp.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for handling UDP addresses */ #include "xiosysincludes.h" #if WITH_UDP && (WITH_IP4 || WITH_IP6) #include "xioopen.h" #include "xio-socket.h" #include "xio-ip4.h" #include "xio-ip6.h" #include "xio-ip.h" #include "xio-ipapp.h" #include "xio-tcpwrap.h" #include "xio-udp.h" static int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned 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, unsigned 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, unsigned 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, unsigned groups, int pf, int socktype, int ipproto); static int _xioopen_udp_sendto(const char *hostname, const char *servname, struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int pf, int socktype, int ipproto); const struct addrdesc addr_udp_connect = { "udp-connect", 3, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP, SOCK_DGRAM, IPPROTO_UDP, PF_UNSPEC HELP("::") }; #if WITH_LISTEN const struct addrdesc addr_udp_listen = { "udp-listen", 3, xioopen_ipdgram_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE, PF_UNSPEC, IPPROTO_UDP, PF_UNSPEC HELP(":") }; #endif /* WITH_LISTEN */ const struct addrdesc addr_udp_sendto = { "udp-sendto", 3, xioopen_udp_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; const struct addrdesc addr_udp_recvfrom = { "udp-recvfrom", 3, xioopen_udp_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_CHILD|GROUP_RANGE, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; const struct addrdesc addr_udp_recv = { "udp-recv", 1, xioopen_udp_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_RANGE, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; const struct addrdesc addr_udp_datagram = { "udp-datagram", 3, xioopen_udp_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_RANGE, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; #if WITH_IP4 const struct addrdesc addr_udp4_connect = { "udp4-connect", 3, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP, SOCK_DGRAM, IPPROTO_UDP, PF_INET HELP("::") }; #if WITH_LISTEN const struct addrdesc addr_udp4_listen = { "udp4-listen", 3, xioopen_ipdgram_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE, PF_INET, IPPROTO_UDP, PF_INET HELP(":") }; #endif /* WITH_LISTEN */ const struct addrdesc addr_udp4_sendto = { "udp4-sendto", 3, xioopen_udp_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP, PF_INET, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; const struct addrdesc addr_udp4_datagram = { "udp4-datagram",3, xioopen_udp_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_RANGE, PF_INET, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; const struct addrdesc addr_udp4_recvfrom= { "udp4-recvfrom", 3, xioopen_udp_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_CHILD|GROUP_RANGE, PF_INET, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; const struct addrdesc addr_udp4_recv = { "udp4-recv", 1, xioopen_udp_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_RANGE, PF_INET, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; #endif /* WITH_IP4 */ #if WITH_IP6 const struct addrdesc addr_udp6_connect = { "udp6-connect", 3, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP, SOCK_DGRAM, IPPROTO_UDP, PF_INET6 HELP("::") }; #if WITH_LISTEN const struct addrdesc addr_udp6_listen = { "udp6-listen", 3, xioopen_ipdgram_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE, PF_INET6, IPPROTO_UDP, 0 HELP(":") }; #endif /* WITH_LISTEN */ const struct addrdesc addr_udp6_sendto = { "udp6-sendto", 3, xioopen_udp_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP, PF_INET6, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; const struct addrdesc addr_udp6_datagram= { "udp6-datagram", 3, xioopen_udp_datagram,GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_RANGE, PF_INET6, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; const struct addrdesc addr_udp6_recvfrom= { "udp6-recvfrom", 3, xioopen_udp_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_CHILD|GROUP_RANGE, PF_INET6, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; const struct addrdesc addr_udp6_recv = { "udp6-recv", 1, xioopen_udp_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_RANGE, PF_INET6, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; #endif /* WITH_IP6 */ /* we expect the form: port */ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int pf, int ipproto, int protname) { const char *portname = argv[1]; union sockaddr_union us; union sockaddr_union themunion; union sockaddr_union *them = &themunion; int socktype = SOCK_DGRAM; struct pollfd readfd; bool dofork = false; pid_t pid; char *rangename; char infobuff[256]; unsigned char buff1[1]; socklen_t uslen; socklen_t themlen; int result; if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); } if (pf == PF_UNSPEC) { #if WITH_IP4 && WITH_IP6 pf = xioopts.default_ip=='6'?PF_INET6:PF_INET; #elif WITH_IP6 pf = PF_INET6; #else pf = PF_INET; #endif } retropt_socket_pf(opts, &pf); if (applyopts_single(&fd->stream, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); uslen = socket_init(pf, &us); retropt_bind(opts, pf, socktype, IPPROTO_UDP, (struct sockaddr *)&us, &uslen, 1, fd->stream.para.socket.ip.res_opts[1], fd->stream.para.socket.ip.res_opts[0]); if (false) { ; #if WITH_IP4 } else if (pf == PF_INET) { us.ip4.sin_port = parseport(portname, ipproto); #endif #if WITH_IP6 } else if (pf == PF_INET6) { us.ip6.sin6_port = parseport(portname, ipproto); #endif } else { Error1("xioopen_ipdgram_listen(): unknown address family %d", pf); } retropt_bool(opts, OPT_FORK, &dofork); if (dofork) { if (!(xioflags & XIO_MAYFORK)) { Error("option fork not allowed here"); return STAT_NORETRY; } } #if WITH_IP4 /*|| WITH_IP6*/ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &fd->stream.para.socket.range) < 0) { free(rangename); return STAT_NORETRY; } free(rangename); fd->stream.para.socket.dorange = true; } #endif #if WITH_LIBWRAP xio_retropt_tcpwrap(&fd->stream, opts); #endif /* WITH_LIBWRAP */ if (retropt_ushort(opts, OPT_SOURCEPORT, &fd->stream.para.socket.ip.sourceport) >= 0) { fd->stream.para.socket.ip.dosourceport = true; } retropt_bool(opts, OPT_LOWPORT, &fd->stream.para.socket.ip.lowport); if (dofork) { xiosetchilddied(); /* set SIGCHLD handler */ } while (true) { /* we loop with fork or prohibited packets */ /* now wait for some packet on this datagram socket, get its sender address, connect there, and return */ int reuseaddr = dofork; int doreuseaddr = (dofork != 0); char infobuff[256]; union sockaddr_union _sockname; union sockaddr_union *la = &_sockname; /* local address */ if ((fd->stream.fd = xiosocket(opts, pf, socktype, ipproto, E_ERROR)) < 0) { return STAT_RETRYLATER; } doreuseaddr |= (retropt_int(opts, OPT_SO_REUSEADDR, &reuseaddr) >= 0); applyopts(fd->stream.fd, opts, PH_PASTSOCKET); if (doreuseaddr) { if (Setsockopt(fd->stream.fd, opt_so_reuseaddr.major, opt_so_reuseaddr.minor, &reuseaddr, sizeof(reuseaddr)) < 0) { Warn6("setsockopt(%d, %d, %d, {%d}, "F_Zd"): %s", fd->stream.fd, opt_so_reuseaddr.major, opt_so_reuseaddr.minor, reuseaddr, sizeof(reuseaddr), strerror(errno)); } } applyopts_cloexec(fd->stream.fd, opts); applyopts(fd->stream.fd, opts, PH_PREBIND); applyopts(fd->stream.fd, opts, PH_BIND); if (Bind(fd->stream.fd, &us.soa, uslen) < 0) { Error4("bind(%d, {%s}, "F_socklen"): %s", fd->stream.fd, sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); return STAT_RETRYLATER; } /* under some circumstances bind() fills sockaddr with interesting info. */ if (Getsockname(fd->stream.fd, &us.soa, &uslen) < 0) { Error4("getsockname(%d, %p, {%d}): %s", fd->stream.fd, &us.soa, uslen, strerror(errno)); } applyopts(fd->stream.fd, opts, PH_PASTBIND); Notice1("listening on UDP %s", sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff))); readfd.fd = fd->stream.fd; readfd.events = POLLIN|POLLERR; while (xiopoll(&readfd, 1, NULL) < 0) { if (errno != EINTR) break; } themlen = socket_init(pf, them); do { result = Recvfrom(fd->stream.fd, buff1, 1, MSG_PEEK, &them->soa, &themlen); } while (result < 0 && errno == EINTR); if (result < 0) { Error5("recvfrom(%d, %p, 1, MSG_PEEK, {%s}, {"F_socklen"}): %s", fd->stream.fd, buff1, sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); return STAT_RETRYLATER; } Notice1("accepting UDP connection from %s", sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff))); if (xiocheckpeer(&fd->stream, them, la) < 0) { /* drop packet */ char buff[512]; Recv(fd->stream.fd, buff, sizeof(buff), 0); /* drop packet */ Close(fd->stream.fd); continue; } Info1("permitting UDP connection from %s", sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff))); if (dofork) { pid = xio_fork(false, E_ERROR); if (pid < 0) { return STAT_RETRYLATER; } if (pid == 0) { /* child */ break; } /* server: continue loop with socket()+recvfrom() */ /* when we dont close this we get awkward behaviour on Linux 2.4: recvfrom gives 0 bytes with invalid socket address */ if (Close(fd->stream.fd) < 0) { Info2("close(%d): %s", fd->stream.fd, strerror(errno)); } continue; } break; } applyopts(fd->stream.fd, opts, PH_CONNECT); if ((result = Connect(fd->stream.fd, &them->soa, themlen)) < 0) { Error4("connect(%d, {%s}, "F_socklen"): %s", fd->stream.fd, sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); return STAT_RETRYLATER; } /* set the env vars describing the local and remote sockets */ if (Getsockname(fd->stream.fd, &us.soa, &uslen) < 0) { Warn4("getsockname(%d, %p, {%d}): %s", fd->stream.fd, &us.soa, uslen, strerror(errno)); } xiosetsockaddrenv("SOCK", &us, uslen, IPPROTO_UDP); xiosetsockaddrenv("PEER", them, themlen, IPPROTO_UDP); fd->stream.howtoend = END_SHUTDOWN; applyopts_fchown(fd->stream.fd, opts); applyopts(fd->stream.fd, opts, PH_LATE); if ((result = _xio_openlate(&fd->stream, opts)) < 0) return result; return 0; } static int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int pf, int socktype, int ipproto) { int result; if (argc != 3) { Error2("%s: wrong number of parameters (%d instead of 2)", argv[0], argc-1); return STAT_NORETRY; } retropt_socket_pf(opts, &pf); if ((result = _xioopen_udp_sendto(argv[1], argv[2], opts, xioflags, xxfd, groups, pf, socktype, ipproto)) != STAT_OK) { return result; } _xio_openlate(&xxfd->stream, opts); return STAT_OK; } /* applies and consumes the following option: PH_INIT, PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE OFUNC_OFFSET OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC */ static int _xioopen_udp_sendto(const char *hostname, const char *servname, struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int pf, int socktype, int ipproto) { xiosingle_t *xfd = &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; /* ...res_opts[] */ if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); xfd->salen = sizeof(xfd->peersa); if ((result = xiogetaddrinfo(hostname, servname, pf, socktype, ipproto, &xfd->peersa, &xfd->salen, xfd->para.socket.ip.res_opts[0], xfd->para.socket.ip.res_opts[1])) != STAT_OK) { return result; } if (pf == PF_UNSPEC) { pf = xfd->peersa.soa.sa_family; } uslen = socket_init(pf, &us); if (retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, feats, xfd->para.socket.ip.res_opts[0], xfd->para.socket.ip.res_opts[1]) != STAT_NOACTION) { needbind = true; } if (retropt_ushort(opts, OPT_SOURCEPORT, &xfd->para.socket.ip.sourceport) >= 0) { switch (pf) { #if WITH_IP4 case PF_INET: us.ip4.sin_port = htons(xfd->para.socket.ip.sourceport); break; #endif #if WITH_IP6 case PF_INET6: us.ip6.sin6_port = htons(xfd->para.socket.ip.sourceport); break; #endif } needbind = true; } retropt_bool(opts, OPT_LOWPORT, &xfd->para.socket.ip.lowport); if (xfd->para.socket.ip.lowport) { switch (pf) { #if WITH_IP4 case PF_INET: /*!!! this is buggy */ us.ip4.sin_port = htons(xfd->para.socket.ip.lowport); break; #endif #if WITH_IP6 case PF_INET6: /*!!! this is buggy */ us.ip6.sin6_port = htons(xfd->para.socket.ip.lowport); break; #endif } needbind = true; } xfd->dtype = XIODATA_RECVFROM; return _xioopen_dgram_sendto(needbind?&us:NULL, uslen, opts, xioflags, xfd, groups, pf, socktype, ipproto); } static int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int pf, int socktype, int ipproto) { xiosingle_t *xfd = &xxfd->stream; char *rangename; char *hostname; int result; if (argc != 3) { Error2("%s: wrong number of parameters (%d instead of 2)", argv[0], argc-1); return STAT_NORETRY; } if ((hostname = strdup(argv[1])) == NULL) { Error1("strdup(\"%s\"): out of memory", argv[1]); return STAT_RETRYLATER; } retropt_socket_pf(opts, &pf); result = _xioopen_udp_sendto(hostname, argv[2], opts, xioflags, xxfd, groups, pf, socktype, ipproto); free(hostname); if (result != STAT_OK) { return result; } xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; xfd->para.socket.la.soa.sa_family = xfd->peersa.soa.sa_family; /* only accept packets with correct remote ports */ xfd->para.socket.ip.sourceport = ntohs(xfd->peersa.ip4.sin_port); xfd->para.socket.ip.dosourceport = true; /* 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) < 0) { free(rangename); return STAT_NORETRY; } xfd->para.socket.dorange = true; xfd->dtype |= XIOREAD_RECV_CHECKRANGE; free(rangename); } #if WITH_LIBWRAP xio_retropt_tcpwrap(xfd, opts); #endif /* WITH_LIBWRAP */ _xio_openlate(xfd, opts); return STAT_OK; } static int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int pf, int socktype, int ipproto) { union sockaddr_union us; socklen_t uslen = sizeof(us); int result; if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); return STAT_NORETRY; } xfd->stream.howtoend = END_NONE; retropt_socket_pf(opts, &pf); if (pf == PF_UNSPEC) { #if WITH_IP4 && WITH_IP6 pf = xioopts.default_ip=='6'?PF_INET6:PF_INET; #elif WITH_IP6 pf = PF_INET6; #else pf = PF_INET; #endif } if ((result = xiogetaddrinfo(NULL, argv[1], pf, socktype, ipproto, &us, &uslen, xfd->stream.para.socket.ip.res_opts[0], xfd->stream.para.socket.ip.res_opts[1])) != STAT_OK) { return result; } if (pf == PF_UNSPEC) { pf = us.soa.sa_family; } { union sockaddr_union la; socklen_t lalen = sizeof(la); if (retropt_bind(opts, pf, socktype, ipproto, &la.soa, &lalen, 1, xfd->stream.para.socket.ip.res_opts[0], xfd->stream.para.socket.ip.res_opts[1]) != STAT_NOACTION) { switch (pf) { #if WITH_IP4 case PF_INET: us.ip4.sin_addr = la.ip4.sin_addr; break; #endif #if WITH_IP6 case PF_INET6: us.ip6.sin6_addr = la.ip6.sin6_addr; break; #endif } } } if (retropt_ushort(opts, OPT_SOURCEPORT, &xfd->stream.para.socket.ip.sourceport) >= 0) { xfd->stream.para.socket.ip.dosourceport = true; } retropt_bool(opts, OPT_LOWPORT, &xfd->stream.para.socket.ip.lowport); xfd->stream.dtype = XIODATA_RECVFROM_ONE; if ((result = _xioopen_dgram_recvfrom(&xfd->stream, xioflags, &us.soa, uslen, opts, pf, socktype, ipproto, E_ERROR)) != STAT_OK) { return result; } _xio_openlate(&xfd->stream, opts); return STAT_OK; } static int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int pf, int socktype, int ipproto) { union sockaddr_union us; socklen_t uslen = sizeof(us); char *rangename; int result; if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); return STAT_NORETRY; } retropt_socket_pf(opts, &pf); if (pf == PF_UNSPEC) { #if WITH_IP4 && WITH_IP6 pf = xioopts.default_ip=='6'?PF_INET6:PF_INET; #elif WITH_IP6 pf = PF_INET6; #else pf = PF_INET; #endif } if ((result = xiogetaddrinfo(NULL, argv[1], pf, socktype, ipproto, &us, &uslen, xfd->stream.para.socket.ip.res_opts[0], xfd->stream.para.socket.ip.res_opts[1])) != STAT_OK) { return result; } if (pf == PF_UNSPEC) { pf = us.soa.sa_family; } #if 1 { union sockaddr_union la; socklen_t lalen = sizeof(la); if (retropt_bind(opts, pf, socktype, ipproto, &xfd->stream.para.socket.la.soa, &lalen, 1, xfd->stream.para.socket.ip.res_opts[0], xfd->stream.para.socket.ip.res_opts[1]) != STAT_NOACTION) { switch (pf) { #if WITH_IP4 case PF_INET: us.ip4.sin_addr = xfd->stream.para.socket.la.ip4.sin_addr; break; #endif #if WITH_IP6 case PF_INET6: us.ip6.sin6_addr = xfd->stream.para.socket.la.ip6.sin6_addr; break; #endif } } else { xfd->stream.para.socket.la.soa.sa_family = pf; } } #endif #if WITH_IP4 /*|| WITH_IP6*/ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &xfd->stream.para.socket.range) < 0) { return STAT_NORETRY; } xfd->stream.para.socket.dorange = true; } #endif #if WITH_LIBWRAP xio_retropt_tcpwrap(&xfd->stream, opts); #endif /* WITH_LIBWRAP */ if (retropt_ushort(opts, OPT_SOURCEPORT, &xfd->stream.para.socket.ip.sourceport) >= 0) { xfd->stream.para.socket.ip.dosourceport = true; } retropt_bool(opts, OPT_LOWPORT, &xfd->stream.para.socket.ip.lowport); xfd->stream.dtype = XIODATA_RECV; if ((result = _xioopen_dgram_recv(&xfd->stream, xioflags, &us.soa, uslen, opts, pf, socktype, ipproto, E_ERROR)) != STAT_OK) { return result; } _xio_openlate(&xfd->stream, opts); return result; } #endif /* WITH_UDP && (WITH_IP4 || WITH_IP6) */ socat-1.7.3.1/xio-fd.c0000644000201000020100000001746612161507203014125 0ustar gerhardgerhard/* source: xio-fd.c */ /* Copyright Gerhard Rieger 2001-2009 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains common file descriptor related option definitions */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-fd.h" /****** for ALL addresses - with open() or fcntl(F_SETFL) ******/ const struct optdesc opt_append = { "append", NULL, OPT_O_APPEND, GROUP_OPEN|GROUP_FD, PH_LATE, TYPE_BOOL, OFUNC_FCNTL, F_SETFL, O_APPEND }; const struct optdesc opt_nonblock = { "o-nonblock", "nonblock", OPT_O_NONBLOCK, GROUP_OPEN|GROUP_FD, PH_FD, TYPE_BOOL, OFUNC_FCNTL, F_SETFL, O_NONBLOCK }; #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK) const struct optdesc opt_o_ndelay = { "o-ndelay", NULL, OPT_O_NDELAY, GROUP_OPEN|GROUP_FD, PH_LATE, TYPE_BOOL, OFUNC_FCNTL, F_SETFL, O_NDELAY }; #endif #ifdef O_ASYNC const struct optdesc opt_async = { "async", NULL, OPT_O_ASYNC, GROUP_OPEN|GROUP_FD, PH_LATE, TYPE_BOOL, OFUNC_FCNTL, F_SETFL, O_ASYNC }; #endif #ifdef O_BINARY const struct optdesc opt_o_binary = { "o-binary", "binary", OPT_O_BINARY, GROUP_OPEN|GROUP_FD, PH_OPEN, TYPE_BOOL, OFUNC_FCNTL, F_SETFL, O_BINARY }; #endif #ifdef O_TEXT const struct optdesc opt_o_text = { "o-text", "text", OPT_O_TEXT, GROUP_OPEN|GROUP_FD, PH_OPEN, TYPE_BOOL, OFUNC_FCNTL, F_SETFL, O_TEXT }; #endif #ifdef O_NOINHERIT const struct optdesc opt_o_noinherit = { "o-noinherit", "noinherit", OPT_O_NOINHERIT, GROUP_OPEN|GROUP_FD, PH_OPEN, TYPE_BOOL, OFUNC_FCNTL, F_SETFL, O_NOINHERIT }; #endif #ifdef O_NOATIME const struct optdesc opt_o_noatime = { "o-noatime", "noatime", OPT_O_NOATIME, GROUP_OPEN|GROUP_FD, PH_FD, TYPE_BOOL, OFUNC_FCNTL, F_SETFL, O_NOATIME }; #endif /****** for ALL addresses - with fcntl(F_SETFD) ******/ const struct optdesc opt_cloexec = { "cloexec", NULL, OPT_CLOEXEC, GROUP_FD, PH_LATE, TYPE_BOOL, OFUNC_FCNTL, F_SETFD, FD_CLOEXEC }; /****** ftruncate() ******/ /* this record is good for ftruncate() or ftruncate64() if available */ #if HAVE_FTRUNCATE64 const struct optdesc opt_ftruncate32 = { "ftruncate32", NULL, OPT_FTRUNCATE32, GROUP_REG, PH_LATE, TYPE_OFF32, OFUNC_SPEC }; const struct optdesc opt_ftruncate64 = { "ftruncate64", "truncate", OPT_FTRUNCATE64, GROUP_REG, PH_LATE, TYPE_OFF64, OFUNC_SPEC }; #else const struct optdesc opt_ftruncate32 = { "ftruncate32", "truncate", OPT_FTRUNCATE32, GROUP_REG, PH_LATE, TYPE_OFF32, OFUNC_SPEC }; #endif /* !HAVE_FTRUNCATE64 */ /****** for ALL addresses - permissions, ownership, and positioning ******/ const struct optdesc opt_group = { "group", "gid", OPT_GROUP, GROUP_FD|GROUP_NAMED,PH_FD,TYPE_GIDT,OFUNC_SPEC }; const struct optdesc opt_group_late= { "group-late","gid-l", OPT_GROUP_LATE,GROUP_FD, PH_LATE, TYPE_GIDT, OFUNC_SPEC }; const struct optdesc opt_perm = { "perm", "mode", OPT_PERM, GROUP_FD|GROUP_NAMED, PH_FD, TYPE_MODET,OFUNC_SPEC }; const struct optdesc opt_perm_late = { "perm-late", NULL, OPT_PERM_LATE, GROUP_FD, PH_LATE, TYPE_MODET,OFUNC_SPEC }; const struct optdesc opt_user = { "user", "uid", OPT_USER, GROUP_FD|GROUP_NAMED, PH_FD, TYPE_UIDT, OFUNC_SPEC }; const struct optdesc opt_user_late = { "user-late", "uid-l", OPT_USER_LATE, GROUP_FD, PH_LATE, TYPE_UIDT, OFUNC_SPEC }; /* for something like random access files */ #if HAVE_LSEEK64 const struct optdesc opt_lseek32_cur = { "lseek32-cur", NULL, OPT_SEEK32_CUR, GROUP_REG|GROUP_BLK, PH_LATE, TYPE_OFF32, OFUNC_SEEK32, SEEK_CUR }; const struct optdesc opt_lseek32_end = { "lseek32-end", NULL, OPT_SEEK32_END, GROUP_REG|GROUP_BLK, PH_LATE, TYPE_OFF32, OFUNC_SEEK32, SEEK_END }; const struct optdesc opt_lseek32_set = { "lseek32-set", NULL, OPT_SEEK32_SET, GROUP_REG|GROUP_BLK, PH_LATE, TYPE_OFF32, OFUNC_SEEK32, SEEK_SET }; const struct optdesc opt_lseek64_cur = { "lseek64-cur", "seek-cur", OPT_SEEK64_CUR, GROUP_REG|GROUP_BLK, PH_LATE, TYPE_OFF64, OFUNC_SEEK64, SEEK_CUR }; const struct optdesc opt_lseek64_end = { "lseek64-end", "seek-end", OPT_SEEK64_END, GROUP_REG|GROUP_BLK, PH_LATE, TYPE_OFF64, OFUNC_SEEK64, SEEK_END }; const struct optdesc opt_lseek64_set = { "lseek64-set", "seek", OPT_SEEK64_SET, GROUP_REG|GROUP_BLK, PH_LATE, TYPE_OFF64, OFUNC_SEEK64, SEEK_SET }; #else const struct optdesc opt_lseek32_cur = { "lseek32-cur", "seek-cur", OPT_SEEK32_CUR, GROUP_REG|GROUP_BLK, PH_LATE, TYPE_OFF32, OFUNC_SEEK32, SEEK_CUR }; const struct optdesc opt_lseek32_end = { "lseek32-end", "seek-end", OPT_SEEK32_END, GROUP_REG|GROUP_BLK, PH_LATE, TYPE_OFF32, OFUNC_SEEK32, SEEK_END }; const struct optdesc opt_lseek32_set = { "lseek32-set", "seek", OPT_SEEK32_SET, GROUP_REG|GROUP_BLK, PH_LATE, TYPE_OFF32, OFUNC_SEEK32, SEEK_SET }; #endif /* !HAVE_LSEEK64 */ /* for all addresses (?) */ const struct optdesc opt_f_setlk_rd = { "f-setlk-rd", "setlk-rd", OPT_F_SETLK_RD, GROUP_FD, PH_FD,TYPE_BOOL, OFUNC_SPEC, F_SETLK, F_RDLCK }; const struct optdesc opt_f_setlkw_rd = { "f-setlkw-rd", "setlkw-rd",OPT_F_SETLKW_RD, GROUP_FD, PH_FD,TYPE_BOOL, OFUNC_SPEC, F_SETLKW, F_RDLCK }; const struct optdesc opt_f_setlk_wr = { "f-setlk-wr", "setlk", OPT_F_SETLK_WR, GROUP_FD, PH_FD,TYPE_BOOL, OFUNC_SPEC, F_SETLK, F_WRLCK }; const struct optdesc opt_f_setlkw_wr = { "f-setlkw-wr", "setlkw", OPT_F_SETLKW_WR, GROUP_FD, PH_FD,TYPE_BOOL, OFUNC_SPEC, F_SETLKW, F_WRLCK }; #if HAVE_FLOCK const struct optdesc opt_flock_sh = { "flock-sh", NULL, OPT_FLOCK_SH, GROUP_FD, PH_FD,TYPE_BOOL, OFUNC_FLOCK, LOCK_SH }; const struct optdesc opt_flock_sh_nb = { "flock-sh-nb", NULL, OPT_FLOCK_SH_NB, GROUP_FD, PH_FD,TYPE_BOOL, OFUNC_FLOCK, LOCK_SH|LOCK_NB }; const struct optdesc opt_flock_ex = { "flock-ex", "flock", OPT_FLOCK_EX, GROUP_FD, PH_FD,TYPE_BOOL, OFUNC_FLOCK, LOCK_EX }; const struct optdesc opt_flock_ex_nb = { "flock-ex-nb", "flock-nb", OPT_FLOCK_EX_NB, GROUP_FD, PH_FD,TYPE_BOOL, OFUNC_FLOCK, LOCK_EX|LOCK_NB }; #endif /* HAVE_FLOCK */ const struct optdesc opt_cool_write = { "cool-write", "coolwrite", OPT_COOL_WRITE, GROUP_FD, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(cool_write) }; /* control closing of connections */ const struct optdesc opt_end_close = { "end-close", "close", OPT_END_CLOSE, GROUP_FD, PH_INIT, TYPE_CONST, OFUNC_OFFSET, XIO_OFFSETOF(howtoend), END_CLOSE }; const struct optdesc opt_shut_none = { "shut-none", NULL, OPT_SHUT_NONE, GROUP_FD, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(howtoshut), XIOSHUT_NONE }; const struct optdesc opt_shut_down = { "shut-down", NULL, OPT_SHUT_DOWN, GROUP_FD, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(howtoshut), XIOSHUT_DOWN }; const struct optdesc opt_shut_close= { "shut-close", NULL, OPT_SHUT_CLOSE, GROUP_FD, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(howtoshut), XIOSHUT_CLOSE }; const struct optdesc opt_shut_null = { "shut-null", NULL, OPT_SHUT_NULL, GROUP_FD, PH_INIT, TYPE_CONST, OFUNC_OFFSET, XIO_OFFSETOF(howtoshut), XIOSHUT_NULL }; /****** generic ioctl() options ******/ const struct optdesc opt_ioctl_void = { "ioctl-void", "ioctl", OPT_IOCTL_VOID, GROUP_FD, PH_FD, TYPE_INT, OFUNC_IOCTL_GENERIC, 0, 0, 0 }; const struct optdesc opt_ioctl_int = { "ioctl-int", NULL, OPT_IOCTL_INT, GROUP_FD, PH_FD, TYPE_INT_INT, OFUNC_IOCTL_GENERIC, 0, 0, 0 }; const struct optdesc opt_ioctl_intp = { "ioctl-intp", NULL, OPT_IOCTL_INTP, GROUP_FD, PH_FD, TYPE_INT_INTP, OFUNC_IOCTL_GENERIC, 0, 0, 0 }; const struct optdesc opt_ioctl_bin = { "ioctl-bin", NULL, OPT_IOCTL_BIN, GROUP_FD, PH_FD, TYPE_INT_BIN, OFUNC_IOCTL_GENERIC, 0, 0, 0 }; const struct optdesc opt_ioctl_string = { "ioctl-string",NULL, OPT_IOCTL_STRING,GROUP_FD, PH_FD, TYPE_INT_STRING,OFUNC_IOCTL_GENERIC, 0, 0, 0 }; /* POSIX STREAMS */ #define ENABLE_OPTIONS #include "xio-streams.c" #undef ENABLE_OPTIONS socat-1.7.3.1/filan_main.c0000644000201000020100000001577612460670272015047 0ustar gerhardgerhard/* source: filan_main.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ const char copyright[] = "filan by Gerhard Rieger - see http://www.dest-unreach.org/socat/"; #include "config.h" #include "xioconfig.h" #include "sysincludes.h" #include "mytypes.h" #include "compat.h" #include "error.h" #include "sycls.h" #include "filan.h" #define WITH_HELP 1 static void filan_usage(FILE *fd); int main(int argc, const char *argv[]) { const char **arg1, *a; const char *filename = NULL, *waittimetxt; unsigned int m = 0; /* first FD (default) */ unsigned int n = FD_SETSIZE; /* last excl. */ unsigned int i; int style = 0; struct timespec waittime = { 0, 0 }; FILE *fdout = stdout; const char *outfname = NULL; unsigned long fildes; diag_set('p', strchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]); arg1 = argv+1; --argc; while (arg1[0] && (arg1[0][0] == '-')) { switch (arg1[0][1]) { #if WITH_HELP case '?': case 'h': filan_usage(stdout); exit(0); #endif #if LATER case 'V': filan_version(stdout); exit(0); #endif case 'L': filan_followsymlinks = true; break; case 'd': diag_set('d', NULL); break; case 's': style = 1; break; case 'r': filan_rawoutput = true; break; case 'i': if (arg1[0][2]) { a = *arg1+2; } else { ++arg1, --argc; if ((a = *arg1) == NULL) { Error("option -i requires an argument"); filan_usage(stderr); exit(1); } } m = strtoul(a, (char **)&a, 0); n = m; break; case 'n': if (arg1[0][2]) { a = *arg1+2; } else { ++arg1, --argc; if ((a = *arg1) == NULL) { Error("option -n requires an argument"); filan_usage(stderr); exit(1); } } n = strtoul(a, (char **)&a, 0); break; case 'f': if (arg1[0][2]) { filename = *arg1+2; } else { ++arg1, --argc; if ((filename = *arg1) == NULL) { Error("option -f requires an argument"); filan_usage(stderr); exit(1); } } break; case 'T': if (arg1[0][2]) { waittimetxt = *arg1+2; } else { ++arg1, --argc; if ((waittimetxt = *arg1) == NULL) { Error("option -T requires an argument"); filan_usage(stderr); exit(1); } } { double waittimedbl; waittimedbl = strtod(waittimetxt, NULL); waittime.tv_sec = waittimedbl; waittime.tv_nsec = (waittimedbl-waittime.tv_sec) * 1000000000; } break; case 'o': if (arg1[0][2]) { outfname = *arg1+2; } else { ++arg1, --argc; if ((outfname = *arg1) == NULL) { Error("option -o requires an argument"); filan_usage(stderr); exit(1); } } break; case '\0': break; default: diag_set_int('e', E_FATAL); Error1("unknown option %s", arg1[0]); #if WITH_HELP filan_usage(stderr); #endif exit(1); } #if 0 if (arg1[0][1] == '\0') break; #endif ++arg1; --argc; } if (argc != 0) { Error1("%d superfluous arguments", argc); filan_usage(stderr); exit(1); } if (outfname) { /* special cases */ if (!strcmp(outfname,"stdin")) { fdout=stdin; } else if (!strcmp(outfname,"stdout")) { fdout=stdout; } else if (!strcmp(outfname,"stderr")) { fdout=stderr; } /* file descriptor */ else if (*outfname == '+') { a = outfname+1; fildes = strtoul(a, (char **)&a, 0); if ((fdout = fdopen(fildes, "w")) == NULL) { Error2("can't fdopen file descriptor %lu: %s\n", fildes, strerror(errno)); exit(1); } } else { /* file name */ if ((fdout = fopen(outfname, "w")) == NULL) { Error2("can't fopen '%s': %s\n", outfname, strerror(errno)); exit(1); } } } Nanosleep(&waittime, NULL); if (style == 0) { /* this style gives detailled infos, but requires a file descriptor */ if (filename) { #if LATER /* this is just in case that S_ISSOCK does not work */ struct stat buf; int fd; if (Stat(filename, &buf) < 0) { Error3("stat(\"%s\", %p): %s", filename, &buf, strerror(errno)); } /* note: when S_ISSOCK was undefined, it always gives 0 */ if (S_ISSOCK(buf.st_mode)) { Error("cannot analyze UNIX domain socket"); } #endif filan_file(filename, fdout); } else { if (m == n) { ++n; } for (i = m; i < n; ++i) { filan_fd(i, fdout); } } } else { /* this style gives only type and path / socket addresses, and works from file descriptor or filename (with restrictions) */ if (filename) { /* filename: NULL means yet unknown; "" means no name at all */ #if LATER int fd; if ((fd = Open(filename, O_RDONLY|O_NOCTTY|O_NONBLOCK #ifdef O_LARGEFILE |O_LARGEFILE #endif , 0700)) < 0) { Debug2("open(\"%s\", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE, 0700): %s", filename, strerror(errno)); } fdname(filename, fd, fdout, NULL); #endif fdname(filename, -1, fdout, NULL); } else { if (m == n) { fdname("", m, fdout, NULL); } else { for (i = m; i < n; ++i) { fdname("", i, fdout, "%5u "); } } } } if (outfname && fdout != stdout && fdout != stderr) { fclose(fdout); } return 0; } #if WITH_HELP static void filan_usage(FILE *fd) { fputs(copyright, fd); fputc('\n', fd); fputs("Analyze file descriptors of the process\n", fd); fputs("Usage:\n", fd); fputs("filan [options]\n", fd); fputs(" options:\n", fd); #if LATER fputs(" -V print version information to stdout, and exit\n", fd); #endif #if WITH_HELP fputs(" -?|-h print this help text\n", fd); fputs(" -d increase verbosity (use up to 4 times)\n", fd); #endif #if 0 fputs(" -ly[facility] log to syslog, using facility (default is daemon)\n", fd); fputs(" -lf log to file\n", fd); fputs(" -ls log to stderr (default if no other log)\n", fd); #endif fputs(" -i only analyze this fd\n", fd); fprintf(fd, " -n analyze all fds from 0 up to fdnum-1 (default: %u)\n", FD_SETSIZE); fputs(" -s simple output with just type and socket address or path\n", fd); /* fputs(" -c alternate device visualization\n", fd);*/ fputs(" -f analyze file system entry\n", fd); fputs(" -T wait before analyzing, useful to connect with debugger\n", fd); fputs(" -r raw output for time stamps and rdev\n", fd); fputs(" -L follow symbolic links instead of showing their properties\n", fd); fputs(" -o output goes to filename, that can be:\n", fd); fputs(" a regular file name, the output goes to that\n", fd); fputs(" + , output goes to the file descriptor (which must be open writable)\n", fd); fputs(" the 3 special names stdin stdout and stderr\n", fd); } #endif /* WITH_HELP */ socat-1.7.3.1/dalan.c0000644000201000020100000001214512460670272014014 0ustar gerhardgerhard/* source: dalan.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* idea of a low level data description language. currently only a most primitive subset exists. */ #include "config.h" #include #include #if HAVE_STDBOOL_H #include #endif #include #include "dalan.h" /* test structure to find maximal alignment */ static struct { char a; long double b; } maxalign; /* test structure to find minimal alignment */ static struct { char a; char b; } minalign; /* test union to find kind of byte ordering */ static union { char a[2]; short b; } byteorder = { "01" }; struct dalan_opts_s dalan_opts = { sizeof(int), sizeof(short), sizeof(long), sizeof(char), sizeof(float), sizeof(double) } ; /* fill the dalan_opts structure with machine dependent defaults values. */ static void _dalan_dflts(struct dalan_opts_s *dlo) { dlo->c_int = sizeof(int); dlo->c_short = sizeof(short); dlo->c_long = sizeof(long); dlo->c_char = sizeof(char); dlo->c_float = sizeof(float); dlo->c_double = sizeof(double); dlo->maxalign = (char *)&maxalign.b-&maxalign.a; dlo->minalign = &minalign.b-&minalign.a; dlo->byteorder = (byteorder.b!=7711); } /* allocate a new dalan_opts structure, fills it with machine dependent defaults values, and returns the pointer. */ struct dalan_opts_s *dalan_props(void) { struct dalan_opts_s *dlo; dlo = malloc(sizeof(struct dalan_opts_s)); if (dlo == NULL) { return NULL; } _dalan_dflts(dlo); return dlo; } void dalan_init(void) { _dalan_dflts(&dalan_opts); } /* read data description from line, write result to data; do not write so much data that *p exceeds n ! p must be initialized to 0. return 0 on success, -1 if the data was cut due to n limit, 1 if a syntax error occurred *p is a global data counter; especially it must be used when calculating alignment. On successful return from the function *p must be actual! */ int dalan(const char *line, char *data, size_t *p, size_t n) { int align, mask, i, x; size_t p1 = *p; char c; /*fputs(line, stderr); fputc('\n', stderr);*/ while (c = *line++) { switch (c) { case ' ': case '\t': case '\r': case '\n': break; case ',': align = 2; while (*line == ',') { align <<= 1; ++line; } mask = align - 1; /* create the bitmask */ i = (align - (p1 & mask)) & mask; while (i && p1= n) { *p = p1; return -1; } data[p1++] = c; continue; } if (c == '"') break; } break; case '\'': switch (c = *line++) { case '\0': fputs("unterminated character\n", stderr); return 1; case '\'': fputs("error in character\n", stderr); return 1; case '\\': if (!(c = *line++)) { fputs("continuation line not implemented\n", stderr); return 1; } switch (c) { case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'f': c = '\f'; break; case 'b': c = '\b'; break; case 'a': c = '\a'; break; #if 0 case 'e': c = '\e'; break; #else case 'e': c = '\033'; break; #endif } /* PASSTHROUGH */ default: if (p1 >= n) { *p = p1; return -1; } data[p1++] = c; break; } if (*line != '\'') { fputs("error in character termination\n", stderr); *p = p1; return 1; } ++line; break; #if LATER case '0': c = *line++; if (c == 'x') { /* hexadecimal */ ; } else if (isdigit(c&0xff)) { /* octal */ } else { /* it was only 0 */ } break; #endif /* LATER */ case 'x': /* expecting hex data, must be an even number of digits!! */ while (true) { c = *line; if (isdigit(c&0xff)) { x = (c-'0') << 4; } else if (isxdigit(c&0xff)) { x = ((c&0x07) + 9) << 4; } else break; ++line; c = *line; if (isdigit(c&0xff)) { x |= (c-'0'); } else if (isxdigit(c&0xff)) { x |= (c&0x07) + 9; } else { fputs("odd number of hexadecimal digits\n", stderr); *p = p1; return 1; } ++line; if (p1 >= n) { *p = p1; return -1; } data[p1++] = x; } break; case 'A': case 'a': case 'C': case 'c': default: fprintf(stderr, "syntax error in \"%s\"\n", line-1); return 1; } } *p = p1; return 0; } socat-1.7.3.1/xio-ip6.h0000644000201000020100000000333611453022152014224 0ustar gerhardgerhard/* source: xio-ip6.h */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ip6_h_included #define __xio_ip6_h_included 1 #if WITH_IP6 extern const struct optdesc opt_ipv6_v6only; extern const struct optdesc opt_ipv6_join_group; extern const struct optdesc opt_ipv6_pktinfo; extern const struct optdesc opt_ipv6_recvpktinfo; extern const struct optdesc opt_ipv6_rthdr; extern const struct optdesc opt_ipv6_recvrthdr; extern const struct optdesc opt_ipv6_authhdr; extern const struct optdesc opt_ipv6_dstopts; extern const struct optdesc opt_ipv6_recvdstopts; extern const struct optdesc opt_ipv6_hopopts; extern const struct optdesc opt_ipv6_unicast_hops; extern const struct optdesc opt_ipv6_recvhopopts; extern const struct optdesc opt_ipv6_flowinfo; extern const struct optdesc opt_ipv6_hoplimit; extern const struct optdesc opt_ipv6_recvhoplimit; extern const struct optdesc opt_ipv6_recverr; extern const struct optdesc opt_ipv6_tclass; extern const struct optdesc opt_ipv6_recvtclass; extern const struct optdesc opt_ipv6_recvpathmtu; extern int xioparsenetwork_ip6(const char *rangename, struct xiorange *range); extern int xiorange_ip6andmask(struct xiorange *range); extern int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange *range); extern int xiolog_ancillary_ip6(struct cmsghdr *cmsg, int *num, char *typbuff, int typlen, char *nambuff, int namlen, char *envbuff, int envlen, char *valbuff, int vallen); extern int xiosetsockaddrenv_ip6(int idx, char *namebuff, size_t namelen, char *valuebuff, size_t valuelen, struct sockaddr_in6 *sa, int ipproto); #endif /* WITH_IP6 */ #endif /* !defined(__xio_ip6_h_included) */ socat-1.7.3.1/daemon.sh0000755000201000020100000000155011453022151014355 0ustar gerhardgerhard#! /bin/sh # source: daemon.sh # Copyright Gerhard Rieger 2001 # Published under the GNU General Public License V.2, see file COPYING # This script assumes that you create group daemon1 and user daemon1 before. # they need only the right to exist (no login etc.) # Note: this pid file mechanism is not robust! # You will adapt these variables USER=daemon1 GROUP=daemon1 INIF=fwnonsec.domain.org OUTIF=fwsec.domain.org TARGET=w3.intra.domain.org INPORT=80 DSTPORT=80 # INOPTS="fork,setgid=$GROUP,setuid=$USER" OUTOPTS= PIDFILE=/var/run/socat-$INPORT.pid OPTS="-d -d -lm" # notice to stderr, then to syslog SOCAT=/usr/local/bin/socat if [ "$1" = "start" -o -z "$1" ]; then $SOCAT $OPTS tcp-l:$INPORT,bind=$INIF,$INOPTS tcp:$TARGET:$DSTPORT,bind=$OUTIF,$OUTOPTS $PIDFILE elif [ "$1" = "stop" ]; then /bin/kill $(/bin/cat $PIDFILE) fi socat-1.7.3.1/EXAMPLES0000644000201000020100000004073512161506654013740 0ustar gerhardgerhard // Examples for using socat (and filan) //"$" means normal user, "#" requires privileges, "//" starts a comment /////////////////////////////////////////////////////////////////////////////// // similar to netcat // connect to 10.1.1.1 on port 80 and relay to and from stdio $ socat - TCP:10.1.1.1:80 # similar to "netcat 10.1.1.1 80" // listen on port 25, wait for an incoming connection, use CR+NL on this // connection, relay data to and from stdio; // then emulate a mailserver by hand :-) # socat - TCP-LISTEN:25,crlf // listen on port 25, wait for an incoming connection, use CR+NL on this // connection, relay data to and from stdio, but have line editing and history; // then emulate a mailserver by hand :-) # socat readline TCP-LISTEN:25,crlf // provide a transient history enabled front end to stupid line based // interactive programs $ socat readline exec:"nslookup",pty,ctty,setsid,echo=0 // same works for ftp (but password is not hidden) // you may also use a file based history list $ socat readline,history=.nslookup_hist exec:"nslookup",pty,ctty,setsid,echo=0 // using ~ as abbreviation for $HOME does not work! // poor mans 'telnetd' replacement # socat tcp-l:2023,reuseaddr,fork exec:/bin/login,pty,setsid,setpgid,stderr,ctty // and here an appropriate client: $ socat -,raw,echo=0 tcp:172.16.181.130:2023 // use ssl with client and server certificate for improved security; // replace /bin/login by /bin/bash when using SSL client authentication, can be // run without root then // this is a cool trick, proposed by Christophe Lohr, to dump communications to // two files; it would also work for other manipulations (recode, compress...) // and it might also work with netcat ;-) $ socat TCP-LISTEN:5555 SYSTEM:'tee l2r | socat - "TCP:remote:5555" | tee r2l' /////////////////////////////////////////////////////////////////////////////// // emergence solution because usleep(1) is not always available // this will "sleep" for 0.1s $ socat -T 0.1 pipe pipe /////////////////////////////////////////////////////////////////////////////// // a very primitive HTTP/1.0 echo server (problems: sends reply headers before // request; hangs if client does not shutdown - HTTP keep-alive) // wait for a connection on port 8000; do not wait for request, but immediately // start a shell that sends reply headers and an empty line; then echo all // incoming data back to client $ socat TCP-LISTEN:8000,crlf SYSTEM:"echo HTTP/1.0 200; echo Content-Type\: text/plain; echo; cat" // a less primitive HTTP echo server that sends back not only the reqest but // also server and client address and port. Might have portability issues with // echo ./socat -T 1 -d -d tcp-l:10081,reuseaddr,fork,crlf system:"echo -e \"\\\"HTTP/1.0 200 OK\\\nDocumentType: text/html\\\n\\\ndate: \$\(date\)
server:\$SOCAT_SOCKADDR:\$SOCAT_SOCKPORT
client: \$SOCAT_PEERADDR:\$SOCAT_PEERPORT\\\n
\\\"\"; cat; echo -e \"\\\"\\\n
\\\"\"" /////////////////////////////////////////////////////////////////////////////// // for communicating with an attached modem, I had reasonable results with // following command line. Required privileges depend on device mode. // after leaving socat, type "sane". // replace /dev/ttyS0 by the correct serial line or with /dev/modem $ socat readline /dev/ttyS0,raw,echo=0,crlf // or $ socat readline /dev/ttyS0,raw,echo=0,crlf,nonblock // then enter "at$" /////////////////////////////////////////////////////////////////////////////// // relay TCP port 80 from everywhere (internet, intranet, dmz) through your // firewall to your DMZ webserver (like plug-gw) // listen on port 80; whenever a connection is made, fork a new process (parent // process keeps accepting connections), su to nobody, and connect to // www.dmz.mydomain.org on port 80. // attention: this is a substitute for a reverse proxy without providing // application level security. # socat TCP-LISTEN:80,reuseaddr,fork,su=nobody TCP:www.dmz.mydomain.org:80 // Note: parent process keeps running as root, su after forking /////////////////////////////////////////////////////////////////////////////// // relay mail from your DMZ server through your firewall. // accept connections only on dmz interface and allow connections only from // smtp.dmz.mydomain.org. // the advantages over plug-gw and other relays are: // * you can bind to an IP address (even an alias), therefore enhance security // * in your OS you can create several IP aliases and bind another socat daemon // to each, making several application servers addressable // * lots of options, like switching user, chroot, IP performance tuning // * no need for inetd # socat -lm -d -d TCP-LISTEN:25,bind=fw.dmz.mydomain.org,fork,su=nobody,range=smtp.dmz.mydomain.org/32 TCP:smtp.intra.mydomain.org:25 /////////////////////////////////////////////////////////////////////////////// // convert line terminator in ascii streams, stdin to stdout // use unidirectional mode, convert nl to crnl $ socat -u - -,crlf // or cr to nl $ socat -u -,cr - // save piped data similar to 'tee': // copies stdin to stdout, but writes everything to the file too $ socat -,echo=0 open:/tmp/myfile,create,trunc,ignoreeof!!/tmp/myfile /////////////////////////////////////////////////////////////////////////////// // intrusion testing // found an XWindow Server behind IP filters with FTP data hole? (you are // lucky!) // prepare your host: # rm -f /tmp/.X11-unix/X1 // relay a pseudo display :1 on your machine to victim:0 # socat UNIX-LISTEN:/tmp/.X11-unix/X1,fork TCP:host.victim.org:6000,sp=20 & // and try to take a screendump (must be very lucky - when server has not even // host based authentication!) # xwd -root -display :1 -silent >victim.xwd // you sit behind a socks firewall that has IP filters but lazily allows socks // connections to loopback and has only host based X11 security. // like above, but from your inside client: # socat UNIX-LISTEN:/tmp/.X11-unix/X1,fork SOCKS4:firewall:loopback:6000 // or for the HTTP proxy: # socat UNIX-LISTEN:/tmp/.X11-unix/X1,fork PROXY:firewall:loopback:6000 /////////////////////////////////////////////////////////////////////////////// // forms of stdin with stdout, all equivalent $ socat echo - $ socat echo STDIO $ socat echo STDIN!!STDOUT $ socat echo STDIO!!STDIO $ socat echo -!!- $ socat echo FD:0!!FD:1 $ socat echo 0!!1 $ socat echo /dev/stdin!!/dev/stdout // if your OS provides these /////////////////////////////////////////////////////////////////////////////// // some echo address examples $ socat - PIPE $ socat - PIPE:/tmp/pipi // other version of echo $ socat - PIPE:/tmp/pipi,nonblock!!/tmp/pipi // other version of echo $ socat - EXEC:/bin/cat // another echo $ socat - SYSTEM:/bin/cat // another echo $ socat - TCP:loopback:7 // if inetd echo/TCP service activated $ socat - UDP:loopback:7 // if inetd echo/UDP service activated $ socat - /tmp/hugo,trunc,ignoreeof!!/tmp/hugo // with delay $ socat - UDP:loopback:2000,bind=:2000 // self "connection" $ socat - TCP:loopback:2000,bind=:2000 // Linux bug? # socat - IP:loopback:222 // raw protocol, self "connected" (attention, // Linux might drop packets with less than 8 bytes payload) /////////////////////////////////////////////////////////////////////////////// // unidirectional data transfer $ socat -u - - // like "tail -f", but start with showing all file contents $ socat -u FILE:/var/log/syslog.debug,ignoreeof - // like "tail -f", but do not show existing file contents $ socat -u FILE:/var/log/syslog.debug,ignoreeof,seek-end - // write to new file, create with given permission and group (must be member) - race condition with group!!! $ socat -u - CREATE:/tmp/outfile1,group=floppy,perm=0640 // // for an existing file /tmp/outfile1 # socat -u - FILE:/tmp/outfile1,group=floppy,perm=0700,user=4321 /////////////////////////////////////////////////////////////////////////////// // file handling $ socat - FILE:/tmp/outfile1,ignoreeof!!FILE:/tmp/outfile1,append // prints outfile1, then echoes input and protocols into file (appends to old data) /////////////////////////////////////////////////////////////////////////////// // unix socket handling // create a listening unix socket $ rm -f /tmp/mysocket; socat UNIX-LISTEN:/tmp/mysocket - // from another terminal, connect to this socket $ socat UNIX:/tmp/mysocket - // then transfer data bidirectionally /////////////////////////////////////////////////////////////////////////////// // transport examples // socks relay (externally socksify applications); // your ssh client and OS are not socksified, but you want to pass a socks // server with ssh: $ socat TCP-LISTEN:10022,fork SOCKS4:socks.mydomain.org:ssh-serv:22 $ ssh -p 10022 loopback // or better define a ProxyCommand in ~/.ssh/config: ProxyCommand socat - SOCKS:socks.mydomain.org:%h:%p // and with proxy: ProxyCommand socat - PROXY:proxy.mydomain.org:%h:%p,proxyport=8000 /////////////////////////////////////////////////////////////////////////////// // application examples // run sendmail daemon with your favorite network options # socat TCP-LISTEN:25,fork,ip-ttl=4,ip-tos=7,tcp-maxseg=576 EXEC:"/usr/sbin/sendmail -bs",nofork // local mail delivery over UNIX socket - no SUID program required # socat UNIX-LISTEN:/tmp/postoffice,fork,perm-early=0666 EXEC:"/usr/sbin/sendmail -bs" $ socat - /tmp/postoffice /////////////////////////////////////////////////////////////////////////////// // uses of filan // see what your operating system opens for you $ filan // or if that was too detailled $ filan -s // see what file descriptors are passed via exec function $ socat - EXEC:filan,nofork $ socat - EXEC:filan $ socat - EXEC:filan,pipes,stderr $ socat - EXEC:filan,pipes $ socat - EXEC:filan,pty // see what's done by your shell and with option "pipes" $ socat - SYSTEM:filan,pipes // see if gdb gives you an equivalent environment or opens some files for your program $ gdb ./filan (gdb) r (gdb) r -s /////////////////////////////////////////////////////////////////////////////// // want to use chat from the ppp package? // note: some OS's do not need "-e" for echo to print control characters // note: chat might send bytes one by one // with AIX, a similar program is available under the name "pppdial" $ socat -d -d tcp:localhost:25,crlf,nodelay exec:'/usr/sbin/chat -v -s "\"220 \"" "\"HELO loopback\"" "\"250 \"" "\"MAIL FROM: \"" "\"250 \"" "\"RCPT TO: root\"" "\"250 \"" "\"DATA\"" "\"354 \"" "\"test1'$(echo -e "\r.")'\"" "\"250 \"" "\"QUIT\"" "\"221 \""',pty,echo=0,cr ////////////////////////////////////////////////////////////////////////////// // IP6 # socat readline TCP6:[::1]:21 # if your inetd/ftp is listening on ip6 /////////////////////////////////////////////////////////////////////////////// // application server solutions // run a program (here: /bin/sh) chrooted, unprivileged; // parent process stays in real / running as root # socat -d -d - EXEC:/bin/sh,chroot=/home/sandbox,su=sandbox,pty // make a program available on the network chrooted, unprivileged; // parent process stays in / running as root // script path is already chrooted # ./socat -lm -d -d TCP-LISTEN:5555,fork EXEC:/bin/myscript,chroot=/home/sandbox,su=sandbox,pty,stderr // to avoid terminal problems, you might - instead of telnet - connect using $ socat -,icanon=0,echo=0 tcp:target:5555; reset // access local display from ssh server, when ssh port forwarding is disabled // socat must be installed on ssh server host // might have to use xauth... // this example is one-shot because ssh can handle only one channel xterm1$ socat -d -d exec:"ssh www.dest-unreach.org rm -f /tmp/.X11-unix/X9; ~/bin/socat -d -d unix-l\:/tmp/.X11-unix/X9\,fork -" unix:/tmp/.X11-unix/X0 xterm2$ ssh target target$ DISPLAY=:9 myxapplication // touch with perms: // no race condition for perms (applied with creat() call) $ socat -u /dev/null creat:/tmp/tempfile,perm=0600 // touch with owner and perms: // race condition before changing owner, but who cares - only root may access # socat -u /dev/null creat:/tmp/tempfile,user=user1,perm=0600 // invoke an interactive ssh with exec // first example passes control chars (^C etc.) to remote server as usual socat -,echo=0,raw exec:'ssh server',pty,setsid,ctty // second example interprets control chars on local command line socat -,echo=0,icanon=0 exec:'ssh server',pty,setsid,ctty // afterwards, type "reset"! // convince ssh to provide an "interactive" shell to your script // three main versions for entering password: // 1) from your TTY; have 10 seconds to enter password: (sleep 10; echo "ls"; sleep 1) |socat - exec:'ssh server',pty // 2) from XWindows (DISPLAY !); again 10 seconds (sleep 10; echo "ls"; sleep 1) |socat - exec:'ssh server',pty,setsid // 3) from script (sleep 5; echo PASSWORD; echo ls; sleep 1) |./socat - exec:'ssh server',pty,setsid,ctty // download with proxy CONNECT // use echo -e if required for \n $ (echo -e "CONNECT 128.129.130.131:80 HTTP/1.0\n"; sleep 5; echo -e "GET /download/file HTTP/1.0\n"; sleep 10) |socat -d -d -t 3600 - tcp:proxy:8080,crlf // retrieve a file from an sshd site with sourceforge style entry menu; // fill in your personal values; cat lets you enter your password (will be // visible on screen) $ (sleep 10; read pass; echo $pass; sleep 10; echo M; sleep 5; echo cat FILENAME; sleep 10) |./socat -d -d -ly - EXEC:'ssh -c 3des -l USER cf.sourceforge.net',pty,setsid,ctty |tee FILENAME // multicast community on local network: start the following command on all // participating hosts; like a conference call: # socat -d -d -d -d - udp-datagram:224.0.0.2:6666,bind=:6666,ip-add-membership=224.0.0.2:eth0,bindtodevice=eth0 // or $ socat -d -d -d -d - udp-datagram:224.0.0.2:6666,bind=:6666,ip-add-membership=224.0.0.2:eth0 // possible reasons for failure: // iptables or other filters (open your filters as required) // packets leave via wrong interface (set route: ...) // socket bound to specific address //============================================================================= // GENERIC FUNCTION CALLS // ioctl(): open CD drive (given value valid on Linux) // on my Linux system I find in /usr/include/linux/cdrom.h the define: // #define CDROMEJECT 0x5309 /* Ejects the cdrom media */ // the following command makes something like ioctl(fd, CDROMEJECT, NULL) // (don't care about the read error): $ socat /dev/cdrom,o-nonblock,ioctl-void=0x5309 - // setsockopt(): SO_REUSEADDR // the following command performs - beyond lots of overhead - something like: // myint=1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &myint, sizeof(myint)) $ socat -u udp-recv:7777,setsockopt-int=1:2:1 - // setsockopt(): SO_BINDTODEVICE // ways to apply SO_BINDTODEVICE without using the special socat address option // so-bindtodevice: // with string argument: $ sudo ./socat tcp-l:7777,setsockopt-string=1:25:eth0 pipe // with binary argument: $ sudo ./socat tcp-l:7777,setsockopt-bin=1:25:x6574683000 pipe =============================================================================== // not tested, just ideas, or have problems // traverse firewall for making internal telnet server accessible for outside // telnet client, when only outbound traffic (syn-filter) is allowed: // on external client run "double server". this process waits for a // connection from localhost on port 10023, and, when it is established, waits // for a connection from anywhere to port 20023: ext$ socat -d TCP-LISTEN:10023,range=localhost TCP-LISTEN:20023 // on internal server run double client: int$ socat -d TCP:localhost:23 TCP:extclient:10023 // or, with socks firewall: int$ socat -d TCP:localhost:23 SOCKS:socksserver:extclient:10023 // login with: ext$ telnet localhost 20023 // you can make a double server capable of handling multiple instances: ext$ socat -d TCP-LISTEN:10023,range=localhost,fork TCP-LISTEN:20023,reuseaddr // access remote display via ssh, when ssh port forwarding is disabled $ socat -d -d EXEC:"ssh target socat - UNIX:/tmp/.X11-unix/X0" TCP-LISTEN:6030 $ xclock -display localhost:30 // relay multiple webserver addresses through your firewall into your DMZ: // make IP aliases on your firewall, and then: # socat -d -d TCP-L:80,bind=fw-addr1,fork TCP:dmz-www1:80 # socat -d -d TCP-L:80,bind=fw-addr2,fork TCP:dmz-www2:80 // and for improved security: # socat -d -d TCP-L:80,bind=fw-addr3,su=nobody,fork TCP:dmz-www3:80 // proxy an arbitrary IP protocol over your firewall (answers won't work) # socat -d -d IP:0.0.0.0:150,bind=fwnonsec IP:sec-host:150,bind=fwsec // proxy an unsupported IP protocol over your firewall, point to point // end points see firewall interfaces as IP peers! # socat -d -d IP:nonsec-host:150,bind=fwnonsec IP:sec-host:150,bind=fwsec // note that, for IPsec, you might face problems that are known with NAT socat-1.7.3.1/xiosigchld.c0000644000201000020100000001260212460670272015070 0ustar gerhardgerhard/* source: xiosigchld.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source of the extended child signal handler */ #include "xiosysincludes.h" #include "xioopen.h" /*!! with socat, at most 4 exec children exist */ pid_t diedunknown[NUMUNKNOWN]; /* children that died before they were registered */ size_t nextunknown; /* register for a xio filedescriptor a callback (handler). when a SIGCHLD occurs, the signal handler will ??? */ int xiosetsigchild(xiofile_t *xfd, int (*callback)(struct single *)) { if (xfd->tag != XIO_TAG_DUAL) { xfd->stream.sigchild = callback; } else { xfd->dual.stream[0]->sigchild = callback; xfd->dual.stream[1]->sigchild = callback; } return 0; } /* exec'd child has died, perform appropriate changes to descriptor */ /* is async-signal-safe */ static int sigchld_stream(struct single *file) { /*!! call back to application */ file->para.exec.pid = 0; if (file->sigchild) { return (*file->sigchild)(file); } return 0; } /* return 0 if socket is not responsible for deadchild */ static int xio_checkchild(xiofile_t *socket, int socknum, pid_t deadchild) { int retval; if (socket != NULL) { if (socket->tag != XIO_TAG_DUAL) { if ((socket->stream.howtoend == END_KILL || socket->stream.howtoend == END_CLOSE_KILL || socket->stream.howtoend == END_SHUTDOWN_KILL) && socket->stream.para.exec.pid == deadchild) { Info2("exec'd process %d on socket %d terminated", socket->stream.para.exec.pid, socknum); sigchld_stream(&socket->stream); /* is async-signal-safe */ return 1; } } else { if (retval = xio_checkchild((xiofile_t *)socket->dual.stream[0], socknum, deadchild)) return retval; else return xio_checkchild((xiofile_t *)socket->dual.stream[1], socknum, deadchild); } } return 0; } /* this is the "physical" signal handler for SIGCHLD */ /* the current socat/xio implementation knows two kinds of children: exec/system addresses perform a fork: these children are registered and there death influences the parents flow; listen-socket with fork children: these children are "anonymous" and their death does not affect the parent process (now; maybe we have a child process counter later) */ void childdied(int signum) { pid_t pid; int _errno; int status = 0; bool wassig = false; int i; _errno = errno; /* save current value; e.g., select() on Cygwin seems to set it to EINTR _before_ handling the signal, and then passes the value left by the signal handler to the caller of select(), accept() etc. */ diag_in_handler = 1; Notice1("childdied(): handling signal %d", signum); Info1("childdied(signum=%d)", signum); do { pid = Waitpid(-1, &status, WNOHANG); if (pid == 0) { Msg(wassig?E_INFO:E_WARN, "waitpid(-1, {}, WNOHANG): no child has exited"); Info("childdied() finished"); diag_in_handler = 0; errno = _errno; return; } else if (pid < 0 && errno == ECHILD) { Msg(wassig?E_INFO:E_WARN, "waitpid(-1, {}, WNOHANG): "F_strerror); Info("childdied() finished"); diag_in_handler = 0; errno = _errno; return; } wassig = true; if (pid < 0) { Warn1("waitpid(-1, {%d}, WNOHANG): "F_strerror, status); Info("childdied() finished"); diag_in_handler = 0; errno = _errno; return; } /*! indent */ if (num_child) num_child--; /* check if it was a registered child process */ i = 0; while (i < XIO_MAXSOCK) { if (xio_checkchild(sock[i], i, pid)) break; ++i; } if (i == XIO_MAXSOCK) { Info2("childdied(%d): cannot identify child %d", signum, pid); if (nextunknown == NUMUNKNOWN) { nextunknown = 0; } diedunknown[nextunknown++] = pid; Debug1("saving pid in diedunknown"F_Zu, nextunknown/*sic, for compatibility*/); } if (WIFEXITED(status)) { if (WEXITSTATUS(status) == 0) { Info2("waitpid(): child %d exited with status %d", pid, WEXITSTATUS(status)); } else { Warn2("waitpid(): child %d exited with status %d", pid, WEXITSTATUS(status)); } } else if (WIFSIGNALED(status)) { Info2("waitpid(): child %d exited on signal %d", pid, WTERMSIG(status)); } else if (WIFSTOPPED(status)) { Info2("waitpid(): child %d stopped on signal %d", pid, WSTOPSIG(status)); } else { Warn1("waitpid(): cannot determine status of child %d", pid); } #if !HAVE_SIGACTION /* we might need to re-register our handler */ if (Signal(SIGCHLD, childdied) == SIG_ERR) { Warn("signal(SIGCHLD, childdied): "F_strerror); } #endif /* !HAVE_SIGACTION */ } while (1); Info("childdied() finished"); diag_in_handler = 0; errno = _errno; } int xiosetchilddied(void) { #if HAVE_SIGACTION struct sigaction act; memset(&act, 0, sizeof(struct sigaction)); act.sa_flags = SA_NOCLDSTOP/*|SA_RESTART*/ #ifdef SA_NOMASK |SA_NOMASK #endif ; act.sa_handler = childdied; sigfillset(&act.sa_mask); if (Sigaction(SIGCHLD, &act, NULL) < 0) { /*! man does not say that errno is defined */ Warn2("sigaction(SIGCHLD, %p, NULL): %s", childdied, strerror(errno)); } #else /* HAVE_SIGACTION */ if (Signal(SIGCHLD, childdied) == SIG_ERR) { Warn2("signal(SIGCHLD, %p): %s", childdied, strerror(errno)); } #endif /* !HAVE_SIGACTION */ return 0; } socat-1.7.3.1/sslcls.h0000644000201000020100000001127612460670272014251 0ustar gerhardgerhard/* source: sslcls.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __sslcls_h_included #define __sslcls_h_included 1 #if WITH_SYCLS #if WITH_OPENSSL void sycSSL_load_error_strings(void); int sycSSL_library_init(void); const SSL_METHOD *sycSSLv2_client_method(void); const SSL_METHOD *sycSSLv2_server_method(void); const SSL_METHOD *sycSSLv3_client_method(void); const SSL_METHOD *sycSSLv3_server_method(void); const SSL_METHOD *sycSSLv23_client_method(void); const SSL_METHOD *sycSSLv23_server_method(void); const SSL_METHOD *sycTLSv1_client_method(void); const SSL_METHOD *sycTLSv1_server_method(void); const SSL_METHOD *sycTLSv1_1_client_method(void); const SSL_METHOD *sycTLSv1_1_server_method(void); const SSL_METHOD *sycTLSv1_2_client_method(void); const SSL_METHOD *sycTLSv1_2_server_method(void); const SSL_METHOD *sycDTLSv1_client_method(void); const SSL_METHOD *sycDTLSv1_server_method(void); SSL_CTX *sycSSL_CTX_new(const SSL_METHOD *method); SSL *sycSSL_new(SSL_CTX *ctx); int sycSSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath); int sycSSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); int sycSSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); int sycSSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); void sycSSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); int sycSSL_CTX_set_tmp_dh(SSL_CTX *ctx, DH *dh); int sycSSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); int sycSSL_set_cipher_list(SSL *ssl, const char *str); long sycSSL_get_verify_result(SSL *ssl); int sycSSL_set_fd(SSL *ssl, int fd); int sycSSL_connect(SSL *ssl); int sycSSL_accept(SSL *ssl); int sycSSL_read(SSL *ssl, void *buf, int num); int sycSSL_pending(SSL *ssl); int sycSSL_write(SSL *ssl, const void *buf, int num); X509 *sycSSL_get_peer_certificate(SSL *ssl); int sycSSL_shutdown(SSL *ssl); void sycSSL_CTX_free(SSL_CTX *ctx); void sycSSL_free(SSL *ssl); int sycRAND_egd(const char *path); DH *sycPEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u); BIO *sycBIO_new_file(const char *filename, const char *mode); int sycFIPS_mode_set(int onoff); #if OPENSSL_VERSION_NUMBER >= 0x00908000L const COMP_METHOD *sycSSL_get_current_compression(SSL *ssl); const COMP_METHOD *sycSSL_get_current_expansion(SSL *ssl); const char *sycSSL_COMP_get_name(const COMP_METHOD *comp); #endif #endif /* WITH_OPENSSL */ #else /* !WITH_SYCLS */ #if WITH_OPENSSL #define sycSSL_load_error_strings() SSL_load_error_strings() #define sycSSL_library_init() SSL_library_init() #define sycSSLv2_client_method() SSLv2_client_method() #define sycSSLv2_server_method() SSLv2_server_method() #define sycSSLv3_client_method() SSLv3_client_method() #define sycSSLv3_server_method() SSLv3_server_method() #define sycSSLv23_client_method() SSLv23_client_method() #define sycSSLv23_server_method() SSLv23_server_method() #define sycTLSv1_client_method() TLSv1_client_method() #define sycTLSv1_server_method() TLSv1_server_method() #define sycSSL_CTX_new(m) SSL_CTX_new(m) #define sycSSL_new(c) SSL_new(c) #define sycSSL_CTX_load_verify_locations(c,f,p) SSL_CTX_load_verify_locations(c,f,p) #define sycSSL_CTX_use_certificate_file(c,f,t) SSL_CTX_use_certificate_file(c,f,t) #define sycSSL_CTX_use_certificate_chain_file(c,f) SSL_CTX_use_certificate_chain_file(c,f) #define sycSSL_CTX_use_PrivateKey_file(c,f,t) SSL_CTX_use_PrivateKey_file(c,f,t) #define sycSSL_CTX_set_verify(c,m,v) SSL_CTX_set_verify(c,m,v) #define sycSSL_CTX_set_tmp_dh(c,d) SSL_CTX_set_tmp_dh(c,d) #define sycSSL_CTX_set_cipher_list(c,s) SSL_CTX_set_cipher_list(c,s) #define sycSSL_set_cipher_list(s,t) SSL_set_cipher_list(s,t) #define sycSSL_get_verify_result(s) SSL_get_verify_result(s) #define sycSSL_set_fd(s,f) SSL_set_fd(s,f) #define sycSSL_connect(s) SSL_connect(s) #define sycSSL_accept(s) SSL_accept(s) #define sycSSL_read(s,b,n) SSL_read(s,b,n) #define sycSSL_pending(s) SSL_pending(s) #define sycSSL_write(s,b,n) SSL_write(s,b,n) #define sycSSL_get_peer_certificate(s) SSL_get_peer_certificate(s) #define sycSSL_shutdown(s) SSL_shutdown(s) #define sycSSL_CTX_free(c) SSL_CTX_free(c) #define sycSSL_free(s) SSL_free(s) #define sycRAND_egd(p) RAND_egd(p) #define sycPEM_read_bio_DHparams(b,x,p,u) PEM_read_bio_DHparams(b,x,p,u) #define sycBIO_new_file(f,m) BIO_new_file(f,m) #define sycSSL_get_current_compression(s) SSL_get_current_compression(s) #define sycSSL_get_current_expansion(s) SSL_get_current_expansion(s) #define sycSSL_COMP_get_name(c) SSL_COMP_get_name(c) #endif /* WITH_OPENSSL */ #define sycFIPS_mode_set(o) FIPS_mode_set(o) #endif /* !WITH_SYCLS */ #endif /* !defined(__sslcls_h_included) */ socat-1.7.3.1/sysutils.c0000644000201000020100000006222712460670272014642 0ustar gerhardgerhard/* source: sysutils.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* translate socket addresses into human readable form */ #include "config.h" #include "xioconfig.h" #include "sysincludes.h" #include "compat.h" /* socklen_t */ #include "mytypes.h" #include "error.h" #include "sycls.h" #include "utils.h" #include "sysutils.h" /* Substitute for Write(): Try to write all bytes before returning; this handles EINTR, EAGAIN/EWOULDBLOCK, and partial write situations. The drawback is that this function might block even with O_NONBLOCK option. Returns <0 on unhandled error, errno valid Will only return <0 or bytes */ ssize_t writefull(int fd, const void *buff, size_t bytes) { size_t writt = 0; ssize_t chk; while (1) { chk = Write(fd, (const char *)buff + writt, bytes - writt); if (chk < 0) { switch (errno) { case EINTR: case EAGAIN: #if EAGAIN != EWOULDBLOCK case EWOULDBLOCK: #endif Warn4("write(%d, %p, "F_Zu"): %s", fd, (const char *)buff+writt, bytes-writt, strerror(errno)); Sleep(1); continue; default: return -1; } } else if (writt+chk < bytes) { Warn4("write(%d, %p, "F_Zu"): only wrote "F_Zu" bytes, trying to continue ", fd, (const char *)buff+writt, bytes-writt, chk); writt += chk; } else { writt = bytes; break; } } return writt; } #if WITH_UNIX void socket_un_init(struct sockaddr_un *sa) { #if HAVE_STRUCT_SOCKADDR_SALEN sa->sun_len = sizeof(struct sockaddr_un); #endif sa->sun_family = AF_UNIX; memset(sa->sun_path, '\0', sizeof(sa->sun_path)); } #endif /* WITH_UNIX */ #if WITH_IP4 void socket_in_init(struct sockaddr_in *sa) { #if HAVE_STRUCT_SOCKADDR_SALEN sa->sin_len = sizeof(struct sockaddr_in); #endif sa->sin_family = AF_INET; sa->sin_port = 0; sa->sin_addr.s_addr = 0; sa->sin_zero[0] = 0; sa->sin_zero[1] = 0; sa->sin_zero[2] = 0; sa->sin_zero[3] = 0; sa->sin_zero[4] = 0; sa->sin_zero[5] = 0; sa->sin_zero[6] = 0; sa->sin_zero[7] = 0; } #endif /* WITH_IP4 */ #if WITH_IP6 void socket_in6_init(struct sockaddr_in6 *sa) { #if HAVE_STRUCT_SOCKADDR_SALEN sa->sin6_len = sizeof(struct sockaddr_in6); #endif sa->sin6_family = AF_INET6; sa->sin6_port = 0; sa->sin6_flowinfo = 0; #if HAVE_IP6_SOCKADDR==0 sa->sin6_addr.s6_addr[0] = 0; sa->sin6_addr.s6_addr[1] = 0; sa->sin6_addr.s6_addr[2] = 0; sa->sin6_addr.s6_addr[3] = 0; sa->sin6_addr.s6_addr[4] = 0; sa->sin6_addr.s6_addr[5] = 0; sa->sin6_addr.s6_addr[6] = 0; sa->sin6_addr.s6_addr[7] = 0; sa->sin6_addr.s6_addr[8] = 0; sa->sin6_addr.s6_addr[9] = 0; sa->sin6_addr.s6_addr[10] = 0; sa->sin6_addr.s6_addr[11] = 0; sa->sin6_addr.s6_addr[12] = 0; sa->sin6_addr.s6_addr[13] = 0; sa->sin6_addr.s6_addr[14] = 0; sa->sin6_addr.s6_addr[15] = 0; #elif HAVE_IP6_SOCKADDR==1 sa->sin6_addr.u6_addr.u6_addr32[0] = 0; sa->sin6_addr.u6_addr.u6_addr32[1] = 0; sa->sin6_addr.u6_addr.u6_addr32[2] = 0; sa->sin6_addr.u6_addr.u6_addr32[3] = 0; #elif HAVE_IP6_SOCKADDR==2 sa->sin6_addr.u6_addr32[0] = 0; sa->sin6_addr.u6_addr32[1] = 0; sa->sin6_addr.u6_addr32[2] = 0; sa->sin6_addr.u6_addr32[3] = 0; #elif HAVE_IP6_SOCKADDR==3 sa->sin6_addr.in6_u.u6_addr32[0] = 0; sa->sin6_addr.in6_u.u6_addr32[1] = 0; sa->sin6_addr.in6_u.u6_addr32[2] = 0; sa->sin6_addr.in6_u.u6_addr32[3] = 0; #elif HAVE_IP6_SOCKADDR==4 sa->sin6_addr._S6_un._S6_u32[0] = 0; sa->sin6_addr._S6_un._S6_u32[1] = 0; sa->sin6_addr._S6_un._S6_u32[2] = 0; sa->sin6_addr._S6_un._S6_u32[3] = 0; #elif HAVE_IP6_SOCKADDR==5 sa->sin6_addr.__u6_addr.__u6_addr32[0] = 0; sa->sin6_addr.__u6_addr.__u6_addr32[1] = 0; sa->sin6_addr.__u6_addr.__u6_addr32[2] = 0; sa->sin6_addr.__u6_addr.__u6_addr32[3] = 0; #endif } #endif /* WITH_IP6 */ #if _WITH_SOCKET /* initializes the socket address of the specified address family. Returns the length of the specific socket address, or 0 on error. */ socklen_t socket_init(int af, union sockaddr_union *sa) { switch (af) { case AF_UNSPEC: memset(sa, 0, sizeof(*sa)); return sizeof(*sa); #if WITH_UNIX case AF_UNIX: socket_un_init(&sa->un); return sizeof(sa->un); #endif #if WITH_IP4 case AF_INET: socket_in_init(&sa->ip4); return sizeof(sa->ip4); #endif #if WITH_IP6 case AF_INET6: socket_in6_init(&sa->ip6); return sizeof(sa->ip6); #endif default: Info1("socket_init(): unknown address family %d", af); memset(sa, 0, sizeof(union sockaddr_union)); sa->soa.sa_family = af; return 0; } } #endif /* _WITH_SOCKET */ #if WITH_UNIX #define XIOUNIXSOCKOVERHEAD (sizeof(struct sockaddr_un)-sizeof(((struct sockaddr_un*)0)->sun_path)) #endif #if _WITH_SOCKET /* writes a textual human readable representation of the sockaddr contents to buff and returns a pointer to buff writes at most blen bytes to buff including the terminating \0 byte */ char *sockaddr_info(const struct sockaddr *sa, socklen_t salen, char *buff, size_t blen) { union sockaddr_union *sau = (union sockaddr_union *)sa; char *lbuff = buff; char *cp = lbuff; int n; #if HAVE_STRUCT_SOCKADDR_SALEN n = xio_snprintf(cp, blen, "LEN=%d ", sau->soa.sa_len); if (n < 0 || n >= blen) { Warn1("sockaddr_info(): buffer too short ("F_Zu")", blen); *buff = '\0'; return buff; } cp += n, blen -= n; #endif n = xio_snprintf(cp, blen, "AF=%d ", sau->soa.sa_family); if (n < 0 || n >= blen) { Warn1("sockaddr_info(): buffer too short ("F_Zu")", blen); *buff = '\0'; return buff; } cp += n, blen -= n; switch (sau->soa.sa_family) { #if WITH_UNIX case 0: case AF_UNIX: sockaddr_unix_info(&sau->un, salen, cp+1, blen-1); cp[0] = '"'; strncat(cp+1, "\"", 1); break; #endif #if WITH_IP4 case AF_INET: sockaddr_inet4_info(&sau->ip4, cp, blen); break; #endif #if WITH_IP6 case AF_INET6: sockaddr_inet6_info(&sau->ip6, cp, blen); break; #endif default: n = xio_snprintf(cp, blen, "AF=%d ", sa->sa_family); if (n < 0 || n >= blen) { Warn1("sockaddr_info(): buffer too short ("F_Zu")", blen); *buff = '\0'; return buff; } cp += n, blen -= n; n = xio_snprintf(cp, blen, "0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", ((unsigned char *)sau->soa.sa_data)[0], ((unsigned char *)sau->soa.sa_data)[1], ((unsigned char *)sau->soa.sa_data)[2], ((unsigned char *)sau->soa.sa_data)[3], ((unsigned char *)sau->soa.sa_data)[4], ((unsigned char *)sau->soa.sa_data)[5], ((unsigned char *)sau->soa.sa_data)[6], ((unsigned char *)sau->soa.sa_data)[7], ((unsigned char *)sau->soa.sa_data)[8], ((unsigned char *)sau->soa.sa_data)[9], ((unsigned char *)sau->soa.sa_data)[10], ((unsigned char *)sau->soa.sa_data)[11], ((unsigned char *)sau->soa.sa_data)[12], ((unsigned char *)sau->soa.sa_data)[13]); if (n < 0 || n >= blen) { Warn("sockaddr_info(): buffer too short"); *buff = '\0'; return buff; } } return lbuff; } #endif /* _WITH_SOCKET */ #if WITH_UNIX char *sockaddr_unix_info(const struct sockaddr_un *sa, socklen_t salen, char *buff, size_t blen) { char ubuff[5*UNIX_PATH_MAX+3]; char *nextc; #if WITH_ABSTRACT_UNIXSOCKET if (salen > XIOUNIXSOCKOVERHEAD && sa->sun_path[0] == '\0') { nextc = sanitize_string(sa->sun_path, salen-XIOUNIXSOCKOVERHEAD, ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3); } else #endif /* WITH_ABSTRACT_UNIXSOCKET */ { if (salen <= XIOUNIXSOCKOVERHEAD) { nextc = sanitize_string ("", MIN(UNIX_PATH_MAX, strlen("")), ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3); } else { nextc = sanitize_string(sa->sun_path, MIN(UNIX_PATH_MAX, strlen(sa->sun_path)), ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3); } } *nextc = '\0'; buff[0] = '\0'; strncat(buff, ubuff, blen-1); return buff; } #endif /* WITH_UNIX */ #if WITH_IP4 /* addr in host byte order! */ char *inet4addr_info(uint32_t addr, char *buff, size_t blen) { if (xio_snprintf(buff, blen, "%u.%u.%u.%u", (unsigned int)(addr >> 24), (unsigned int)((addr >> 16) & 0xff), (unsigned int)((addr >> 8) & 0xff), (unsigned int)(addr & 0xff)) >= blen) { Warn("inet4addr_info(): buffer too short"); buff[blen-1] = '\0'; } return buff; } #endif /* WITH_IP4 */ #if WITH_IP4 char *sockaddr_inet4_info(const struct sockaddr_in *sa, char *buff, size_t blen) { if (xio_snprintf(buff, blen, "%u.%u.%u.%u:%hu", ((unsigned char *)&sa->sin_addr.s_addr)[0], ((unsigned char *)&sa->sin_addr.s_addr)[1], ((unsigned char *)&sa->sin_addr.s_addr)[2], ((unsigned char *)&sa->sin_addr.s_addr)[3], htons(sa->sin_port)) >= blen) { Warn("sockaddr_inet4_info(): buffer too short"); buff[blen-1] = '\0'; } return buff; } #endif /* WITH_IP4 */ #if !HAVE_INET_NTOP /* http://www.opengroup.org/onlinepubs/000095399/functions/inet_ntop.html */ const char *inet_ntop(int pf, const void *binaddr, char *addrtext, socklen_t textlen) { size_t retlen; switch (pf) { case PF_INET: if ((retlen = xio_snprintf(addrtext, textlen, "%u.%u.%u.%u", ((unsigned char *)binaddr)[0], ((unsigned char *)binaddr)[1], ((unsigned char *)binaddr)[2], ((unsigned char *)binaddr)[3])) >= textlen) { errno = ENOSPC; return NULL; } break; #if WITH_IP6 case PF_INET6: if ((retlen = xio_snprintf(addrtext, textlen, "%x:%x:%x:%x:%x:%x:%x:%x", ntohs(((uint16_t *)binaddr)[0]), ntohs(((uint16_t *)binaddr)[1]), ntohs(((uint16_t *)binaddr)[2]), ntohs(((uint16_t *)binaddr)[3]), ntohs(((uint16_t *)binaddr)[4]), ntohs(((uint16_t *)binaddr)[5]), ntohs(((uint16_t *)binaddr)[6]), ntohs(((uint16_t *)binaddr)[7]) )) >= textlen) { errno = ENOSPC; return NULL; } break; #endif /* WITH_IP6 */ default: errno = EAFNOSUPPORT; return NULL; } addrtext[retlen] = '\0'; return addrtext; } #endif /* !HAVE_INET_NTOP */ #if WITH_IP6 /* convert the IP6 socket address to human readable form. buff should be at least 50 chars long. output includes the port number */ char *sockaddr_inet6_info(const struct sockaddr_in6 *sa, char *buff, size_t blen) { if (xio_snprintf(buff, blen, "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]:%hu", #if HAVE_IP6_SOCKADDR==0 (sa->sin6_addr.s6_addr[0]<<8)+ sa->sin6_addr.s6_addr[1], (sa->sin6_addr.s6_addr[2]<<8)+ sa->sin6_addr.s6_addr[3], (sa->sin6_addr.s6_addr[4]<<8)+ sa->sin6_addr.s6_addr[5], (sa->sin6_addr.s6_addr[6]<<8)+ sa->sin6_addr.s6_addr[7], (sa->sin6_addr.s6_addr[8]<<8)+ sa->sin6_addr.s6_addr[9], (sa->sin6_addr.s6_addr[10]<<8)+ sa->sin6_addr.s6_addr[11], (sa->sin6_addr.s6_addr[12]<<8)+ sa->sin6_addr.s6_addr[13], (sa->sin6_addr.s6_addr[14]<<8)+ sa->sin6_addr.s6_addr[15], #elif HAVE_IP6_SOCKADDR==1 ntohs(((unsigned short *)&sa->sin6_addr.u6_addr.u6_addr16)[0]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr.u6_addr16)[1]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr.u6_addr16)[2]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr.u6_addr16)[3]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr.u6_addr16)[4]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr.u6_addr16)[5]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr.u6_addr16)[6]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr.u6_addr16)[7]), #elif HAVE_IP6_SOCKADDR==2 ntohs(((unsigned short *)&sa->sin6_addr.u6_addr16)[0]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr16)[1]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr16)[2]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr16)[3]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr16)[4]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr16)[5]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr16)[6]), ntohs(((unsigned short *)&sa->sin6_addr.u6_addr16)[7]), #elif HAVE_IP6_SOCKADDR==3 ntohs(((unsigned short *)&sa->sin6_addr.in6_u.u6_addr16)[0]), ntohs(((unsigned short *)&sa->sin6_addr.in6_u.u6_addr16)[1]), ntohs(((unsigned short *)&sa->sin6_addr.in6_u.u6_addr16)[2]), ntohs(((unsigned short *)&sa->sin6_addr.in6_u.u6_addr16)[3]), ntohs(((unsigned short *)&sa->sin6_addr.in6_u.u6_addr16)[4]), ntohs(((unsigned short *)&sa->sin6_addr.in6_u.u6_addr16)[5]), ntohs(((unsigned short *)&sa->sin6_addr.in6_u.u6_addr16)[6]), ntohs(((unsigned short *)&sa->sin6_addr.in6_u.u6_addr16)[7]), #elif HAVE_IP6_SOCKADDR==4 (sa->sin6_addr._S6_un._S6_u8[0]<<8)|(sa->sin6_addr._S6_un._S6_u8[1]&0xff), (sa->sin6_addr._S6_un._S6_u8[2]<<8)|(sa->sin6_addr._S6_un._S6_u8[3]&0xff), (sa->sin6_addr._S6_un._S6_u8[4]<<8)|(sa->sin6_addr._S6_un._S6_u8[5]&0xff), (sa->sin6_addr._S6_un._S6_u8[6]<<8)|(sa->sin6_addr._S6_un._S6_u8[7]&0xff), (sa->sin6_addr._S6_un._S6_u8[8]<<8)|(sa->sin6_addr._S6_un._S6_u8[9]&0xff), (sa->sin6_addr._S6_un._S6_u8[10]<<8)|(sa->sin6_addr._S6_un._S6_u8[11]&0xff), (sa->sin6_addr._S6_un._S6_u8[12]<<8)|(sa->sin6_addr._S6_un._S6_u8[13]&0xff), (sa->sin6_addr._S6_un._S6_u8[14]<<8)|(sa->sin6_addr._S6_un._S6_u8[15]&0xff), #elif HAVE_IP6_SOCKADDR==5 ntohs(((unsigned short *)&sa->sin6_addr.__u6_addr.__u6_addr16)[0]), ntohs(((unsigned short *)&sa->sin6_addr.__u6_addr.__u6_addr16)[1]), ntohs(((unsigned short *)&sa->sin6_addr.__u6_addr.__u6_addr16)[2]), ntohs(((unsigned short *)&sa->sin6_addr.__u6_addr.__u6_addr16)[3]), ntohs(((unsigned short *)&sa->sin6_addr.__u6_addr.__u6_addr16)[4]), ntohs(((unsigned short *)&sa->sin6_addr.__u6_addr.__u6_addr16)[5]), ntohs(((unsigned short *)&sa->sin6_addr.__u6_addr.__u6_addr16)[6]), ntohs(((unsigned short *)&sa->sin6_addr.__u6_addr.__u6_addr16)[7]), #endif ntohs(sa->sin6_port)) >= blen) { Warn("sockaddr_inet6_info(): buffer too short"); } return buff; } #endif /* WITH_IP6 */ #if HAVE_GETGROUPLIST || (defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)) /* fills the list with the supplementary group ids of user. caller passes size of list in ngroups, function returns number of groups in ngroups. function returns 0 if 0 or more groups were found, or 1 if the list is too short. */ int getusergroups(const char *user, gid_t *list, int *ngroups) { #if HAVE_GETGROUPLIST /* we prefer getgrouplist because it may be much faster with many groups, but it is not standard */ gid_t grp, twogrps[2]; int two = 2; /* getgrouplist requires to pass an extra group id, typically the users primary group, that is then added to the supplementary group list. We don't want such an additional group in the result, but there is not "unspecified" gid value available. Thus we try to find an abitrary supplementary group id that we then pass in a second call to getgrouplist. */ grp = 0; Getgrouplist(user, grp, twogrps, &two); if (two == 1) { /* either user has just this supp group, or none; we try another id */ grp = 1; two = 2; Getgrouplist(user, grp, twogrps, &two); if (two == 1) { /* user has no supp group */ *ngroups = 0; return 0; } /* user has just the first tried group */ *ngroups = 1; list[0] = grp; return 0; } /* find the first supp group that is not our grp, and use its id */ if (twogrps[0] == grp) { grp = twogrps[1]; } else { grp = twogrps[0]; } if (Getgrouplist(user, grp, list, ngroups) < 0) { return 1; } return 0; #elif defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT) /* this is standard (POSIX) but may be slow */ struct group *grp; int i = 0; setgrent(); while (grp = getgrent()) { char **gusr = grp->gr_mem; while (*gusr) { if (!strcmp(*gusr, user)) { if (i == *ngroups) return 1; list[i++] = grp->gr_gid; break; } ++gusr; } } endgrent(); *ngroups = i; return 0; #endif /* HAVE_SETGRENT... */ } #endif #if !HAVE_HSTRERROR const char *hstrerror(int err) { static const char *h_messages[] = { "success", "authoritative answer not found", "non-authoritative, host not found, or serverfail", "Host name lookup failure", /* "non recoverable error" */ "valid name, no data record of requested type" }; assert(HOST_NOT_FOUND==1); assert(TRY_AGAIN==2); assert(NO_RECOVERY==3); assert(NO_DATA==4); if ((err < 0) || err > sizeof(h_messages)/sizeof(const char *)) { return ""; } return h_messages[err]; } #endif /* !HAVE_HSTRERROR */ /* this function behaves like poll(). It tries to do so even when the poll() system call is not available. */ /* note: glibc 5.4 does not know nfds_t */ int xiopoll(struct pollfd fds[], unsigned long nfds, struct timeval *timeout) { int i, n = 0; int result = 0; while (true) { /* should be if (), but we want to break */ fd_set readfds; fd_set writefds; fd_set exceptfds; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); for (i = 0; i < nfds; ++i) { fds[i].revents = 0; if (fds[i].fd < 0) { continue; } if (fds[i].fd > FD_SETSIZE) { break; /* use poll */ } if (fds[i].events & POLLIN) { FD_SET(fds[i].fd, &readfds); n = MAX(n, fds[i].fd); } if (fds[i].events & POLLOUT) { FD_SET(fds[i].fd, &writefds); n = MAX(n, fds[i].fd); } } if (i < nfds) { break; /* use poll */ } result = Select(n+1, &readfds, &writefds, &exceptfds, timeout); if (result < 0) { return result; } for (i = 0; i < nfds; ++i) { if (fds[i].fd < 0) { continue; } if ((fds[i].events & POLLIN) && FD_ISSET(fds[i].fd, &readfds)) { fds[i].revents |= POLLIN; ++result; } if ((fds[i].events & POLLOUT) && FD_ISSET(fds[i].fd, &writefds)) { fds[i].revents |= POLLOUT; ++result; } } return result; } #if HAVE_POLL { int ms = 0; if (timeout == NULL) { ms = -1; } else { ms = 1000*timeout->tv_sec + timeout->tv_usec/1000; } /*! timeout */ return Poll(fds, nfds, ms); #else /* HAVE_POLL */ } else { Error("poll() not available"); return -1; #endif /* !HAVE_POLL */ } } #if WITH_TCP || WITH_UDP /* returns port in network byte order; ipproto==IPPROTO_UDP resolves as UDP service, every other value resolves as TCP */ int parseport(const char *portname, int ipproto) { struct servent *se; char *extra; int result; if (isdigit(portname[0]&0xff)) { result = htons(strtoul(portname, &extra, 0)); if (*extra != '\0') { Error3("parseport(\"%s\", %d): extra trailing data \"%s\"", portname, ipproto, extra); } return result; } if ((se = getservbyname(portname, ipproto==IPPROTO_UDP?"udp":"tcp")) == NULL) { Error2("cannot resolve service \"%s/%d\"", portname, ipproto); return 0; } return se->s_port; } #endif /* WITH_TCP || WITH_UDP */ #if WITH_IP4 || WITH_IP6 || WITH_INTERFACE /* check the systems interfaces for ifname and return its index or -1 if no interface with this name was found The system calls require an arbitrary socket; the calling program may provide one in anysock to avoid creation of a dummy socket. anysock must be <0 if it does not specify a socket fd. */ int ifindexbyname(const char *ifname, int anysock) { /* Linux: man 7 netdevice */ /* FreeBSD: man 4 networking */ /* Solaris: man 7 if_tcp */ #if defined(HAVE_STRUCT_IFREQ) && defined(SIOCGIFCONF) && defined(SIOCGIFINDEX) /* currently we support Linux, FreeBSD; not Solaris */ #define IFBUFSIZ 32*sizeof(struct ifreq) /*1024*/ int s; struct ifreq ifr; if (ifname[0] == '\0') { return -1; } if (anysock >= 0) { s = anysock; } else if ((s = Socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { Error1("socket(PF_INET, SOCK_DGRAM, IPPROTO_IP): %s", strerror(errno)); return -1; } strncpy(ifr.ifr_name, ifname, IFNAMSIZ); /* ok */ if (Ioctl(s, SIOCGIFINDEX, &ifr) < 0) { Info3("ioctl(%d, SIOCGIFINDEX, {\"%s\"}): %s", s, ifr.ifr_name, strerror(errno)); Close(s); return -1; } Close(s); #if HAVE_STRUCT_IFREQ_IFR_INDEX Info3("ioctl(%d, SIOCGIFINDEX, {\"%s\"}) -> { %d }", s, ifname, ifr.ifr_index); return ifr.ifr_index; #elif HAVE_STRUCT_IFREQ_IFR_IFINDEX Info3("ioctl(%d, SIOCGIFINDEX, {\"%s\"}) -> { %d }", s, ifname, ifr.ifr_ifindex); return ifr.ifr_ifindex; #endif /* HAVE_STRUCT_IFREQ_IFR_IFINDEX */ #else /* !defined(HAVE_ STRUCT_IFREQ) && defined(SIOCGIFCONF) && defined(SIOCGIFINDEX) */ return -1; #endif /* !defined(HAVE_ STRUCT_IFREQ) && defined(SIOCGIFCONF) && defined(SIOCGIFINDEX) */ } #endif /* WITH_IP4 || WITH_IP6 || WITH_INTERFACE */ #if WITH_IP4 || WITH_IP6 || WITH_INTERFACE /* like ifindexbyname(), but also allows the index number as input - in this case it does not lookup the index. writes the resulting index to *ifindex and returns 0, or returns -1 on error */ int ifindex(const char *ifname, unsigned int *ifindex, int anysock) { char *endptr; long int val; if (ifname[0] == '\0') { return -1; } val = strtol(ifname, &endptr, 0); if (endptr[0] == '\0') { *ifindex = val; return 0; } if ((val = ifindexbyname(ifname, anysock)) < 0) { return -1; } *ifindex = val; return 0; } #endif /* WITH_IP4 || WITH_IP6 || WITH_INTERFACE */ int _xiosetenv(const char *envname, const char *value, int overwrite, const char *sep) { char *oldval; char *newval; if (overwrite >= 2 && (oldval = getenv(envname)) != NULL) { size_t newlen = strlen(oldval)+strlen(sep)+strlen(value)+1; if ((newval = Malloc(newlen+1)) == NULL) { return -1; } snprintf(newval, newlen+1, "%s%s%s", oldval, sep, value); } else { newval = (char *)value; } if (Setenv(envname, newval, overwrite) < 0) { Warn3("setenv(\"%s\", \"%s\", 1): %s", envname, value, strerror(errno)); #if HAVE_UNSETENV Unsetenv(envname); /* dont want to have a wrong value */ #endif return -1; } return 0; } /* constructs an environment variable whose name is built from socats uppercase program name, and underscore and varname; if the variable of this name already exists arg overwrite determines: 0: keep old value 1: overwrite with new value 2: append to old value, separated by *sep a non zero value of overwrite lets the old value be overwritten. returns 0 on success or <0 if an error occurred. */ int xiosetenv(const char *varname, const char *value, int overwrite, const char *sep) { # define XIO_ENVNAMELEN 256 const char *progname; char envname[XIO_ENVNAMELEN]; size_t i, l; progname = diag_get_string('p'); envname[0] = '\0'; strncat(envname, progname, XIO_ENVNAMELEN-1); l = strlen(envname); for (i = 0; i < l; ++i) envname[i] = toupper(envname[i]); strncat(envname+l, "_", XIO_ENVNAMELEN-l-1); l += 1; strncat(envname+l, varname, XIO_ENVNAMELEN-l-1); return _xiosetenv(envname, value, overwrite, sep); # undef ENVNAMELEN } int xiosetenv2(const char *varname, const char *varname2, const char *value, int overwrite, const char *sep) { # define XIO_ENVNAMELEN 256 const char *progname; char envname[XIO_ENVNAMELEN]; size_t i, l; progname = diag_get_string('p'); envname[0] = '\0'; strncat(envname, progname, XIO_ENVNAMELEN-1); l = strlen(progname); strncat(envname+l, "_", XIO_ENVNAMELEN-l-1); l += 1; strncat(envname+l, varname, XIO_ENVNAMELEN-l-1); l += strlen(envname+l); strncat(envname+l, "_", XIO_ENVNAMELEN-l-1); l += 1; strncat(envname+l, varname2, XIO_ENVNAMELEN-l-1); l += strlen(envname+l); for (i = 0; i < l; ++i) envname[i] = toupper(envname[i]); return _xiosetenv(envname, value, overwrite, sep); # undef XIO_ENVNAMELEN } int xiosetenv3(const char *varname, const char *varname2, const char *varname3, const char *value, int overwrite, const char *sep) { # define XIO_ENVNAMELEN 256 const char *progname; char envname[XIO_ENVNAMELEN]; size_t i, l; progname = diag_get_string('p'); envname[0] = '\0'; strncat(envname, progname, XIO_ENVNAMELEN-1); l = strlen(progname); strncat(envname+l, "_", XIO_ENVNAMELEN-l-1); l += 1; strncat(envname+l, varname, XIO_ENVNAMELEN-l-1); l += strlen(envname+l); strncat(envname+l, "_", XIO_ENVNAMELEN-l-1); l += 1; strncat(envname+l, varname2, XIO_ENVNAMELEN-l-1); l += strlen(envname+l); strncat(envname+l, "_", XIO_ENVNAMELEN-l-1); l += 1; strncat(envname+l, varname3, XIO_ENVNAMELEN-l-1); l += strlen(envname+l); for (i = 0; i < l; ++i) envname[i] = toupper(envname[i]); return _xiosetenv(envname, value, overwrite, sep); # undef XIO_ENVNAMELEN } /* like xiosetenv(), but uses an unsigned long value */ int xiosetenvulong(const char *varname, unsigned long value, int overwrite) { # define XIO_LONGLEN 21 /* should suffice for 64bit longs with \0 */ char envbuff[XIO_LONGLEN]; snprintf(envbuff, XIO_LONGLEN, "%lu", value); return xiosetenv(varname, envbuff, overwrite, NULL); # undef XIO_LONGLEN } /* like xiosetenv(), but uses an unsigned short value */ int xiosetenvushort(const char *varname, unsigned short value, int overwrite) { # define XIO_SHORTLEN 11 /* should suffice for 32bit shorts with \0 */ char envbuff[XIO_SHORTLEN]; snprintf(envbuff, XIO_SHORTLEN, "%hu", value); return xiosetenv(varname, envbuff, overwrite, NULL); # undef XIO_SHORTLEN } socat-1.7.3.1/xio-progcall.h0000644000201000020100000000172311453022152015327 0ustar gerhardgerhard/* source: xio-progcall.h */ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_progcall_h_included #define __xio_progcall_h_included 1 extern const struct optdesc opt_fdin; extern const struct optdesc opt_fdout; extern const struct optdesc opt_path; extern const struct optdesc opt_pipes; extern const struct optdesc opt_pty; extern const struct optdesc opt_openpty; extern const struct optdesc opt_ptmx; extern const struct optdesc opt_stderr; extern const struct optdesc opt_nofork; extern const struct optdesc opt_sighup; extern const struct optdesc opt_sigint; extern const struct optdesc opt_sigquit; extern int _xioopen_foxec(int rw, /* O_RDONLY etc. */ struct single *fd, unsigned groups, struct opt **opts, int *duptostderr ); extern int setopt_path(struct opt *opts, char **path); extern int _xioopen_redir_stderr(int fdo); #endif /* !defined(__xio_progcall_h_included) */ socat-1.7.3.1/xio-unix.c0000644000201000020100000005133712460670272014523 0ustar gerhardgerhard/* source: xio-unix.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of UNIX socket type */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-socket.h" #include "xio-listen.h" #include "xio-unix.h" #include "xio-named.h" #if WITH_UNIX /* to avoid unneccessary "live" if () conditionals when no abstract support is compiled in (or at least to give optimizing compilers a good chance) we need a constant that can be used in C expressions */ #if WITH_ABSTRACT_UNIXSOCKET # define ABSTRACT 1 #else # define ABSTRACT 0 #endif static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned 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, unsigned 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, unsigned 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, unsigned 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, unsigned 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, unsigned groups, int abstract, int dummy2, int dummy3); /* 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 unsused */ const struct addrdesc xioaddr_unix_connect = { "unix-connect", 3, xioopen_unix_connect, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; #if WITH_LISTEN const struct addrdesc xioaddr_unix_listen = { "unix-listen", 3, xioopen_unix_listen, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":") }; #endif /* WITH_LISTEN */ const struct addrdesc xioaddr_unix_sendto = { "unix-sendto", 3, xioopen_unix_sendto, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; const struct addrdesc xioaddr_unix_recvfrom= { "unix-recvfrom", 3, xioopen_unix_recvfrom, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, 0, 0, 0 HELP(":") }; const struct addrdesc xioaddr_unix_recv = { "unix-recv", 1, xioopen_unix_recv, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; const struct addrdesc xioaddr_unix_client = { "unix-client", 3, xioopen_unix_client, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; #if WITH_ABSTRACT_UNIXSOCKET const struct addrdesc xioaddr_abstract_connect = { "abstract-connect", 3, xioopen_unix_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; #if WITH_LISTEN const struct addrdesc xioaddr_abstract_listen = { "abstract-listen", 3, xioopen_unix_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 1, 0, 0 HELP(":") }; #endif /* WITH_LISTEN */ const struct addrdesc xioaddr_abstract_sendto = { "abstract-sendto", 3, xioopen_unix_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; const struct addrdesc xioaddr_abstract_recvfrom= { "abstract-recvfrom", 3, xioopen_unix_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, 1, 0, 0 HELP(":") }; const struct addrdesc xioaddr_abstract_recv = { "abstract-recv", 1, xioopen_unix_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; const struct addrdesc xioaddr_abstract_client = { "abstract-client", 3, xioopen_unix_client, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; #endif /* WITH_ABSTRACT_UNIXSOCKET */ const struct optdesc xioopt_unix_tightsocklen = { "unix-tightsocklen", "tightsocklen", OPT_UNIX_TIGHTSOCKLEN, GROUP_SOCK_UNIX, PH_PREBIND, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.un.tight), XIO_SIZEOF(para.socket.un.tight) }; /* fills the socket address struct and returns its effective length. abstract is usually 0; != 0 generates an abstract socket address on Linux. tight!=0 calculates the resulting length from the path length, not from the structures length; this is more common (see option unix-tightsocklen) the struct need not be initialized when calling this function. */ socklen_t xiosetunix(int pf, struct sockaddr_un *saun, const char *path, bool abstract, bool tight) { size_t pathlen; socklen_t len; socket_un_init(saun); #ifdef WITH_ABSTRACT_UNIXSOCKET if (abstract) { if ((pathlen = strlen(path)) >= sizeof(saun->sun_path)) { Warn2("socket address "F_Zu" characters long, truncating to "F_Zu"", pathlen+1, sizeof(saun->sun_path)); } saun->sun_path[0] = '\0'; /* so it's abstract */ strncpy(saun->sun_path+1, path, sizeof(saun->sun_path)-1); /* ok */ if (tight) { len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+ MIN(pathlen+1, sizeof(saun->sun_path)); #if HAVE_STRUCT_SOCKADDR_SALEN saun->sun_len = len; #endif } else { len = sizeof(struct sockaddr_un); } return len; } #endif /* WITH_ABSTRACT_UNIXSOCKET */ if ((pathlen = strlen(path)) > sizeof(saun->sun_path)) { Warn2("unix socket address "F_Zu" characters long, truncating to "F_Zu"", pathlen, sizeof(saun->sun_path)); } strncpy(saun->sun_path, path, sizeof(saun->sun_path)); /* ok */ if (tight) { len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+ MIN(pathlen, sizeof(saun->sun_path)); #if HAVE_STRUCT_SOCKADDR_SALEN saun->sun_len = len; #endif } else { len = sizeof(struct sockaddr_un); } return len; } #if WITH_LISTEN static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) { /* we expect the form: filename */ const char *name; xiosingle_t *xfd = &xxfd->stream; int pf = PF_UNIX; int socktype = SOCK_STREAM; int protocol = 0; struct sockaddr_un us; socklen_t uslen; struct opt *opts0 = NULL; pid_t pid = Getpid(); bool opt_unlink_early = false; bool opt_unlink_close = true; int result; if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); return STAT_NORETRY; } name = argv[1]; xfd->para.socket.un.tight = true; retropt_socket_pf(opts, &pf); xfd->howtoend = END_SHUTDOWN; if (!(ABSTRACT && 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(-1, opts, PH_INIT); applyopts_named(name, opts, PH_EARLY); /* umask! */ applyopts_offset(xfd, opts); applyopts(-1, opts, PH_EARLY); uslen = xiosetunix(pf, &us, name, abstract, xfd->para.socket.un.tight); if (!(ABSTRACT && abstract)) { if (opt_unlink_early) { if (Unlink(name) < 0) { if (errno == ENOENT) { Warn2("unlink(\"%s\"): %s", name, strerror(errno)); } else { Error2("unlink(\"%s\"): %s", name, strerror(errno)); } } } else { struct stat buf; if (Lstat(name, &buf) == 0) { Error1("\"%s\" exists", name); return STAT_RETRYLATER; } } if (opt_unlink_close) { if ((xfd->unlink_close = strdup(name)) == NULL) { Error1("strdup(\"%s\"): out of memory", name); } xfd->opt_unlink_close = true; } /* trying to set user-early, perm-early etc. here is useless because file system entry is available only past bind() call. */ } opts0 = copyopts(opts, GROUP_ALL); /* this may fork() */ if ((result = xioopen_listen(xfd, xioflags, (struct sockaddr *)&us, uslen, opts, opts0, pf, socktype, protocol)) != 0) return result; if (!(ABSTRACT && abstract)) { if (opt_unlink_close) { if (pid != Getpid()) { /* in a child process - do not unlink-close here! */ xfd->opt_unlink_close = false; } } } return 0; } #endif /* WITH_LISTEN */ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) { /* we expect the form: filename */ const char *name; struct single *xfd = &xxfd->stream; int pf = PF_UNIX; int socktype = SOCK_STREAM; int protocol = 0; struct sockaddr_un them, us; socklen_t themlen, uslen = sizeof(us); bool needbind = false; bool opt_unlink_close = false; int result; if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); return STAT_NORETRY; } name = argv[1]; xfd->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(-1, opts, PH_INIT); applyopts_offset(xfd, opts); applyopts(-1, opts, PH_EARLY); themlen = xiosetunix(pf, &them, name, abstract, xfd->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, (struct sockaddr *)&us, &uslen, (abstract<<1)|xfd->para.socket.un.tight, 0, 0) == STAT_OK) { needbind = true; } if (opt_unlink_close) { if ((xfd->unlink_close = strdup(name)) == NULL) { Error1("strdup(\"%s\"): out of memory", name); } xfd->opt_unlink_close = true; } if ((result = xioopen_connect(xfd, needbind?(struct sockaddr *)&us:NULL, uslen, (struct sockaddr *)&them, themlen, opts, pf, socktype, protocol, false)) != 0) { return result; } if ((result = _xio_openlate(xfd, 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, unsigned groups, int abstract, int dummy, int dummy3) { /* we expect the form: filename */ const char *name; xiosingle_t *xfd = &xxfd->stream; int pf = PF_UNIX; int socktype = SOCK_DGRAM; int protocol = 0; union sockaddr_union us; socklen_t uslen = sizeof(us); bool needbind = false; bool opt_unlink_close = false; if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); return STAT_NORETRY; } name = argv[1]; xfd->para.socket.un.tight = true; retropt_socket_pf(opts, &pf); xfd->howtoend = END_SHUTDOWN; applyopts_offset(xfd, opts); xfd->salen = xiosetunix(pf, &xfd->peersa.un, name, abstract, xfd->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); } xfd->dtype = XIODATA_RECVFROM; if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, (abstract<<1)| xfd->para.socket.un.tight, 0, 0) == STAT_OK) { needbind = true; } if (opt_unlink_close) { if ((xfd->unlink_close = strdup(name)) == NULL) { Error1("strdup(\"%s\"): out of memory", name); } xfd->opt_unlink_close = true; } if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); return _xioopen_dgram_sendto(needbind?&us:NULL, uslen, opts, xioflags, xfd, groups, pf, socktype, protocol); } static int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) { /* we expect the form: filename */ const char *name; xiosingle_t *xfd = &xxfd->stream; int pf = PF_UNIX; int socktype = SOCK_DGRAM; int protocol = 0; struct sockaddr_un us; socklen_t uslen; bool needbind = true; bool opt_unlink_early = false; bool opt_unlink_close = true; if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); return STAT_NORETRY; } name = argv[1]; xfd->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(-1, opts, PH_INIT); applyopts_named(name, opts, PH_EARLY); /* umask! */ applyopts_offset(xfd, opts); if (!(ABSTRACT && 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(-1, opts, PH_EARLY); uslen = xiosetunix(pf, &us, name, abstract, xfd->para.socket.un.tight); #if 0 if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen, (abstract<<1)|xfd->para.socket.un.tight, 0, 0) == STAT_OK) { } #endif if (!(ABSTRACT && abstract)) { if (opt_unlink_early) { if (Unlink(name) < 0) { if (errno == ENOENT) { Warn2("unlink(\"%s\"): %s", name, strerror(errno)); } else { Error2("unlink(\"%s\"): %s", name, strerror(errno)); } } } else { struct stat buf; if (Lstat(name, &buf) == 0) { Error1("\"%s\" exists", name); return STAT_RETRYLATER; } } if (opt_unlink_close) { if ((xfd->unlink_close = strdup(name)) == NULL) { Error1("strdup(\"%s\"): out of memory", name); } xfd->opt_unlink_close = true; } /* trying to set user-early, perm-early etc. here is useless because file system entry is available only past bind() call. */ } applyopts_named(name, opts, PH_EARLY); /* umask! */ xfd->para.socket.la.soa.sa_family = pf; xfd->dtype = XIODATA_RECVFROM_ONE; /* this may fork */ return _xioopen_dgram_recvfrom(xfd, 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, unsigned groups, int abstract, int dummy2, int dummy3) { /* we expect the form: filename */ const char *name; xiosingle_t *xfd = &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 = true; int result; if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); return STAT_NORETRY; } name = argv[1]; xfd->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(-1, opts, PH_INIT); applyopts_named(name, opts, PH_EARLY); /* umask! */ applyopts_offset(xfd, opts); if (!(ABSTRACT && 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(-1, opts, PH_EARLY); uslen = xiosetunix(pf, &us.un, name, abstract, xfd->para.socket.un.tight); #if 0 if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, (abstract<<1)|xfd->para.socket.un.tight, 0, 0) == STAT_OK) { } #endif if (!(ABSTRACT && abstract)) { if (opt_unlink_early) { if (Unlink(name) < 0) { if (errno == ENOENT) { Warn2("unlink(\"%s\"): %s", name, strerror(errno)); } else { Error2("unlink(\"%s\"): %s", name, strerror(errno)); } } } else { struct stat buf; if (Lstat(name, &buf) == 0) { Error1("\"%s\" exists", name); return STAT_RETRYLATER; } } if (opt_unlink_close) { if ((xfd->unlink_close = strdup(name)) == NULL) { Error1("strdup(\"%s\"): out of memory", name); } xfd->opt_unlink_close = true; } } applyopts_named(name, opts, PH_EARLY); /* umask! */ xfd->para.socket.la.soa.sa_family = pf; xfd->dtype = XIODATA_RECV; result = _xioopen_dgram_recv(xfd, xioflags, &us.soa, uslen, opts, pf, socktype, protocol, E_ERROR); return result; } static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) { /* we expect the form: filename */ if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); } return _xioopen_unix_client(&xxfd->stream, xioflags, groups, abstract, opts, argv[1]); } /* establishes communication with an existing UNIX type socket. supports stream and datagram socket types: first tries to connect(), but when this fails it falls back to sendto(). applies and consumes the following option: PH_INIT, PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE, ?PH_CONNECT OFUNC_OFFSET, OPT_PROTOCOL_FAMILY, OPT_UNIX_TIGHTSOCKLEN, OPT_UNLINK_CLOSE, OPT_BIND, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_CLOEXEC, OPT_USER, OPT_GROUP, ?OPT_FORK, */ int _xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups, int abstract, struct opt *opts, const char *name) { int pf = PF_UNIX; int socktype = 0; /* to be determined by server socket type */ int protocol = 0; union sockaddr_union them, us; socklen_t themlen, uslen = sizeof(us); bool needbind = false; bool opt_unlink_close = false; struct opt *opts0; int result; xfd->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(-1, opts, PH_INIT); applyopts_offset(xfd, opts); applyopts(-1, opts, PH_EARLY); themlen = xiosetunix(pf, &them.un, name, abstract, xfd->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, 0, 0) != STAT_NOACTION) { needbind = true; } if (opt_unlink_close) { if ((xfd->unlink_close = strdup(name)) == NULL) { Error1("strdup(\"%s\"): out of memory", name); } xfd->opt_unlink_close = true; } /* save options, because we might have to start again */ opts0 = copyopts(opts, GROUP_ALL); /* xfd->dtype = DATA_STREAM; // is default */ if ((result = xioopen_connect(xfd, needbind?(struct sockaddr *)&us:NULL, uslen, (struct sockaddr *)&them, themlen, opts, pf, socktype?socktype:SOCK_STREAM, protocol, false)) != 0) { if (errno == EPROTOTYPE) { if (needbind) { Unlink(us.un.sun_path); } dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0; xfd->peersa = them; xfd->salen = sizeof(struct sockaddr_un); if ((result = _xioopen_dgram_sendto(needbind?&us:NULL, uslen, opts, xioflags, xfd, groups, pf, socktype?socktype:SOCK_DGRAM, protocol)) != 0) { return result; } xfd->dtype = XIODATA_RECVFROM; } } if ((result = _xio_openlate(xfd, opts)) < 0) { return result; } return 0; } /* returns information that can be used for constructing an environment variable describing the socket address. if idx is 0, this function writes "ADDR" into namebuff and the path into valuebuff, and returns 0 (which means that no more info is there). if idx is != 0, it returns -1 namelen and valuelen contain the max. allowed length of output chars in the respective buffer. on error this function returns -1. */ int xiosetsockaddrenv_unix(int idx, char *namebuff, size_t namelen, char *valuebuff, size_t valuelen, struct sockaddr_un *sa, socklen_t salen, int ipproto) { if (idx != 0) { return -1; } strcpy(namebuff, "ADDR"); sockaddr_unix_info(sa, salen, valuebuff, valuelen); return 0; } #endif /* WITH_UNIX */ socat-1.7.3.1/proxy.sh0000755000201000020100000000321012311110206014257 0ustar gerhardgerhard#! /bin/bash # source: proxy.sh # Copyright Gerhard Rieger 2003-2004 # Published under the GNU General Public License V.2, see file COPYING # perform primitive simulation of a proxy server. # accepts and answers correct HTTP CONNECT requests on stdio, and tries to # establish the connection to the given server. # it is required for socats test.sh # for TCP, use this script as: # socat tcp-l:8080,reuseaddr,fork exec:"proxy.sh",nofork if [ -z "$SOCAT" ]; then if type socat >/dev/null 2>&1; then SOCAT=socat else SOCAT="./socat" fi fi if [ $(echo "x\c") = "x" ]; then E="" elif [ $(echo -e "x\c") = "x" ]; then E="-e" else echo "cannot suppress trailing newline on echo" >&2 exit 1 fi ECHO="echo $E" CR=$($ECHO "\r") #echo "CR=$($ECHO "$CR\c" |od -c)" >&2 case `uname` in HP-UX|OSF1) # their cats are too stupid to work with unix domain sockets CAT="$SOCAT -u stdin stdout" ;; *) CAT=cat ;; esac SPACES=" " while [ -n "$1" ]; do case "$1" in -w) n="$2"; while [ "$n" -gt 0 ]; do SPACES="$SPACES "; n=$((n-1)); done shift ;; #-s) STAT="$2"; shift ;; esac shift done # read and parse HTTP request read l if echo "$l" |egrep '^CONNECT +[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+ +HTTP/1.[01]' >/dev/null then : go on below else $ECHO "HTTP/1.0${SPACES}500 Bad Request$CR" $ECHO "$CR" exit fi # extract target server name/address s=`echo $l |awk '{print($2);}'` # read more headers until empty line while [ "$l" != "$CR" ]; do read l done # send status $ECHO "HTTP/1.0${SPACES}200 OK$CR" # send empty line $ECHO "$CR" # perform proxy (relay) function exec $SOCAT $SOCAT_OPTS - tcp:$s socat-1.7.3.1/xio-sctp.h0000644000201000020100000000124511453022152014474 0ustar gerhardgerhard/* source: xio-sctp.h */ /* Copyright Gerhard Rieger 2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_sctp_h_included #define __xio_sctp_h_included 1 extern const struct addrdesc addr_sctp_connect; extern const struct addrdesc addr_sctp_listen; extern const struct addrdesc addr_sctp4_connect; extern const struct addrdesc addr_sctp4_listen; extern const struct addrdesc addr_sctp6_connect; extern const struct addrdesc addr_sctp6_listen; extern const struct optdesc opt_sctp_nodelay; extern const struct optdesc opt_sctp_maxseg; extern const struct optdesc opt_sctp_maxseg_late; #endif /* !defined(__xio_sctp_h_included) */ socat-1.7.3.1/xio-tun.h0000644000201000020100000000240711453022152014332 0ustar gerhardgerhard/* source: xio-tun.h */ /* Copyright Gerhard Rieger 2006-2007 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_tun_h_included #define __xio_tun_h_included 1 extern const struct optdesc opt_tun_device; extern const struct optdesc opt_tun_name; extern const struct optdesc opt_tun_type; extern const struct optdesc opt_iff_no_pi; extern const struct optdesc opt_interface_addr; extern const struct optdesc opt_interface_netmask; extern const struct optdesc opt_iff_up; extern const struct optdesc opt_iff_broadcast; extern const struct optdesc opt_iff_debug; extern const struct optdesc opt_iff_loopback; extern const struct optdesc opt_iff_pointopoint; extern const struct optdesc opt_iff_notrailers; extern const struct optdesc opt_iff_running; extern const struct optdesc opt_iff_noarp; extern const struct optdesc opt_iff_promisc; extern const struct optdesc opt_iff_allmulti; extern const struct optdesc opt_iff_master; extern const struct optdesc opt_iff_slave; extern const struct optdesc opt_iff_multicast; extern const struct optdesc opt_iff_portsel; extern const struct optdesc opt_iff_automedia; /*extern const struct optdesc opt_iff_dynamic;*/ extern const struct addrdesc xioaddr_tun; #endif /* !defined(__xio_tun_h_included) */ socat-1.7.3.1/nestlex.h0000644000201000020100000000172512652637410014426 0ustar gerhardgerhard/* source: nestlex.h */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __nestlex_h_included #define __nestlex_h_included 1 extern int nestlex(const char **addr, /* input string; aft points to end token */ char **token, /* output token; aft points to first unwritten char (caller might want to set it to \0) */ size_t *len, /* remaining bytes in token space (incl. \0) */ const char *ends[], /* list of end strings */ const char *hquotes[],/* list of strings that quote (hard qu.) */ const char *squotes[],/* list of strings that quote softly */ const char *nests[],/* list of strings that start nesting; every second one is matching end */ bool dropquotes, /* drop the outermost quotes */ bool c_esc, /* solve C char escapes: \n \t \0 etc */ bool html_esc /* solve HTML char escapes: %0d %08 etc */ ); #endif /* !defined(__nestlex_h_included) */ socat-1.7.3.1/xio-socket.c0000644000201000020100000021275712460670272015035 0ustar gerhardgerhard/* source: xio-socket.c */ /* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for socket related functions, and the implementation of generic socket addresses */ #include "xiosysincludes.h" #if _WITH_SOCKET #include "xioopen.h" #include "xio-ascii.h" #include "xio-socket.h" #include "xio-named.h" #include "xio-unix.h" #if WITH_IP4 #include "xio-ip4.h" #endif /* WITH_IP4 */ #if WITH_IP6 #include "xio-ip6.h" #endif /* WITH_IP6 */ #include "xio-ip.h" #include "xio-listen.h" #include "xio-ipapp.h" /*! not clean */ #include "xio-tcpwrap.h" static int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned 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, unsigned 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, unsigned 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, unsigned 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, unsigned 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, unsigned groups, int dumy1, int dummy2, int dummy3); static int _xioopen_socket_sendto(const char *pfname, const char *type, const char *proto, const char *address, struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups); static int xiolog_ancillary_socket(struct cmsghdr *cmsg, int *num, char *typbuff, int typlen, char *nambuff, int namlen, char *envbuff, int envlen, char *valbuff, int vallen); #if WITH_GENERICSOCKET /* generic socket addresses */ const struct addrdesc xioaddr_socket_connect = { "socket-connect", 1, xioopen_socket_connect, GROUP_FD|GROUP_SOCKET|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":::") }; #if WITH_LISTEN const struct addrdesc xioaddr_socket_listen = { "socket-listen", 1, xioopen_socket_listen, GROUP_FD|GROUP_SOCKET|GROUP_LISTEN|GROUP_RANGE|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":::") }; #endif /* WITH_LISTEN */ const struct addrdesc xioaddr_socket_sendto = { "socket-sendto", 3, xioopen_socket_sendto, GROUP_FD|GROUP_SOCKET, 0, 0, 0 HELP("::::") }; const struct addrdesc xioaddr_socket_datagram= { "socket-datagram", 3, xioopen_socket_datagram, GROUP_FD|GROUP_SOCKET|GROUP_RANGE, 0, 0, 0 HELP("::::") }; const struct addrdesc xioaddr_socket_recvfrom= { "socket-recvfrom", 3, xioopen_socket_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_RANGE|GROUP_CHILD, 0, 0, 0 HELP("::::") }; const struct addrdesc xioaddr_socket_recv = { "socket-recv", 1, xioopen_socket_recv, GROUP_FD|GROUP_SOCKET|GROUP_RANGE, 0, 0, 0 HELP("::::") }; #endif /* WITH_GENERICSOCKET */ /* the following options apply not only to generic socket addresses but to all addresses that have anything to do with sockets */ const struct optdesc opt_so_debug = { "so-debug", "debug", OPT_SO_DEBUG, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_DEBUG }; #ifdef SO_ACCEPTCONN /* AIX433 */ const struct optdesc opt_so_acceptconn={ "so-acceptconn","acceptconn",OPT_SO_ACCEPTCONN,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_ACCEPTCONN}; #endif /* SO_ACCEPTCONN */ const struct optdesc opt_so_broadcast= { "so-broadcast", "broadcast", OPT_SO_BROADCAST,GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_BROADCAST}; const struct optdesc opt_so_reuseaddr= { "so-reuseaddr", "reuseaddr", OPT_SO_REUSEADDR,GROUP_SOCKET, PH_PREBIND, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_REUSEADDR}; const struct optdesc opt_so_keepalive= { "so-keepalive", "keepalive", OPT_SO_KEEPALIVE,GROUP_SOCKET, PH_FD, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_KEEPALIVE}; #if HAVE_STRUCT_LINGER const struct optdesc opt_so_linger = { "so-linger", "linger", OPT_SO_LINGER, GROUP_SOCKET, PH_PASTSOCKET, TYPE_LINGER,OFUNC_SOCKOPT,SOL_SOCKET, SO_LINGER }; #else /* !HAVE_STRUCT_LINGER */ const struct optdesc opt_so_linger = { "so-linger", "linger", OPT_SO_LINGER, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_LINGER }; #endif /* !HAVE_STRUCT_LINGER */ const struct optdesc opt_so_oobinline= { "so-oobinline", "oobinline", OPT_SO_OOBINLINE,GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_OOBINLINE}; const struct optdesc opt_so_sndbuf = { "so-sndbuf", "sndbuf", OPT_SO_SNDBUF, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_SNDBUF}; const struct optdesc opt_so_sndbuf_late={ "so-sndbuf-late","sndbuf-late",OPT_SO_SNDBUF_LATE,GROUP_SOCKET,PH_LATE,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_SNDBUF }; const struct optdesc opt_so_rcvbuf = { "so-rcvbuf", "rcvbuf", OPT_SO_RCVBUF, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_RCVBUF}; const struct optdesc opt_so_rcvbuf_late={"so-rcvbuf-late","rcvbuf-late",OPT_SO_RCVBUF_LATE,GROUP_SOCKET,PH_LATE,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_RCVBUF }; const struct optdesc opt_so_error = { "so-error", "error", OPT_SO_ERROR, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_ERROR}; const struct optdesc opt_so_type = { "so-type", "type", OPT_SO_TYPE, GROUP_SOCKET, PH_SOCKET, TYPE_INT, OFUNC_SPEC, SOL_SOCKET, SO_TYPE }; const struct optdesc opt_so_dontroute= { "so-dontroute", "dontroute", OPT_SO_DONTROUTE,GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_DONTROUTE }; #ifdef SO_RCVLOWAT const struct optdesc opt_so_rcvlowat = { "so-rcvlowat", "rcvlowat", OPT_SO_RCVLOWAT, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_RCVLOWAT }; #endif #ifdef SO_RCVTIMEO const struct optdesc opt_so_rcvtimeo = { "so-rcvtimeo", "rcvtimeo", OPT_SO_RCVTIMEO, GROUP_SOCKET, PH_PASTSOCKET, TYPE_TIMEVAL,OFUNC_SOCKOPT,SOL_SOCKET,SO_RCVTIMEO }; #endif #ifdef SO_SNDLOWAT const struct optdesc opt_so_sndlowat = { "so-sndlowat", "sndlowat", OPT_SO_SNDLOWAT, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_SNDLOWAT }; #endif #ifdef SO_SNDTIMEO const struct optdesc opt_so_sndtimeo = { "so-sndtimeo", "sndtimeo", OPT_SO_SNDTIMEO, GROUP_SOCKET, PH_PASTSOCKET, TYPE_TIMEVAL,OFUNC_SOCKOPT,SOL_SOCKET,SO_SNDTIMEO }; #endif /* end of setsockopt options of UNIX98 standard */ #ifdef SO_AUDIT /* AIX 4.3.3 */ const struct optdesc opt_so_audit = { "so-audit", "audit", OPT_SO_AUDIT, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_AUDIT }; #endif /* SO_AUDIT */ #ifdef SO_ATTACH_FILTER const struct optdesc opt_so_attach_filter={"so-attach-filter","attachfilter",OPT_SO_ATTACH_FILTER,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_ATTACH_FILTER}; #endif #ifdef SO_DETACH_FILTER const struct optdesc opt_so_detach_filter={"so-detach-filter","detachfilter",OPT_SO_DETACH_FILTER,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_DETACH_FILTER}; #endif #ifdef SO_BINDTODEVICE /* Linux: man 7 socket */ const struct optdesc opt_so_bindtodevice={"so-bindtodevice","if",OPT_SO_BINDTODEVICE,GROUP_SOCKET,PH_PASTSOCKET,TYPE_NAME,OFUNC_SOCKOPT,SOL_SOCKET,SO_BINDTODEVICE}; #endif #ifdef SO_BSDCOMPAT const struct optdesc opt_so_bsdcompat= { "so-bsdcompat","bsdcompat",OPT_SO_BSDCOMPAT,GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_BSDCOMPAT }; #endif #ifdef SO_CKSUMRECV const struct optdesc opt_so_cksumrecv= { "so-cksumrecv","cksumrecv",OPT_SO_CKSUMRECV,GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_CKSUMRECV }; #endif /* SO_CKSUMRECV */ #ifdef SO_TIMESTAMP const struct optdesc opt_so_timestamp= { "so-timestamp","timestamp",OPT_SO_TIMESTAMP,GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_TIMESTAMP }; #endif #ifdef SO_KERNACCEPT /* AIX 4.3.3 */ const struct optdesc opt_so_kernaccept={ "so-kernaccept","kernaccept",OPT_SO_KERNACCEPT,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_KERNACCEPT}; #endif /* SO_KERNACCEPT */ #ifdef SO_NO_CHECK const struct optdesc opt_so_no_check = { "so-no-check", "nocheck",OPT_SO_NO_CHECK, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_NO_CHECK }; #endif #ifdef SO_NOREUSEADDR /* AIX 4.3.3 */ const struct optdesc opt_so_noreuseaddr={"so-noreuseaddr","noreuseaddr",OPT_SO_NOREUSEADDR,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET, SO_NOREUSEADDR}; #endif /* SO_NOREUSEADDR */ #ifdef SO_PASSCRED const struct optdesc opt_so_passcred = { "so-passcred", "passcred", OPT_SO_PASSCRED, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_PASSCRED}; #endif #ifdef SO_PEERCRED const struct optdesc opt_so_peercred = { "so-peercred", "peercred", OPT_SO_PEERCRED, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT3,OFUNC_SOCKOPT, SOL_SOCKET, SO_PEERCRED}; #endif #ifdef SO_PRIORITY const struct optdesc opt_so_priority = { "so-priority", "priority", OPT_SO_PRIORITY, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_PRIORITY}; #endif #ifdef SO_REUSEPORT /* AIX 4.3.3, BSD, HP-UX */ const struct optdesc opt_so_reuseport= { "so-reuseport","reuseport",OPT_SO_REUSEPORT,GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_REUSEPORT }; #endif /* defined(SO_REUSEPORT) */ #ifdef SO_SECURITY_AUTHENTICATION const struct optdesc opt_so_security_authentication={"so-security-authentication","securityauthentication",OPT_SO_SECURITY_AUTHENTICATION,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_SECURITY_AUTHENTICATION}; #endif #ifdef SO_SECURITY_ENCRYPTION_NETWORK const struct optdesc opt_so_security_encryption_network={"so-security-encryption-network","securityencryptionnetwork",OPT_SO_SECURITY_ENCRYPTION_NETWORK,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_SECURITY_ENCRYPTION_NETWORK}; #endif #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT const struct optdesc opt_so_security_encryption_transport={"so-security-encryption-transport","securityencryptiontransport",OPT_SO_SECURITY_ENCRYPTION_TRANSPORT,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_SECURITY_ENCRYPTION_TRANSPORT}; #endif #ifdef SO_USE_IFBUFS const struct optdesc opt_so_use_ifbufs={ "so-use-ifbufs","useifbufs",OPT_SO_USE_IFBUFS,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_USE_IFBUFS}; #endif /* SO_USE_IFBUFS */ #ifdef SO_USELOOPBACK /* AIX433, Solaris, HP-UX */ const struct optdesc opt_so_useloopback={"so-useloopback","useloopback",OPT_SO_USELOOPBACK,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT, SOL_SOCKET, SO_USELOOPBACK}; #endif /* SO_USELOOPBACK */ #ifdef SO_DGRAM_ERRIND /* Solaris */ const struct optdesc opt_so_dgram_errind={"so-dgram-errind","dgramerrind",OPT_SO_DGRAM_ERRIND,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_DGRAM_ERRIND}; #endif /* SO_DGRAM_ERRIND */ #ifdef SO_DONTLINGER /* Solaris */ const struct optdesc opt_so_dontlinger = {"so-dontlinger", "dontlinger", OPT_SO_DONTLINGER, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_DONTLINGER }; #endif /* the SO_PROTOTYPE is OS defined on Solaris, HP-UX; we lend this for a more general purpose */ const struct optdesc opt_so_prototype = {"so-prototype", "prototype", OPT_SO_PROTOTYPE, GROUP_SOCKET,PH_SOCKET, TYPE_INT,OFUNC_SPEC, SOL_SOCKET,SO_PROTOTYPE }; #ifdef FIOSETOWN const struct optdesc opt_fiosetown = { "fiosetown", NULL, OPT_FIOSETOWN, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_IOCTL, FIOSETOWN }; #endif #ifdef SIOCSPGRP const struct optdesc opt_siocspgrp = { "siocspgrp", NULL, OPT_SIOCSPGRP, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_IOCTL, SIOCSPGRP }; #endif const struct optdesc opt_bind = { "bind", NULL, OPT_BIND, GROUP_SOCKET, PH_BIND, TYPE_STRING,OFUNC_SPEC }; const struct optdesc opt_connect_timeout = { "connect-timeout", NULL, OPT_CONNECT_TIMEOUT, GROUP_SOCKET, PH_PASTSOCKET, TYPE_TIMEVAL, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.connect_timeout) }; const struct optdesc opt_protocol_family = { "protocol-family", "pf", OPT_PROTOCOL_FAMILY, GROUP_SOCKET, PH_PRESOCKET, TYPE_STRING, OFUNC_SPEC }; const struct optdesc opt_protocol = { "protocol", NULL, OPT_PROTOCOL, GROUP_SOCKET, PH_PRESOCKET, TYPE_STRING, OFUNC_SPEC }; /* generic setsockopt() options */ const struct optdesc opt_setsockopt_int = { "setsockopt-int", "sockopt-int", OPT_SETSOCKOPT_INT, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_INT, OFUNC_SOCKOPT_GENERIC, 0, 0 }; const struct optdesc opt_setsockopt_bin = { "setsockopt-bin", "sockopt-bin", OPT_SETSOCKOPT_BIN, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 }; const struct optdesc opt_setsockopt_string = { "setsockopt-string", "sockopt-string", OPT_SETSOCKOPT_STRING, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_STRING, OFUNC_SOCKOPT_GENERIC, 0, 0 }; const struct optdesc opt_null_eof = { "null-eof", NULL, OPT_NULL_EOF, GROUP_SOCKET, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.null_eof) }; #if WITH_GENERICSOCKET static int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int dummy2, int dummy3) { struct single *xfd = &xxfd->stream; const char *pfname = argv[1]; const char *protname = argv[2]; const char *address = argv[3]; char *garbage; int pf; int proto; int socktype = SOCK_STREAM; int needbind = 0; union sockaddr_union them; socklen_t themlen; size_t themsize; union sockaddr_union us; socklen_t uslen = sizeof(us); int result; if (argc != 4) { Error2("%s: wrong number of parameters (%d instead of 3)", argv[0], argc-1); return STAT_NORETRY; } pf = strtoul(pfname, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } proto = strtoul(protname, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } retropt_socket_pf(opts, &pf); retropt_int(opts, OPT_SO_TYPE, &socktype); /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ xfd->howtoend = END_SHUTDOWN; if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); applyopts(-1, opts, PH_EARLY); themsize = 0; if ((result = dalan(address, (char *)&them.soa.sa_data, &themsize, sizeof(them))) < 0) { Error1("data too long: \"%s\"", address); } else if (result > 0) { Error1("syntax error in \"%s\"", address); } them.soa.sa_family = pf; themlen = themsize + #if HAVE_STRUCT_SOCKADDR_SALEN sizeof(them.soa.sa_len) + #endif sizeof(them.soa.sa_family); xfd->dtype = XIOREAD_STREAM|XIOWRITE_STREAM; socket_init(0, &us); if (retropt_bind(opts, 0 /*pf*/, socktype, proto, (struct sockaddr *)&us, &uslen, 3, 0, 0) != STAT_NOACTION) { needbind = true; us.soa.sa_family = pf; } if ((result = xioopen_connect(xfd, needbind?(struct sockaddr *)&us:NULL, uslen, (struct sockaddr *)&them, themlen, opts, pf, socktype, proto, false)) != 0) { return result; } if ((result = _xio_openlate(xfd, opts)) < 0) { return result; } return STAT_OK; } #if WITH_LISTEN static int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int dummy2, int dummy3) { struct single *xfd = &xxfd->stream; const char *pfname = argv[1]; const char *protname = argv[2]; const char *usname = argv[3]; char *garbage; int pf; int proto; int socktype = SOCK_STREAM; union sockaddr_union us; socklen_t uslen; size_t ussize; struct opt *opts0; int result; if (argc != 4) { Error2("%s: wrong number of parameters (%d instead of 3)", argv[0], argc-1); return STAT_NORETRY; } pf = strtoul(pfname, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } proto = strtoul(protname, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } retropt_socket_pf(opts, &pf); retropt_int(opts, OPT_SO_TYPE, &socktype); /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ xfd->howtoend = END_SHUTDOWN; socket_init(0, &us); ussize = 0; if ((result = dalan(usname, (char *)&us.soa.sa_data, &ussize, sizeof(us))) < 0) { Error1("data too long: \"%s\"", usname); } else if (result > 0) { Error1("syntax error in \"%s\"", usname); } uslen = ussize + sizeof(us.soa.sa_family) #if HAVE_STRUCT_SOCKADDR_SALEN + sizeof(us.soa.sa_len) #endif ; us.soa.sa_family = pf; if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); applyopts(-1, opts, PH_EARLY); opts0 = copyopts(opts, GROUP_ALL); if ((result = xioopen_listen(xfd, xioflags, (struct sockaddr *)&us, uslen, opts, opts0, 0/*instead of pf*/, socktype, proto)) != STAT_OK) return result; return STAT_OK; } #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, unsigned groups, int dummy1, int dummy2, int dummy3) { int result; if (argc != 5) { Error2("%s: wrong number of parameters (%d instead of 4)", argv[0], argc-1); return STAT_NORETRY; } if ((result = _xioopen_socket_sendto(argv[1], argv[2], argv[3], argv[4], opts, xioflags, xxfd, groups)) != STAT_OK) { return result; } _xio_openlate(&xxfd->stream, opts); return STAT_OK; } static int _xioopen_socket_sendto(const char *pfname, const char *type, const char *protname, const char *address, struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups) { xiosingle_t *xfd = &xxfd->stream; char *garbage; union sockaddr_union us = {{0}}; socklen_t uslen = 0; size_t ussize; size_t themsize; int pf; int socktype = SOCK_RAW; int proto; bool needbind = false; char *bindstring = NULL; int result; pf = strtoul(pfname, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } socktype = strtoul(type, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } proto = strtoul(protname, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } retropt_socket_pf(opts, &pf); retropt_int(opts, OPT_SO_TYPE, &socktype); /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ xfd->howtoend = END_SHUTDOWN; xfd->peersa.soa.sa_family = pf; themsize = 0; if ((result = dalan(address, (char *)&xfd->peersa.soa.sa_data, &themsize, sizeof(xfd->peersa))) < 0) { Error1("data too long: \"%s\"", address); } else if (result > 0) { Error1("syntax error in \"%s\"", address); } xfd->salen = themsize + sizeof(sa_family_t) #if HAVE_STRUCT_SOCKADDR_SALEN + sizeof(xfd->peersa.soa.sa_len) #endif ; #if HAVE_STRUCT_SOCKADDR_SALEN xfd->peersa.soa.sa_len = sizeof(xfd->peersa.soa.sa_len) + sizeof(xfd->peersa.soa.sa_family) + themsize; #endif /* ...res_opts[] */ if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); if (pf == PF_UNSPEC) { pf = xfd->peersa.soa.sa_family; } xfd->dtype = XIODATA_RECVFROM; if (retropt_string(opts, OPT_BIND, &bindstring) == 0) { ussize = 0; if ((result = dalan(bindstring, (char *)&us.soa.sa_data, &ussize, sizeof(us))) < 0) { Error1("data too long: \"%s\"", bindstring); } else if (result > 0) { Error1("syntax error in \"%s\"", bindstring); } us.soa.sa_family = pf; uslen = ussize + sizeof(sa_family_t) #if HAVE_STRUCT_SOCKADDR_SALEN + sizeof(us.soa.sa_len) #endif ; needbind = true; } return _xioopen_dgram_sendto(needbind?&us:NULL, uslen, opts, xioflags, xfd, groups, pf, socktype, proto); } /* 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, unsigned groups, int dummy, int summy2, int dummy3) { struct single *xfd = &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; 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); return STAT_NORETRY; } pf = strtoul(pfname, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } socktype = strtoul(typename, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } proto = strtoul(protname, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } retropt_socket_pf(opts, &pf); retropt_int(opts, OPT_SO_TYPE, &socktype); /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ xfd->howtoend = END_NONE; ussize = 0; if ((result = dalan(address, (char *)&us->soa.sa_data, &ussize, sizeof(*us))) < 0) { Error1("data too long: \"%s\"", address); } else if (result > 0) { Error1("syntax error in \"%s\"", address); } us->soa.sa_family = pf; uslen = ussize + sizeof(us->soa.sa_family) #if HAVE_STRUCT_SOCKADDR_SALEN + sizeof(us->soa.sa_len); #endif ; xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, 0, &xfd->para.socket.range) < 0) { return STAT_NORETRY; } xfd->para.socket.dorange = true; free(rangename); } if ((result = _xioopen_dgram_recvfrom(xfd, xioflags, &us->soa, uslen, opts, pf, socktype, proto, E_ERROR)) != STAT_OK) { return result; } _xio_openlate(xfd, 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, unsigned groups, int dummy1, int dummy2, int dummy3) { struct single *xfd = &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; 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); return STAT_NORETRY; } pf = strtoul(pfname, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } socktype = strtoul(typename, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } proto = strtoul(protname, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } retropt_socket_pf(opts, &pf); retropt_int(opts, OPT_SO_TYPE, &socktype); /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ xfd->howtoend = END_NONE; ussize = 0; if ((result = dalan(address, (char *)&us.soa.sa_data, &ussize, sizeof(us))) < 0) { Error1("data too long: \"%s\"", address); } else if (result > 0) { Error1("syntax error in \"%s\"", address); } us.soa.sa_family = pf; uslen = ussize + sizeof(sa_family_t) #if HAVE_STRUCT_SOCKADDR_SALEN +sizeof(us.soa.sa_len) #endif ; xfd->dtype = XIOREAD_RECV; xfd->para.socket.la.soa.sa_family = pf; if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, 0, &xfd->para.socket.range) < 0) { return STAT_NORETRY; } xfd->para.socket.dorange = true; free(rangename); } if ((result = _xioopen_dgram_recv(xfd, xioflags, &us.soa, uslen, opts, pf, socktype, proto, E_ERROR)) != STAT_OK) { return result; } _xio_openlate(xfd, 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, unsigned groups, int dummy1, int dummy2, int dummy3) { xiosingle_t *xfd = &xxfd->stream; const char *pfname = argv[1]; const char *typename = argv[2]; const char *protname = argv[3]; const char *address = argv[4]; char *garbage; char *rangename; size_t themsize; int pf; int result; if (argc != 5) { Error2("%s: wrong number of parameters (%d instead of 4)", argv[0], argc-1); return STAT_NORETRY; } pf = strtoul(pfname, &garbage, 0); if (*garbage != '\0') { Warn1("garbage in parameter: \"%s\"", garbage); } retropt_socket_pf(opts, &pf); /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ xfd->howtoend = END_SHUTDOWN; xfd->peersa.soa.sa_family = pf; themsize = 0; if ((result = dalan(address, (char *)&xfd->peersa.soa.sa_data, &themsize, sizeof(xfd->peersa))) < 0) { Error1("data too long: \"%s\"", address); } else if (result > 0) { Error1("syntax error in \"%s\"", address); } xfd->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) + themsize; #endif if ((result = _xioopen_socket_sendto(pfname, typename, protname, address, opts, xioflags, xxfd, groups)) != STAT_OK) { return result; } xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; xfd->para.socket.la.soa.sa_family = xfd->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) < 0) { free(rangename); return STAT_NORETRY; } xfd->para.socket.dorange = true; xfd->dtype |= XIOREAD_RECV_CHECKRANGE; free(rangename); } _xio_openlate(xfd, opts); return STAT_OK; } #endif /* WITH_GENERICSOCKET */ /* a subroutine that is common to all socket addresses that want to connect to a peer address. might fork. applies and consumes the following options: PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECT, PH_CONNECTED, PH_LATE, OFUNC_OFFSET, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC returns 0 on success. */ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, struct sockaddr *them, size_t themlen, struct opt *opts, int pf, int socktype, int protocol, bool alt, int level) { int fcntl_flags = 0; char infobuff[256]; union sockaddr_union la; socklen_t lalen = themlen; int _errno; int result; if ((xfd->fd = xiosocket(opts, pf, socktype, protocol, level)) < 0) { return STAT_RETRYLATER; } applyopts_offset(xfd, opts); applyopts(xfd->fd, opts, PH_PASTSOCKET); applyopts(xfd->fd, opts, PH_FD); applyopts_cloexec(xfd->fd, opts); applyopts(xfd->fd, opts, PH_PREBIND); applyopts(xfd->fd, opts, PH_BIND); #if WITH_TCP || WITH_UDP if (alt) { union sockaddr_union sin, *sinp; unsigned short *port, i, N; div_t dv; /* prepare sockaddr for bind probing */ if (us) { sinp = (union sockaddr_union *)us; } else { if (them->sa_family == AF_INET) { socket_in_init(&sin.ip4); #if WITH_IP6 } else { socket_in6_init(&sin.ip6); #endif } sinp = &sin; } if (them->sa_family == AF_INET) { port = &sin.ip4.sin_port; #if WITH_IP6 } else if (them->sa_family == AF_INET6) { port = &sin.ip6.sin6_port; #endif } else { port = 0; /* just to make compiler happy */ } /* combine random+step variant to quickly find a free port when only few are in use, and certainly find a free port in defined time even if there are almost all in use */ /* dirt 1: having tcp/udp code in socket function */ /* dirt 2: using a time related system call for init of random */ { /* generate a random port, with millisecond random init */ #if 0 struct timeb tb; ftime(&tb); srandom(tb.time*1000+tb.millitm); #else struct timeval tv; struct timezone tz; tz.tz_minuteswest = 0; tz.tz_dsttime = 0; if ((result = Gettimeofday(&tv, &tz)) < 0) { Warn2("gettimeofday(%p, {0,0}): %s", &tv, strerror(errno)); } srandom(tv.tv_sec*1000000+tv.tv_usec); #endif } dv = div(random(), IPPORT_RESERVED-XIO_IPPORT_LOWER); i = N = XIO_IPPORT_LOWER + dv.rem; do { /* loop over lowport bind() attempts */ *port = htons(i); if (Bind(xfd->fd, (struct sockaddr *)sinp, sizeof(*sinp)) < 0) { Msg4(errno==EADDRINUSE?E_INFO:level, "bind(%d, {%s}, "F_Zd"): %s", xfd->fd, sockaddr_info(&sinp->soa, sizeof(*sinp), infobuff, sizeof(infobuff)), sizeof(*sinp), strerror(errno)); if (errno != EADDRINUSE) { Close(xfd->fd); return STAT_RETRYLATER; } } else { break; /* could bind to port, good, continue past loop */ } --i; if (i < XIO_IPPORT_LOWER) i = IPPORT_RESERVED-1; if (i == N) { Msg(level, "no low port available"); /*errno = EADDRINUSE; still assigned */ Close(xfd->fd); return STAT_RETRYLATER; } } while (i != N); } else #endif /* WITH_TCP || WITH_UDP */ if (us) { if (Bind(xfd->fd, us, uslen) < 0) { Msg4(level, "bind(%d, {%s}, "F_Zd"): %s", xfd->fd, sockaddr_info(us, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); Close(xfd->fd); return STAT_RETRYLATER; } } applyopts(xfd->fd, opts, PH_PASTBIND); applyopts(xfd->fd, opts, PH_CONNECT); if (xfd->para.socket.connect_timeout.tv_sec != 0 || xfd->para.socket.connect_timeout.tv_usec != 0) { fcntl_flags = Fcntl(xfd->fd, F_GETFL); Fcntl_l(xfd->fd, F_SETFL, fcntl_flags|O_NONBLOCK); } result = Connect(xfd->fd, (struct sockaddr *)them, themlen); _errno = errno; la.soa.sa_family = them->sa_family; lalen = sizeof(la); if (Getsockname(xfd->fd, &la.soa, &lalen) < 0) { Msg4(level-1, "getsockname(%d, %p, {%d}): %s", xfd->fd, &la.soa, lalen, strerror(errno)); } errno = _errno; if (result < 0) { if (errno == EINPROGRESS) { if (xfd->para.socket.connect_timeout.tv_sec != 0 || xfd->para.socket.connect_timeout.tv_usec != 0) { struct timeval timeout; struct pollfd writefd; int result; Info4("connect(%d, %s, "F_Zd"): %s", xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); timeout = xfd->para.socket.connect_timeout; writefd.fd = xfd->fd; writefd.events = (POLLOUT|POLLERR); result = xiopoll(&writefd, 1, &timeout); if (result < 0) { Msg4(level, "xiopoll({%d,POLLOUT|POLLERR},,{"F_tv_sec"."F_tv_usec"): %s", xfd->fd, timeout.tv_sec, timeout.tv_usec, strerror(errno)); return STAT_RETRYLATER; } if (result == 0) { Msg2(level, "connecting to %s: %s", sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), strerror(ETIMEDOUT)); return STAT_RETRYLATER; } if (writefd.revents & POLLERR) { #if 0 unsigned char dummy[1]; Read(xfd->fd, &dummy, 1); /* get error message */ Msg2(level, "connecting to %s: %s", sockaddr_info(them, infobuff, sizeof(infobuff)), strerror(errno)); #else Connect(xfd->fd, them, themlen); /* get error message */ Msg4(level, "connect(%d, %s, "F_Zd"): %s", xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); #endif return STAT_RETRYLATER; } /* otherwise OK */ Fcntl_l(xfd->fd, F_SETFL, fcntl_flags); } else { Warn4("connect(%d, %s, "F_Zd"): %s", xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); } } else if (pf == PF_UNIX && errno == EPROTOTYPE) { /* this is for UNIX domain sockets: a connect attempt seems to be the only way to distinguish stream and datagram sockets */ int _errno = errno; Info4("connect(%d, %s, "F_Zd"): %s", xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); #if 0 Info("assuming datagram socket"); xfd->dtype = DATA_RECVFROM; xfd->salen = themlen; memcpy(&xfd->peersa.soa, them, xfd->salen); #endif /*!!! and remove bind socket */ Close(xfd->fd); xfd->fd = -1; errno = _errno; return -1; } else { Msg4(level, "connect(%d, %s, "F_Zd"): %s", xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); Close(xfd->fd); return STAT_RETRYLATER; } } else { /* result >= 0 */ Notice1("successfully connected from local address %s", sockaddr_info(&la.soa, themlen, infobuff, sizeof(infobuff))); } applyopts_fchown(xfd->fd, opts); /* OPT_USER, OPT_GROUP */ applyopts(xfd->fd, opts, PH_CONNECTED); applyopts(xfd->fd, opts, PH_LATE); return STAT_OK; } /* a subroutine that is common to all socket addresses that want to connect to a peer address. might fork. applies and consumes the following option: PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECT, PH_CONNECTED, PH_LATE, OFUNC_OFFSET, OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC returns 0 on success. */ int xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, struct sockaddr *them, size_t themlen, struct opt *opts, int pf, int socktype, int protocol, bool alt) { bool dofork = false; struct opt *opts0; char infobuff[256]; int level; int result; retropt_bool(opts, OPT_FORK, &dofork); opts0 = copyopts(opts, GROUP_ALL); Notice1("opening connection to %s", sockaddr_info(them, themlen, infobuff, sizeof(infobuff))); do { /* loop over retries and forks */ #if WITH_RETRY if (xfd->forever || xfd->retry) { level = E_INFO; } else #endif /* WITH_RETRY */ level = E_ERROR; result = _xioopen_connect(xfd, 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 (result == STAT_RETRYLATER) { Nanosleep(&xfd->intervall, NULL); } dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); continue; } return STAT_NORETRY; #endif /* WITH_RETRY */ default: return result; } if (dofork) { xiosetchilddied(); /* set SIGCHLD handler */ } #if WITH_RETRY if (dofork) { pid_t pid; int level = E_ERROR; if (xfd->forever || xfd->retry) { level = E_WARN; /* most users won't expect a problem here, so Notice is too weak */ } while ((pid = xio_fork(false, level)) < 0) { --xfd->retry; if (xfd->forever || xfd->retry) { dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); Nanosleep(&xfd->intervall, NULL); continue; } return STAT_RETRYLATER; } if (pid == 0) { /* child process */ break; } /* parent process */ Close(xfd->fd); /* with and without retry */ Nanosleep(&xfd->intervall, NULL); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); continue; /* with next socket() bind() connect() */ } else #endif /* WITH_RETRY */ { break; } #if 0 if ((result = _xio_openlate(fd, opts)) < 0) return result; #endif } while (true); return 0; } /* common to xioopen_udp_sendto, ..unix_sendto, ..rawip applies and consumes the following option: PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE OFUNC_OFFSET OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC */ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */ union sockaddr_union *us, socklen_t uslen, struct opt *opts, int xioflags, xiosingle_t *xfd, unsigned groups, int pf, int socktype, int ipproto) { int level = E_ERROR; union sockaddr_union la; socklen_t lalen = sizeof(la); char infobuff[256]; if ((xfd->fd = xiosocket(opts, pf, socktype, ipproto, level)) < 0) { return STAT_RETRYLATER; } applyopts_offset(xfd, opts); applyopts_single(xfd, opts, PH_PASTSOCKET); applyopts(xfd->fd, opts, PH_PASTSOCKET); applyopts(xfd->fd, opts, PH_FD); applyopts_cloexec(xfd->fd, opts); applyopts(xfd->fd, opts, PH_PREBIND); applyopts(xfd->fd, opts, PH_BIND); if (us) { if (Bind(xfd->fd, (struct sockaddr *)us, uslen) < 0) { Msg4(level, "bind(%d, {%s}, "F_socklen"): %s", xfd->fd, sockaddr_info((struct sockaddr *)us, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); Close(xfd->fd); return STAT_RETRYLATER; } } applyopts(xfd->fd, opts, PH_PASTBIND); /*applyopts(xfd->fd, opts, PH_CONNECT);*/ if (Getsockname(xfd->fd, &la.soa, &lalen) < 0) { Warn4("getsockname(%d, %p, {%d}): %s", xfd->fd, &la.soa, lalen, strerror(errno)); } applyopts_fchown(xfd->fd, opts); applyopts(xfd->fd, opts, PH_CONNECTED); applyopts(xfd->fd, opts, PH_LATE); /* xfd->dtype = DATA_RECVFROM; *//* no, the caller must set this (ev _SKIPIP) */ Notice1("successfully prepared local socket %s", sockaddr_info(&la.soa, lalen, infobuff, sizeof(infobuff))); return STAT_OK; } /* when the recvfrom address (with option fork) receives a packet it keeps this packet in the IP stacks input queue and forks a sub process. The sub process then reads this packet for processing its data. There is a problem because the parent process would find the same packet again if it calls select()/poll() before the child process reads the packet. To solve this problem we implement the following mechanism: The sub process sends a SIGUSR1 when it has read the packet (or a SIGCHLD if it dies before). The parent process waits until it receives that signal and only then continues to listen. To prevent a signal from another process to trigger our loop, we pass the pid of the sub process to the signal handler in xio_waitingfor. The signal handler sets xio_hashappened if the pid matched. */ static pid_t xio_waitingfor; /* info from recv loop to signal handler: indicates the pid of the child process that should send us the USR1 signal */ static bool xio_hashappened; /* info from signal handler to loop: child process has read ("consumed") the packet */ /* this is the signal handler for USR1 and CHLD */ void xiosigaction_hasread(int signum #if HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined(SA_SIGINFO) , siginfo_t *siginfo, void *ucontext #endif ) { pid_t pid; int _errno; int status = 0; bool wassig = false; _errno = errno; diag_in_handler = 1; #if HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined(SA_SIGINFO) Debug5("xiosigaction_hasread(%d, {%d,%d,%d,"F_pid"}, )", signum, siginfo->si_signo, siginfo->si_errno, siginfo->si_code, siginfo->si_pid); #else Debug1("xiosigaction_hasread(%d)", signum); #endif if (signum == SIGCHLD) { do { pid = Waitpid(-1, &status, WNOHANG); if (pid == 0) { Msg(wassig?E_INFO:E_WARN, "waitpid(-1, {}, WNOHANG): no child has exited"); Info("xiosigaction_hasread() finished"); Debug("xiosigaction_hasread() ->"); diag_in_handler = 0; errno = _errno; return; } else if (pid < 0 && errno == ECHILD) { Msg(wassig?E_INFO:E_WARN, "waitpid(-1, {}, WNOHANG): "F_strerror); Info("xiosigaction_hasread() finished"); Debug("xiosigaction_hasread() ->"); diag_in_handler = 0; errno = _errno; return; } wassig = true; if (pid < 0) { Warn1("waitpid(-1, {%d}, WNOHANG): "F_strerror, status); Info("xiosigaction_hasread() finished"); Debug("xiosigaction_hasread() ->"); diag_in_handler = 0; errno = _errno; return; } if (pid == xio_waitingfor) { xio_hashappened = true; Debug("xiosigaction_hasread() ->"); diag_in_handler = 0; errno = _errno; return; } } while (1); } #if HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined(SA_SIGINFO) if (xio_waitingfor == siginfo->si_pid) { xio_hashappened = true; } #else xio_hashappened = true; #endif #if !HAVE_SIGACTION Signal(sig, xiosigaction_hasread); #endif /* !HAVE_SIGACTION */ Debug("xiosigaction_hasread() ->"); diag_in_handler = 0; errno = _errno; return; } /* waits for incoming packet, checks its source address and port. Depending on fork option, it may fork a subprocess. Returns STAT_OK if a the packet was accepted; with fork option, this is already in a new subprocess! Other return values indicate a problem; this can happen in the master process or in a subprocess. This function does not retry. If you need retries, handle this is a loop in the calling function. after fork, we set the forever/retry of the child process to 0 applies and consumes the following options: PH_INIT, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_EARLY, PH_PREOPEN, PH_FD, PH_CONNECTED, PH_LATE, PH_LATE2 OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, cloexec, OPT_RANGE, tcpwrap */ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, int pf, int socktype, int proto, int level) { char *rangename; bool dofork = false; pid_t pid; /* mostly int; only used with fork */ char infobuff[256]; char lisname[256]; bool drop = false; /* true if current packet must be dropped */ int result; retropt_bool(opts, OPT_FORK, &dofork); if (dofork) { if (!(xioflags & XIO_MAYFORK)) { Error("option fork not allowed here"); return STAT_NORETRY; } xfd->flags |= XIO_DOESFORK; } if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY; if ((xfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) { return STAT_RETRYLATER; } applyopts_single(xfd, opts, PH_PASTSOCKET); applyopts(xfd->fd, opts, PH_PASTSOCKET); applyopts_cloexec(xfd->fd, opts); applyopts(xfd->fd, opts, PH_PREBIND); applyopts(xfd->fd, opts, PH_BIND); if ((us != NULL) && Bind(xfd->fd, (struct sockaddr *)us, uslen) < 0) { Msg4(level, "bind(%d, {%s}, "F_socklen"): %s", xfd->fd, sockaddr_info(us, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); Close(xfd->fd); return STAT_RETRYLATER; } #if WITH_UNIX if (pf == AF_UNIX && us != NULL) { applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD); } #endif applyopts(xfd->fd, opts, PH_PASTBIND); #if WITH_UNIX if (pf == AF_UNIX && us != NULL) { /*applyopts_early(((struct sockaddr_un *)us)->sun_path, opts);*/ applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_EARLY); applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN); } #endif /* WITH_UNIX */ /* for generic sockets, this has already been retrieved */ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &xfd->para.socket.range) < 0) { free(rangename); return STAT_NORETRY; } free(rangename); xfd->para.socket.dorange = true; } #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP xio_retropt_tcpwrap(xfd, opts); #endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */ if (xioopts.logopt == 'm') { Info("starting recvfrom loop, switching to syslog"); diag_set('y', xioopts.syslogfac); xioopts.logopt = 'y'; } else { Info("starting recvfrom loop"); } if (dofork) { #if HAVE_SIGACTION { struct sigaction act; memset(&act, 0, sizeof(struct sigaction)); act.sa_flags = SA_NOCLDSTOP/*|SA_RESTART*/ #ifdef SA_SIGINFO /* not on Linux 2.0(.33) */ |SA_SIGINFO #endif #ifdef SA_NOMASK |SA_NOMASK #endif ; #if HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined(SA_SIGINFO) act.sa_sigaction = xiosigaction_hasread; #else /* Linux 2.0(.33) does not have sigaction.sa_sigaction */ act.sa_handler = xiosigaction_hasread; #endif sigfillset(&act.sa_mask); if (Sigaction(SIGUSR1, &act, NULL) < 0) { /*! Linux man does not explicitely say that errno is defined */ Warn1("sigaction(SIGUSR1, {&xiosigaction_subaddr_ok}, NULL): %s", strerror(errno)); } if (Sigaction(SIGCHLD, &act, NULL) < 0) { /*! Linux man does not explicitely say that errno is defined */ Warn1("sigaction(SIGCHLD, {&xiosigaction_subaddr_ok}, NULL): %s", strerror(errno)); } } #else /* !HAVE_SIGACTION */ /*!!!*/ if (Signal(SIGUSR1, xiosigaction_hasread) == SIG_ERR) { Warn1("signal(SIGUSR1, xiosigaction_hasread): %s", strerror(errno)); } if (Signal(SIGCHLD, xiosigaction_hasread) == SIG_ERR) { Warn1("signal(SIGCHLD, xiosigaction_hasread): %s", strerror(errno)); } #endif /* !HAVE_SIGACTION */ } while (true) { /* but we only loop if fork option is set */ char peername[256]; union sockaddr_union _peername; union sockaddr_union _sockname; union sockaddr_union *pa = &_peername; /* peer address */ union sockaddr_union *la = &_sockname; /* local address */ socklen_t palen = sizeof(_peername); /* peer address size */ char ctrlbuff[1024]; /* ancillary messages */ struct msghdr msgh = {0}; socket_init(pf, pa); if (drop) { char *dummy[2]; Recv(xfd->fd, dummy, sizeof(dummy), 0); drop = true; } /* loop until select()/poll() returns valid */ do { struct pollfd readfd; /*? int level = E_ERROR;*/ if (us != NULL) { Notice1("receiving on %s", sockaddr_info(us, uslen, lisname, sizeof(lisname))); } else { Notice1("receiving IP protocol %u", proto); } readfd.fd = xfd->fd; readfd.events = POLLIN; if (xiopoll(&readfd, 1, NULL) > 0) { break; } if (errno == EINTR) { continue; } Msg2(level, "poll({%d,,},,-1): %s", xfd->fd, strerror(errno)); Close(xfd->fd); return STAT_RETRYLATER; } while (true); msgh.msg_name = pa; msgh.msg_namelen = palen; #if HAVE_STRUCT_MSGHDR_MSGCONTROL msgh.msg_control = ctrlbuff; #endif #if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN msgh.msg_controllen = sizeof(ctrlbuff); #endif if (xiogetpacketsrc(xfd->fd, &msgh) < 0) { return STAT_RETRYLATER; } palen = msgh.msg_namelen; Notice1("receiving packet from %s"/*"src"*/, sockaddr_info((struct sockaddr *)pa, palen, peername, sizeof(peername))/*, sockaddr_info(&la->soa, sockname, sizeof(sockname))*/); xiodopacketinfo(&msgh, true, true); if (xiocheckpeer(xfd, pa, la) < 0) { /* drop packet */ char buff[512]; Recv(xfd->fd, buff, sizeof(buff), 0); continue; } Info1("permitting packet from %s", sockaddr_info((struct sockaddr *)pa, palen, infobuff, sizeof(infobuff))); /* set the env vars describing the local and remote sockets */ /*xiosetsockaddrenv("SOCK", la, lalen, proto);*/ xiosetsockaddrenv("PEER", pa, palen, proto); applyopts(xfd->fd, opts, PH_FD); applyopts(xfd->fd, opts, PH_CONNECTED); xfd->peersa = *(union sockaddr_union *)pa; xfd->salen = palen; if (dofork) { sigset_t mask_sigchldusr1; /* we must prevent that the current packet triggers another fork; therefore we wait for a signal from the recent child: USR1 indicates that is has consumed the last packet; CHLD means it has terminated */ /* block SIGCHLD and SIGUSR1 until parent is ready to react */ sigemptyset(&mask_sigchldusr1); sigaddset(&mask_sigchldusr1, SIGCHLD); sigaddset(&mask_sigchldusr1, SIGUSR1); Sigprocmask(SIG_BLOCK, &mask_sigchldusr1, NULL); if ((pid = xio_fork(false, level)) < 0) { Close(xfd->fd); Sigprocmask(SIG_UNBLOCK, &mask_sigchldusr1, NULL); return STAT_RETRYLATER; } if (pid == 0) { /* child */ /* no reason to block SIGCHLD in child process */ Sigprocmask(SIG_UNBLOCK, &mask_sigchldusr1, NULL); xfd->ppid = Getppid(); /* send parent a signal when packet has been consumed */ #if WITH_RETRY /* !? */ xfd->retry = 0; xfd->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; #endif /* WITH_UNIX */ break; } /* server: continue loop with listen */ xio_waitingfor = pid; /* now we are ready to handle signals */ Sigprocmask(SIG_UNBLOCK, &mask_sigchldusr1, NULL); while (!xio_hashappened) { Sleep(UINT_MAX); /* any signal lets us continue */ } xio_waitingfor = 0; /* so this child will not set hashappened again */ xio_hashappened = false; Info("continue listening"); } else { break; } } if ((result = _xio_openlate(xfd, opts)) != 0) return STAT_NORETRY; return STAT_OK; } /* returns STAT_* */ int _xioopen_dgram_recv(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, int pf, int socktype, int proto, int level) { char *rangename; char infobuff[256]; if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY; if ((xfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) { return STAT_RETRYLATER; } applyopts_single(xfd, opts, PH_PASTSOCKET); applyopts(xfd->fd, opts, PH_PASTSOCKET); applyopts_cloexec(xfd->fd, opts); applyopts(xfd->fd, opts, PH_PREBIND); applyopts(xfd->fd, opts, PH_BIND); if ((us != NULL) && Bind(xfd->fd, (struct sockaddr *)us, uslen) < 0) { Msg4(level, "bind(%d, {%s}, "F_socklen"): %s", xfd->fd, sockaddr_info(us, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); Close(xfd->fd); return STAT_RETRYLATER; } #if WITH_UNIX if (pf == AF_UNIX && us != NULL) { applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD); } #endif applyopts(xfd->fd, opts, PH_PASTBIND); #if WITH_UNIX if (pf == AF_UNIX && us != NULL) { /*applyopts_early(((struct sockaddr_un *)us)->sun_path, opts);*/ applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_EARLY); applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN); } #endif /* WITH_UNIX */ #if WITH_IP4 /*|| WITH_IP6*/ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &xfd->para.socket.range) < 0) { free(rangename); return STAT_NORETRY; } free(rangename); xfd->para.socket.dorange = true; } #endif #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP xio_retropt_tcpwrap(xfd, opts); #endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */ if (xioopts.logopt == 'm') { Info("starting recvfrom loop, switching to syslog"); diag_set('y', xioopts.syslogfac); xioopts.logopt = 'y'; } else { Info("starting recvfrom loop"); } return STAT_OK; } int retropt_socket_pf(struct opt *opts, int *pf) { char *pfname; if (retropt_string(opts, OPT_PROTOCOL_FAMILY, &pfname) >= 0) { if (isdigit(pfname[0])) { *pf = strtoul(pfname, NULL /*!*/, 0); #if WITH_IP4 } else if (!strcasecmp("inet", pfname) || !strcasecmp("inet4", pfname) || !strcasecmp("ip4", pfname) || !strcasecmp("ipv4", pfname) || !strcasecmp("2", pfname)) { *pf = PF_INET; #endif /* WITH_IP4 */ #if WITH_IP6 } else if (!strcasecmp("inet6", pfname) || !strcasecmp("ip6", pfname) || !strcasecmp("ipv6", pfname) || !strcasecmp("10", pfname)) { *pf = PF_INET6; #endif /* WITH_IP6 */ } else { Error1("unknown protocol family \"%s\"", pfname); /*! Warn("falling back to INET");*/ } free(pfname); return 0; } return -1; } /* this function calls recvmsg(..., MSG_PEEK, ...) to obtain information about the arriving packet. in msgh the msg_name pointer must refer to an (empty) sockaddr storage. */ int xiogetpacketsrc(int fd, struct msghdr *msgh) { char peekbuff[1]; #if HAVE_STRUCT_IOVEC struct iovec iovec; #endif #if HAVE_STRUCT_IOVEC iovec.iov_base = peekbuff; iovec.iov_len = sizeof(peekbuff); msgh->msg_iov = &iovec; msgh->msg_iovlen = 1; #endif #if HAVE_STRUCT_MSGHDR_MSGFLAGS msgh->msg_flags = 0; #endif if (Recvmsg(fd, msgh, MSG_PEEK #ifdef MSG_TRUNC |MSG_TRUNC #endif ) < 0) { Warn1("recvmsg(): %s", strerror(errno)); return STAT_RETRYLATER; } return STAT_OK; } /* works through the ancillary messages found in the given socket header record and logs the relevant information (E_DEBUG, E_INFO). calls protocol/layer specific functions for handling the messages creates appropriate environment vars if withenv is set */ int xiodopacketinfo(struct msghdr *msgh, bool withlog, bool withenv) { #if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) struct cmsghdr *cmsg; /* parse ancillary messages */ cmsg = CMSG_FIRSTHDR(msgh); while (cmsg != NULL) { int num = 0; /* number of data components of a ancill.msg */ int i; char typbuff[16], *typp; char nambuff[128], *namp; char valbuff[256], *valp; char envbuff[256], *envp; if (withlog) { xiodump(CMSG_DATA(cmsg), cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg), valbuff, sizeof(valbuff)-1, 0); Debug4("ancillary message: len="F_cmsg_len", level=%d, type=%d, data=%s", cmsg->cmsg_len, cmsg->cmsg_level, cmsg->cmsg_type, valbuff); } /* try to get the anc.msg. contents in handy components, protocol/level dependent */ switch (cmsg->cmsg_level) { case SOL_SOCKET: xiolog_ancillary_socket(cmsg, &num, typbuff, sizeof(typbuff)-1, nambuff, sizeof(nambuff)-1, envbuff, sizeof(envbuff)-1, valbuff, sizeof(valbuff)-1); break; #if WITH_IP4 || WITH_IP6 case SOL_IP: xiolog_ancillary_ip(cmsg, &num, typbuff, sizeof(typbuff)-1, nambuff, sizeof(nambuff)-1, envbuff, sizeof(envbuff)-1, valbuff, sizeof(valbuff)-1); break; #endif /* WITH_IP4 || WITH_IP6 */ #if WITH_IP6 case SOL_IPV6: xiolog_ancillary_ip6(cmsg, &num, typbuff, sizeof(typbuff)-1, nambuff, sizeof(nambuff)-1, envbuff, sizeof(envbuff)-1, valbuff, sizeof(valbuff)-1); break; #endif /* WITH_IP6 */ default: num = 1; snprintf(typbuff, sizeof(typbuff)-1, "LEVEL%u", cmsg->cmsg_level); snprintf(nambuff, sizeof(nambuff)-1, "type%u", cmsg->cmsg_type); xiodump(CMSG_DATA(cmsg), cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg), valbuff, sizeof(valbuff)-1, 0); } /* here the info is in typbuff (one string), nambuff (num consecutive strings), and valbuff (num consecutive strings) */ i = 0; typp = typbuff; namp = nambuff; envp = envbuff; valp = valbuff; while (i < num) { if (withlog) { Info3("ancillary message: %s: %s=%s", typp, namp, valp); } if (withenv) { if (*envp) { xiosetenv(envp, valp, 1, NULL); } else if (!strcasecmp(typp+strlen(typp)-strlen(namp), namp)) { xiosetenv(typp, valp, 1, NULL); } else { xiosetenv2(typp, namp, valp, 1, NULL); } } if (++i == num) break; namp = strchr(namp, '\0')+1; envp = strchr(envp, '\0')+1; valp = strchr(valp, '\0')+1; } cmsg = CMSG_NXTHDR(msgh, cmsg); } return 0; #else /* !(defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA)) */ return -1; #endif /* !(defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA)) */ } /* check if peer address is within permitted range. return >= 0 if so. */ int xiocheckrange(union sockaddr_union *sa, struct xiorange *range) { switch (sa->soa.sa_family) { #if WITH_IP4 case PF_INET: return xiocheckrange_ip4(&sa->ip4, range); #endif /* WITH_IP4 */ #if WITH_IP6 case PF_INET6: return xiocheckrange_ip6(&sa->ip6, range); #endif /* WITH_IP6 */ #if 0 case PF_UNSPEC: { socklen_t i; for (i = 0; i < sizeof(sa->soa.sa_data); ++i) { if ((range->netmask.soa.sa_data[i] & sa->soa.sa_data[i]) != range->netaddr.soa.sa_data[i]) { return -1; } } return 0; } #endif } return -1; } int xiocheckpeer(xiosingle_t *xfd, union sockaddr_union *pa, union sockaddr_union *la) { char infobuff[256]; int result; #if WITH_IP4 if (xfd->para.socket.dorange) { if (pa == NULL) { return -1; } if (xiocheckrange(pa, &xfd->para.socket.range) < 0) { char infobuff[256]; Warn1("refusing connection from %s due to range option", sockaddr_info((struct sockaddr *)pa, 0, infobuff, sizeof(infobuff))); return -1; } Info1("permitting connection from %s due to range option", sockaddr_info((struct sockaddr *)pa, 0, infobuff, sizeof(infobuff))); } #endif /* WITH_IP4 */ #if WITH_TCP || WITH_UDP if (xfd->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) { Warn1("refusing connection from %s due to wrong sourceport", sockaddr_info((struct sockaddr *)pa, 0, infobuff, sizeof(infobuff))); return -1; } #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) { Warn1("refusing connection from %s due to wrong sourceport", sockaddr_info((struct sockaddr *)pa, 0, infobuff, sizeof(infobuff))); return -1; } #endif /* WITH_IP6 */ Info1("permitting connection from %s due to sourceport option", sockaddr_info((struct sockaddr *)pa, 0, infobuff, sizeof(infobuff))); } else if (xfd->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) { Warn1("refusing connection from %s due to lowport option", sockaddr_info((struct sockaddr *)pa, 0, infobuff, sizeof(infobuff))); return -1; } #if WITH_IP6 else if (pa->soa.sa_family == AF_INET6 && ntohs(((struct sockaddr_in6 *)pa)->sin6_port) >= IPPORT_RESERVED) { Warn1("refusing connection from %s due to lowport option", sockaddr_info((struct sockaddr *)pa, 0, infobuff, sizeof(infobuff))); return -1; } #endif /* WITH_IP6 */ Info1("permitting connection from %s due to lowport option", sockaddr_info((struct sockaddr *)pa, 0, infobuff, sizeof(infobuff))); } #endif /* WITH_TCP || WITH_UDP */ #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP result = xio_tcpwrap_check(xfd, la, pa); if (result < 0) { char infobuff[256]; Warn1("refusing connection from %s due to tcpwrapper option", sockaddr_info((struct sockaddr *)pa, 0, infobuff, sizeof(infobuff))); return -1; } else if (result > 0) { Info1("permitting connection from %s due to tcpwrapper option", sockaddr_info((struct sockaddr *)pa, 0, infobuff, sizeof(infobuff))); } #endif /* (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */ return 0; /* permitted */ } #if HAVE_STRUCT_CMSGHDR /* converts the ancillary message in *cmsg into a form useable for further processing. knows the specifics of common message types. returns the number of resulting syntax elements in *num returns a sequence of \0 terminated type strings in *typbuff returns a sequence of \0 terminated name strings in *nambuff returns a sequence of \0 terminated value strings in *valbuff the respective len parameters specify the available space in the buffers returns STAT_OK or other STAT_* */ static int xiolog_ancillary_socket(struct cmsghdr *cmsg, int *num, char *typbuff, int typlen, char *nambuff, int namlen, char *envbuff, int envlen, char *valbuff, int vallen) { const char *cmsgtype, *cmsgname, *cmsgenvn; size_t msglen; struct timeval *tv; int rc = STAT_OK; #if defined(CMSG_DATA) msglen = cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg); switch (cmsg->cmsg_type) { #ifdef SO_PASSCRED case SO_PASSCRED: /* this is really a UNIX/LOCAL message */ /*! needs implementation */ #endif /* SO_PASSCRED */ #ifdef SO_RIGHTS case SO_RIGHTS: /* this is really a UNIX/LOCAL message */ /*! needs implementation */ #endif default: /* binary data */ snprintf(typbuff, typlen, "SOCKET.%u", cmsg->cmsg_type); nambuff[0] = '\0'; strncat(nambuff, "data", namlen-1); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #ifdef SO_TIMESTAMP # ifdef SCM_TIMESTAMP case SCM_TIMESTAMP: # else case SO_TIMESTAMP: # endif tv = (struct timeval *)CMSG_DATA(cmsg); cmsgtype = #ifdef SCM_TIMESTAMP "SCM_TIMESTAMP" /* FreeBSD */ #else "SO_TIMESTAMP" /* Linux */ #endif ; cmsgname = "timestamp"; cmsgenvn = "TIMESTAMP"; { time_t t = tv->tv_sec; ctime_r(&t, valbuff); } snprintf(strchr(valbuff, '\0')-1/*del \n*/, vallen-strlen(valbuff)+1, ", %06ld usecs", (long)tv->tv_usec); break; #endif /* defined(SO_TIMESTAMP) */ ; } /* when we come here we provide a single parameter with type in cmsgtype, name in cmsgname, and value already in valbuff */ *num = 1; if (strlen(cmsgtype) >= typlen) rc = STAT_WARNING; typbuff[0] = '\0'; strncat(typbuff, cmsgtype, typlen-1); if (strlen(cmsgname) >= namlen) rc = STAT_WARNING; nambuff[0] = '\0'; strncat(nambuff, cmsgname, namlen-1); if (strlen(cmsgenvn) >= envlen) rc = STAT_WARNING; envbuff[0] = '\0'; strncat(envbuff, cmsgenvn, envlen-1); return rc; #else /* !defined(CMSG_DATA) */ return STAT_NORETRY; #endif /* !defined(CMSG_DATA) */ } #endif /* HAVE_STRUCT_CMSGHDR */ /* return the name of the interface with given index or NULL if is fails The system call requires an arbitrary socket; the calling program may provide one in parameter ins to avoid creation of a dummy socket. ins must be <0 if it does not specify a socket fd. */ char *xiogetifname(int ind, char *val, int ins) { #if !HAVE_PROTOTYPE_LIB_if_indextoname int s; struct ifreq ifr; if (ins >= 0) { s = ins; } else { if ((s = Socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { Error1("socket(PF_INET, SOCK_DGRAM, IPPROTO_IP): %s", strerror(errno)); return NULL; } } #if HAVE_STRUCT_IFREQ_IFR_INDEX ifr.ifr_index = ind; #elif HAVE_STRUCT_IFREQ_IFR_IFINDEX ifr.ifr_ifindex = ind; #endif #ifdef SIOCGIFNAME if(Ioctl(s, SIOCGIFNAME, &ifr) < 0) { #if HAVE_STRUCT_IFREQ_IFR_INDEX Info3("ioctl(%d, SIOCGIFNAME, {..., ifr_index=%d, ...}: %s", s, ifr.ifr_index, strerror(errno)); #elif HAVE_STRUCT_IFREQ_IFR_IFINDEX Info3("ioctl(%d, SIOCGIFNAME, {..., ifr_ifindex=%d, ...}: %s", s, ifr.ifr_ifindex, strerror(errno)); #endif if (ins < 0) Close(s); return NULL; } #endif /* SIOCGIFNAME */ if (ins < 0) Close(s); strcpy(val, ifr.ifr_name); return val; #else /* HAVE_PROTOTYPE_LIB_if_indextoname */ return if_indextoname(ind, val); #endif /* HAVE_PROTOTYPE_LIB_if_indextoname */ } /* parses a network specification consisting of an address and a mask. */ int xioparsenetwork(const char *rangename, int pf, struct xiorange *range) { size_t addrlen = 0, masklen = 0; int result; switch (pf) { #if WITH_IP4 case PF_INET: return xioparsenetwork_ip4(rangename, range); break; #endif /* WITH_IP4 */ #if WITH_IP6 case PF_INET6: return xioparsenetwork_ip6(rangename, range); break; #endif /* WITH_IP6 */ case PF_UNSPEC: { char *addrname; const char *maskname; if ((maskname = strchr(rangename, ':')) == NULL) { Error1("syntax error in range \"%s\": use :", rangename); return STAT_NORETRY; } ++maskname; /* skip ':' */ if ((addrname = Malloc(maskname-rangename)) == NULL) { return STAT_NORETRY; } strncpy(addrname, rangename, maskname-rangename-1); /* ok */ addrname[maskname-rangename-1] = '\0'; result = dalan(addrname, (char *)&range->netaddr.soa.sa_data, &addrlen, sizeof(range->netaddr)-(size_t)(&((struct sockaddr *)0)->sa_data) /* data length */); if (result < 0) { Error1("data too long: \"%s\"", addrname); free(addrname); return STAT_NORETRY; } else if (result > 0) { Error1("syntax error in \"%s\"", addrname); free(addrname); return STAT_NORETRY; } free(addrname); result = dalan(maskname, (char *)&range->netmask.soa.sa_data, &masklen, sizeof(range->netaddr)-(size_t)(&((struct sockaddr *)0)->sa_data) /* data length */); if (result < 0) { Error1("data too long: \"%s\"", maskname); return STAT_NORETRY; } else if (result > 0) { Error1("syntax error in \"%s\"", maskname); return STAT_NORETRY; } if (addrlen != masklen) { Error2("network address is "F_Zu" bytes long, mask is "F_Zu" bytes long", addrlen, masklen); /* recover by padding the shorter component with 0 */ memset((char *)&range->netaddr.soa.sa_data+addrlen, 0, MAX(0, addrlen-masklen)); memset((char *)&range->netmask.soa.sa_data+masklen, 0, MAX(0, masklen-addrlen)); } } break; default: Error1("range option not supported with address family %d", pf); return STAT_NORETRY; } return STAT_OK; } /* parses a string of form address/bits or address:mask, and fills the fields of the range union. The addr component is masked with mask. */ int xioparserange(const char *rangename, int pf, struct xiorange *range) { int i; if (xioparsenetwork(rangename, pf, range) < 0) { return -1; } /* we have parsed the address and mask; now we make sure that the stored address has 0 where mask is 0, to simplify comparisions */ switch (pf) { #if WITH_IP4 case PF_INET: range->netaddr.ip4.sin_addr.s_addr &= range->netmask.ip4.sin_addr.s_addr; break; #endif /* WITH_IP4 */ #if WITH_IP6 case PF_INET6: return xiorange_ip6andmask(range); break; #endif /* WITH_IP6 */ case PF_UNSPEC: for (i = 0; i < sizeof(range->netaddr); ++i) { ((char *)&range->netaddr)[i] &= ((char *)&range->netmask)[i]; } break; default: Error1("range option not supported with address family %d", pf); return STAT_NORETRY; } return 0; } /* set environment variables describing (part of) a socket address, e.g. SOCAT_SOCKADDR. lr (local/remote) specifies a string like "SOCK" or "PEER". proto should correspond to the third parameter of socket(2) and is used to determine the presence of port information. */ int xiosetsockaddrenv(const char *lr, union sockaddr_union *sau, socklen_t salen, int proto) { # define XIOSOCKADDRENVLEN 256 char namebuff[XIOSOCKADDRENVLEN]; char valuebuff[XIOSOCKADDRENVLEN]; int idx = 0, result; strcpy(namebuff, lr); switch (sau->soa.sa_family) { #if WITH_UNIX case PF_UNIX: result = xiosetsockaddrenv_unix(idx, strchr(namebuff, '\0'), XIOSOCKADDRENVLEN-strlen(lr), valuebuff, XIOSOCKADDRENVLEN, &sau->un, salen, proto); xiosetenv(namebuff, valuebuff, 1, NULL); break; #endif /* WITH_UNIX */ #if WITH_IP4 case PF_INET: do { result = xiosetsockaddrenv_ip4(idx, strchr(namebuff, '\0'), XIOSOCKADDRENVLEN-strlen(lr), valuebuff, XIOSOCKADDRENVLEN, &sau->ip4, proto); xiosetenv(namebuff, valuebuff, 1, NULL); namebuff[strlen(lr)] = '\0'; ++idx; } while (result > 0); break; #endif /* WITH_IP4 */ #if WITH_IP6 case PF_INET6: strcpy(namebuff, lr); do { result = xiosetsockaddrenv_ip6(idx, strchr(namebuff, '\0'), XIOSOCKADDRENVLEN-strlen(lr), valuebuff, XIOSOCKADDRENVLEN, &sau->ip6, proto); xiosetenv(namebuff, valuebuff, 1, NULL); namebuff[strlen(lr)] = '\0'; ++idx; } while (result > 0); break; #endif /* WITH_IP6 */ #if LATER case PF_PACKET: result = xiosetsockaddrenv_packet(lr, (void *)sau, proto); break; #endif default: result = -1; break; } return result; # undef XIOSOCKADDRENVLEN } #endif /* _WITH_SOCKET */ /* these do sockets internally */ /* retrieves options so-type and so-prototype from opts, calls socket, and ev. generates an appropriate error message. returns 0 on success or -1 if an error occurred. */ int xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) { int result; retropt_int(opts, OPT_SO_TYPE, &socktype); retropt_int(opts, OPT_SO_PROTOTYPE, &proto); result = Socket(pf, socktype, proto); if (result < 0) { Msg4(msglevel, "socket(%d, %d, %d): %s", pf, socktype, proto, strerror(errno)); return -1; } return result; } /* retrieves options so-type and so-prototype from opts, calls socketpair, and ev. generates an appropriate error message. returns 0 on success or -1 if an error occurred. */ int xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]) { int result; retropt_int(opts, OPT_SO_TYPE, &socktype); retropt_int(opts, OPT_SO_PROTOTYPE, &proto); result = Socketpair(pf, socktype, proto, sv); if (result < 0) { Error5("socketpair(%d, %d, %d, %p): %s", pf, socktype, proto, sv, strerror(errno)); return -1; } return result; } socat-1.7.3.1/xio-fd.h0000644000201000020100000000401312161507203014112 0ustar gerhardgerhard/* source: xio-fd.h */ /* Copyright Gerhard Rieger 2001-2009 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_fd_h_included #define __xio_fd_h_included 1 extern const struct optdesc opt_ioctl_void; extern const struct optdesc opt_ioctl_int; extern const struct optdesc opt_ioctl_intp; extern const struct optdesc opt_ioctl_bin; extern const struct optdesc opt_ioctl_string; extern const struct optdesc opt_append; extern const struct optdesc opt_nonblock; extern const struct optdesc opt_o_ndelay; extern const struct optdesc opt_async; extern const struct optdesc opt_o_binary; extern const struct optdesc opt_o_text; extern const struct optdesc opt_o_noinherit; extern const struct optdesc opt_cloexec; extern const struct optdesc opt_ftruncate32; extern const struct optdesc opt_ftruncate64; extern const struct optdesc opt_group; extern const struct optdesc opt_group_late; extern const struct optdesc opt_perm; extern const struct optdesc opt_perm_late; extern const struct optdesc opt_user; extern const struct optdesc opt_user_late; extern const struct optdesc opt_lseek32_cur; extern const struct optdesc opt_lseek32_end; extern const struct optdesc opt_lseek32_set; extern const struct optdesc opt_lseek64_cur; extern const struct optdesc opt_lseek64_end; extern const struct optdesc opt_lseek64_set; extern const struct optdesc opt_flock_sh; extern const struct optdesc opt_flock_sh_nb; extern const struct optdesc opt_flock_ex; extern const struct optdesc opt_flock_ex_nb; extern const struct optdesc opt_f_setlk_rd; extern const struct optdesc opt_f_setlkw_rd; extern const struct optdesc opt_f_setlk_wr; extern const struct optdesc opt_f_setlkw_wr; extern const struct optdesc opt_cool_write; extern const struct optdesc opt_end_close; extern const struct optdesc opt_shut_none; extern const struct optdesc opt_shut_down; extern const struct optdesc opt_shut_close; extern const struct optdesc opt_shut_null; extern const struct optdesc opt_streams_i_push; #endif /* !defined(__xio_fd_h_included) */ socat-1.7.3.1/xio-tcpwrap.h0000644000201000020100000000134511453022152015204 0ustar gerhardgerhard/* source: xio-tcpwrap.h */ /* Copyright Gerhard Rieger 2006 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_tcpwrap_h_included #define __xio_tcpwrap_h_included 1 #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP extern const struct optdesc opt_tcpwrappers; extern const struct optdesc opt_tcpwrap_etc; extern const struct optdesc opt_tcpwrap_hosts_allow_table; extern const struct optdesc opt_tcpwrap_hosts_deny_table; extern int xio_retropt_tcpwrap(xiosingle_t *xfd, struct opt *opts); extern int xio_tcpwrap_check(xiosingle_t *xfd, union sockaddr_union *us, union sockaddr_union *them); #endif /* (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */ #endif /* !defined(__xio_tcpwrap_h_included) */ socat-1.7.3.1/xio-exec.c0000644000201000020100000001001712161511320014434 0ustar gerhardgerhard/* source: xio-exec.c */ /* Copyright Gerhard Rieger 2001-2011 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of exec type */ #include "xiosysincludes.h" #include "xioopen.h" #include "nestlex.h" #include "xio-progcall.h" #include "xio-exec.h" #if WITH_EXEC static int xioopen_exec(int argc, const char *argv[], struct opt *opts, int xioflags, /* XIO_RDONLY etc. */ xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3 ); const struct addrdesc addr_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 *fd, unsigned groups, int dummy1, int dummy2, int dummy3 ) { int status; bool dash = false; int duptostderr; if (argc != 2) { Error3("\"%s:%s\": wrong number of parameters (%d instead of 1)", argv[0], argv[1], argc-1); } retropt_bool(opts, OPT_DASH, &dash); status = _xioopen_foxec(xioflags, &fd->stream, groups, &opts, &duptostderr); if (status < 0) return status; if (status == 0) { /* child */ const char *ends[] = { " ", NULL }; const char *hquotes[] = { "'", NULL }; const char *squotes[] = { "\"", NULL }; const char *nests[] = { "'", "'", "(", ")", "[", "]", "{", "}", NULL } ; char **pargv = NULL; int pargc; size_t len; const char *strp; char *token; /*! */ char *tokp; char *path = NULL; char *tmp; int numleft; /*! Close(something) */ /* parse command line */ Debug1("child: args = \"%s\"", argv[1]); pargv = Malloc(8*sizeof(char *)); if (pargv == NULL) return STAT_RETRYLATER; len = strlen(argv[1])+1; strp = argv[1]; token = Malloc(len); /*! */ tokp = token; if (nestlex(&strp, &tokp, &len, ends, hquotes, squotes, nests, true, true, false) < 0) { Error("internal: miscalculated string lengths"); } *tokp++ = '\0'; pargv[0] = strrchr(tokp-1, '/'); if (pargv[0] == NULL) pargv[0] = token; else ++pargv[0]; pargc = 1; while (*strp == ' ') { while (*++strp == ' ') ; if ((pargc & 0x07) == 0) { pargv = Realloc(pargv, (pargc+8)*sizeof(char *)); if (pargv == NULL) return STAT_RETRYLATER; } pargv[pargc++] = tokp; if (nestlex(&strp, &tokp, &len, ends, hquotes, squotes, nests, true, true, false) < 0) { Error("internal: miscalculated string lengths"); } *tokp++ = '\0'; } pargv[pargc] = NULL; if ((tmp = Malloc(strlen(pargv[0])+2)) == NULL) { return STAT_RETRYLATER; } if (dash) { tmp[0] = '-'; strcpy(tmp+1, pargv[0]); } else { strcpy(tmp, pargv[0]); } pargv[0] = tmp; if (setopt_path(opts, &path) < 0) { /* this could be dangerous, so let us abort this child... */ Exit(1); } if ((numleft = leftopts(opts)) > 0) { Error1("%d option(s) could not be used", numleft); showleft(opts); return STAT_NORETRY; } /* only now redirect stderr */ if (duptostderr >= 0) { diag_dup(); Dup2(duptostderr, 2); } Notice1("execvp'ing \"%s\"", token); Execvp(token, pargv); /* here we come only if execvp() failed */ switch (pargc) { case 1: Error3("execvp(\"%s\", \"%s\"): %s", token, pargv[0], strerror(errno)); break; case 2: Error4("execvp(\"%s\", \"%s\", \"%s\"): %s", token, pargv[0], pargv[1], strerror(errno)); break; case 3: default: Error5("execvp(\"%s\", \"%s\", \"%s\", \"%s\", ...): %s", token, pargv[0], pargv[1], pargv[2], strerror(errno)); break; } Exit(1); /* this child process */ } /* parent */ return 0; } #endif /* WITH_EXEC */ socat-1.7.3.1/xio-listen.h0000644000201000020100000000137412161511320015021 0ustar gerhardgerhard/* source: xio-listen.h */ /* Copyright Gerhard Rieger 2001-2011 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_listen_h_included #define __xio_listen_h_included 1 extern const struct optdesc opt_backlog; extern const struct optdesc opt_fork; extern const struct optdesc opt_max_children; extern const struct optdesc opt_range; int xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, struct opt *opts0, int pf, int socktype, int proto); int _xioopen_listen(struct single *fd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, int pf, int socktype, int proto, int level); #endif /* !defined(__xio_listen_h_included) */