[libvirt] [PATCH v5 7/9] Implement _nss_libvirt_gethostbyname4_r

Michal Privoznik mprivozn at redhat.com
Fri Mar 18 15:18:14 UTC 2016


On 18.03.2016 15:09, Martin Kletzander wrote:
> On Tue, Mar 15, 2016 at 06:05:54PM +0100, Michal Privoznik wrote:
>> This function is a different beast compared to previous ones.
>> But yet again, nothing surprising is happening here.
>>
>> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
>> ---
>> tools/nss/libvirt_nss.c    | 92
>> ++++++++++++++++++++++++++++++++++++++++++++++
>> tools/nss/libvirt_nss.h    |  4 ++
>> tools/nss/libvirt_nss.syms |  1 +
>> 3 files changed, 97 insertions(+)
>>
>> diff --git a/tools/nss/libvirt_nss.c b/tools/nss/libvirt_nss.c
>> index 1b9ccba..9b80ace 100644
>> --- a/tools/nss/libvirt_nss.c
>> +++ b/tools/nss/libvirt_nss.c
>> @@ -364,3 +364,95 @@ _nss_libvirt_gethostbyname3_r(const char *name,
>> int af, struct hostent *result,
>>     VIR_FREE(addr);
>>     return ret;
>> }
>> +
>> +enum nss_status
>> +_nss_libvirt_gethostbyname4_r(const char *name, struct gaih_addrtuple
>> **pat,
>> +                              char *buffer, size_t buflen, int *errnop,
>> +                              int *herrnop, int32_t *ttlp)
>> +{
>> +    enum nss_status ret = NSS_STATUS_UNAVAIL;
>> +    leaseAddress *addr = NULL;
>> +    size_t naddr, i;
>> +    bool found = false;
>> +    int r;
>> +    size_t nameLen, need, idx;
>> +    struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL;
>> +    char *r_name;
>> +
>> +    if ((r = findLease(name, AF_UNSPEC, &addr, &naddr, &found,
>> errnop)) < 0) {
>> +        /* Error occurred. Return immediately. */
>> +        if (*errnop == EAGAIN) {
>> +            *herrnop = TRY_AGAIN;
>> +            return NSS_STATUS_TRYAGAIN;
>> +        } else {
>> +            *herrnop = NO_RECOVERY;
>> +            return NSS_STATUS_UNAVAIL;
>> +        }
>> +    }
>> +
>> +    if (!found) {
>> +        /* NOT found */
>> +        *errnop = ESRCH;
>> +        *herrnop = HOST_NOT_FOUND;
>> +        return NSS_STATUS_NOTFOUND;
>> +    } else if (!naddr) {
>> +        /* Found, but no data */
>> +        *errnop = ENXIO;
>> +        *herrnop = NO_DATA;
>> +        return NSS_STATUS_UNAVAIL;
>> +    }
>> +
>> +    /* Found and have data */
>> +
>> +    nameLen = strlen(name);
>> +    /* We need space for:
>> +     * a) name
>> +     * b) address */
>> +    need = ALIGN(nameLen + 1) + ALIGN(sizeof(struct gaih_addrtuple));
>> +
> 
> Shouldn't this be ' + naddr * ALIGN('... ???

Yes, good catch.

> 
>> +    if (buflen < need) {
>> +        *errnop = ENOMEM;
>> +        *herrnop = TRY_AGAIN;
>> +        ret = NSS_STATUS_TRYAGAIN;
>> +        goto cleanup;
>> +    }
>> +
>> +    /* First, append name */
>> +    r_name = buffer;
>> +    memcpy(r_name, name, nameLen + 1);
>> +    idx = ALIGN(nameLen + 1);
>> +
>> +
>> +    /* Second, append addresses */
>> +    r_tuple_first = (struct gaih_addrtuple*) (buffer + idx);
>> +    for (i = 0; i < naddr; i++) {
>> +        int family = addr[i].af;
>> +
>> +        r_tuple = (struct gaih_addrtuple*) (buffer + idx);
>> +        r_tuple->next = i == naddr - 1 ? NULL : (struct
>> gaih_addrtuple*) ((char*) r_tuple + ALIGN(sizeof(struct
>> gaih_addrtuple)));
> 
> This would be more readable with a proper condition instead of this long
> line.

Okay.

Michal




More information about the libvir-list mailing list