src/lib/resolve.c
branchnew-lib-errors
changeset 219 cefec18b8268
parent 184 2ab01ab33cfa
equal deleted inserted replaced
218:5229a5d098b2 219:cefec18b8268
       
     1 #include "resolve.h"
       
     2 
       
     3 #include <sys/types.h>
       
     4 #include <sys/socket.h>
       
     5 #include <string.h>
       
     6 #include <stdio.h>
       
     7 
       
     8 static const char* _gai_error_msg (const struct error_extra_type *type, const union error_extra *extra)
       
     9 {
       
    10     (void) type;
       
    11 
       
    12     return gai_strerror(extra->int_);
       
    13 }
       
    14 
       
    15 static const struct error_extra_type _gai_error_type = {
       
    16     .name       = "gai",
       
    17     .msg_func   = _gai_error_msg
       
    18 };
       
    19 
       
    20 
       
    21 
       
    22 const struct error_list resolve_errors = ERROR_LIST("resolve",
       
    23     ERROR_TYPE_EXTRA(   ERR_RESOLVE_GETADDRINFO,        "getaddrinfo",              &_gai_error_type),
       
    24     ERROR_TYPE_EXTRA(   ERR_RESOLVE_GETADDRINFO_EMPTY,  "getaddrinfo: no results",  &_gai_error_type)
       
    25 
       
    26 );
       
    27 
       
    28 err_t resolve_addr (struct resolve_result *res, const char *node, const char *service, int socktype, int ai_flags, error_t *err)
       
    29 {
       
    30     struct addrinfo hints, *ai;
       
    31     int ret;
       
    32 
       
    33     // build hints
       
    34     memset(&hints, 0, sizeof(hints));
       
    35     hints.ai_flags = ai_flags;
       
    36     hints.ai_family = AF_UNSPEC;
       
    37     hints.ai_socktype = socktype;
       
    38 
       
    39     // resolve (blocking)
       
    40     if ((ret = getaddrinfo(node, service, &hints, &ai)))
       
    41         return SET_ERROR_EXTRA(err, &resolve_errors, ERR_RESOLVE_GETADDRINFO, &_gai_error_type, ret);
       
    42 
       
    43     // no results?
       
    44     if (!ai)
       
    45         return SET_ERROR(err, &resolve_errors, ERR_RESOLVE_GETADDRINFO_EMPTY);
       
    46     
       
    47     // store
       
    48     res->list = res->item = ai;
       
    49 
       
    50     // ok
       
    51     return SUCCESS;
       
    52 }
       
    53 
       
    54 void resolve_result_init (struct resolve_result *res)
       
    55 {
       
    56     res->list = res->item = NULL;
       
    57 }
       
    58 
       
    59 struct addrinfo* resolve_result_next (struct resolve_result *res)
       
    60 {
       
    61     if (!res->item) {
       
    62         // no items left
       
    63         return NULL;
       
    64 
       
    65     } else {
       
    66         // ...remember the current item
       
    67         struct addrinfo *ai = res->item;
       
    68 
       
    69         if (res->item)
       
    70             // advance item to the next one
       
    71             res->item = res->item->ai_next;
       
    72 
       
    73         // return the current one
       
    74         return ai;
       
    75     }
       
    76 }
       
    77 
       
    78 void resolve_result_deinit (struct resolve_result *res)
       
    79 {
       
    80     if (res->list)
       
    81         // free them all
       
    82         freeaddrinfo(res->list);
       
    83     
       
    84     // invalidate
       
    85     res->list = res->item = NULL;
       
    86 }
       
    87 
       
    88 const char * resolve_addr_text (const struct addrinfo *addr)
       
    89 {
       
    90     static char text[1024];
       
    91     char host[NI_MAXHOST], service[NI_MAXSERV];
       
    92     int ret;
       
    93 
       
    94     // lookup the reverse nameinfo
       
    95     if ((ret = getnameinfo(
       
    96                 addr->ai_addr, addr->ai_addrlen, 
       
    97                 host, sizeof(host), service, sizeof(service), 
       
    98                 NI_NUMERICHOST | NI_NUMERICSERV
       
    99     ))) {
       
   100         strcpy(host, "???");
       
   101         strcpy(service, "???");
       
   102     }
       
   103 
       
   104     // format message
       
   105     snprintf(text, sizeof(text), "[%s]:%s", host, service);
       
   106 
       
   107     // return static pointer
       
   108     return text;
       
   109 }