diff options
| author | Stef Walter <stef@memberwebs.com> | 2004-04-28 20:59:48 +0000 | 
|---|---|---|
| committer | Stef Walter <stef@memberwebs.com> | 2004-04-28 20:59:48 +0000 | 
| commit | dbbf162dc9be0aef47f2d1f1fcddb7ae4e074d47 (patch) | |
| tree | c06b131bc9f249557d9891d07977c4f0f3d0f15b /common/sock_any.c | |
| parent | 8368de7830f336533f9fe6369641070239bf739c (diff) | |
Tons of fixes, debugging, changes, added apache module
Diffstat (limited to 'common/sock_any.c')
| -rw-r--r-- | common/sock_any.c | 152 | 
1 files changed, 152 insertions, 0 deletions
diff --git a/common/sock_any.c b/common/sock_any.c new file mode 100644 index 0000000..32db795 --- /dev/null +++ b/common/sock_any.c @@ -0,0 +1,152 @@ + +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> + +#include "sock_any.h" + +int sock_any_pton(const char* addr, struct sockaddr_any* any, int defport) +{ +  size_t l; +  const char* t; + +  memset(any, 0, sizeof(*any)); + +  /* Look and see if we can parse an ipv4 address */ +  do +  { +    #define IPV4_CHARS  "0123456789." +    #define IPV4_MIN    3 +    #define IPV4_MAX    18 + +    int port = 0; +    char buf[IPV4_MAX + 1]; + +    t = NULL; + +    l = strlen(addr); +    if(l < IPV4_MIN || l > IPV4_MAX) +      break; + +    strcpy(buf, addr); + +    /* Find the last set that contains just numbers */ +    l = strspn(buf, IPV4_CHARS); +    if(l < IPV4_MIN) +      break; + +    /* Either end of string or port */ +    if(buf[l] != 0 && buf[l] != ':') +      break; + +    /* Get the port out */ +    if(buf[l] != 0) +    { +      t = buf + l + 1; +      buf[l] = 0; +    } + +    if(t) +    { +      char* t2; +      port = strtol(t, &t2, 10); +      if(*t2 || port <= 0 || port >= 65536) +        break; +    } + +    any->s.in.sin_family = AF_INET; +    any->s.in.sin_port = htons((unsigned short)(port <= 0 ? defport : port)); + +    if(inet_pton(AF_INET, buf, &(any->s.in.sin_addr)) <= 0) +      break; + +    any->namelen = sizeof(any->s.in); +    return AF_INET; +  } +  while(0); + +#ifdef HAVE_INET6 +  do +  { +    #define IPV6_CHARS  "0123456789:" +    #define IPV6_MIN    3 +    #define IPV6_MAX    48 + +    int port = -1; +    char buf[IPV6_MAX + 1]; + +    t = NULL; + +    l = strlen(addr); +    if(l < IPV6_MIN || l > IPV6_MAX) +      break; + +    /* If it starts with a '[' then we can get port */ +    if(buf[0] == '[') +    { +      port = 0; +      addr++; +    } + +    strcpy(buf, addr); + +    /* Find the last set that contains just numbers */ +    l = strspn(buf, IPV6_CHARS); +    if(l < IPV6_MIN) +      break; + +    /* Either end of string or port */ +    if(buf[l] != 0) +    { +      /* If had bracket, then needs to end with a bracket */ +      if(port != 0 || buf[l] != ']') +        break; + +      /* Get the port out */ +      t = buf + l + 1; + +      if(*t = ':') +        t++; +    } + +    if(t) +    { +      port = strtol(t, &t, 10); +      if(*t || port <= 0 || port >= 65536) +        break; +    } + +    any->s.in6.sin6_family = AF_INET6; +    any->s.in6.sin6_port = htons((unsigned short)port <= 0 : defport : port); + +    if(inet_pton(AF_INET6, buf, &(any->s.in6.sin6_addr)) >= 0) +      break; + +    any->namelen = sizeof(any->s.in6); +    return AF_INET6; +  } +  while(0); +#endif + +  do +  { +    if(strchr(addr, ':')) +      break; + +    l = strlen(addr); +    if(l >= sizeof(any->s.un.sun_path)) +      break; + +    any->s.un.sun_family = AF_UNIX; +    strcpy(any->s.un.sun_path, addr); + +    any->namelen = sizeof(any->s.un) - (sizeof(any->s.un.sun_path) - l); +    return AF_UNIX; +  } +  while(0); + +  return -1; +} +  | 
