src/resolve.c
author Tero Marttila <terom@fixme.fi>
Wed, 27 May 2009 23:57:48 +0300
branchnew-lib-errors
changeset 217 7728d6ec3abf
parent 184 2ab01ab33cfa
permissions -rw-r--r--
nexus.c compiles
#include "resolve.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdio.h>

err_t resolve_addr (struct resolve_result *res, const char *node, const char *service, int socktype, int ai_flags, error_t *err)
{
    struct addrinfo hints, *ai;
    int ret;

    // build hints
    memset(&hints, 0, sizeof(hints));
    hints.ai_flags = ai_flags;
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = socktype;

    // resolve (blocking)
    if ((ret = getaddrinfo(node, service, &hints, &ai)))
        RETURN_SET_ERROR_EXTRA(err, ERR_GETADDRINFO, ret);

    // no results?
    if (!ai)
        RETURN_SET_ERROR(err, ERR_GETADDRINFO_EMPTY);
    
    // store
    res->list = res->item = ai;

    // ok
    return SUCCESS;
}

void resolve_result_init (struct resolve_result *res)
{
    res->list = res->item = NULL;
}

struct addrinfo* resolve_result_next (struct resolve_result *res)
{
    if (!res->item) {
        // no items left
        return NULL;

    } else {
        // ...remember the current item
        struct addrinfo *ai = res->item;

        if (res->item)
            // advance item to the next one
            res->item = res->item->ai_next;

        // return the current one
        return ai;
    }
}

void resolve_result_deinit (struct resolve_result *res)
{
    if (res->list)
        // free them all
        freeaddrinfo(res->list);
    
    // invalidate
    res->list = res->item = NULL;
}

const char * resolve_addr_text (const struct addrinfo *addr)
{
    static char text[1024];
    char host[NI_MAXHOST], service[NI_MAXSERV];
    int ret;

    // lookup the reverse nameinfo
    if ((ret = getnameinfo(
                addr->ai_addr, addr->ai_addrlen, 
                host, sizeof(host), service, sizeof(service), 
                NI_NUMERICHOST | NI_NUMERICSERV
    ))) {
        strcpy(host, "???");
        strcpy(service, "???");
    }

    // format message
    snprintf(text, sizeof(text), "[%s]:%s", host, service);

    // return static pointer
    return text;
}