]> xenbits.xensource.com Git - libvirt.git/commitdiff
Implement _nss_libvirt_gethostbyname4_r
authorMichal Privoznik <mprivozn@redhat.com>
Sun, 14 Feb 2016 07:13:54 +0000 (08:13 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 18 Mar 2016 16:29:53 +0000 (17:29 +0100)
This function is a different beast compared to previous ones.
But yet again, nothing surprising is happening here.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
tools/nss/libvirt_nss.c
tools/nss/libvirt_nss.h
tools/nss/libvirt_nss.syms

index 1b9ccba6075c45c6658ad4c5615022cfd414cbb6..ba3bb31b3569d9459a93c198a47c166a124da880 100644 (file)
@@ -364,3 +364,98 @@ _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) addresses */
+    need = ALIGN(nameLen + 1) + naddr * ALIGN(sizeof(struct gaih_addrtuple));
+
+    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);
+        if (i == naddr - 1)
+            r_tuple->next = NULL;
+        else
+            r_tuple->next = (struct gaih_addrtuple*) ((char*) r_tuple + ALIGN(sizeof(struct gaih_addrtuple)));
+        r_tuple->name = r_name;
+        r_tuple->family = family;
+        r_tuple->scopeid = 0;
+        memcpy(r_tuple->addr, addr[i].addr, FAMILY_ADDRESS_SIZE(family));
+
+        idx += ALIGN(sizeof(struct gaih_addrtuple));
+    }
+
+    /* At this point, idx == need */
+    DEBUG("Done idx:%zd need:%zd", idx, need);
+
+    if (*pat)
+        **pat = *r_tuple_first;
+    else
+        *pat = r_tuple_first;
+
+    if (ttlp)
+        *ttlp = 0;
+
+    /* Explicitly reset all error variables */
+    *errnop = 0;
+    *herrnop = NETDB_SUCCESS;
+    ret = NSS_STATUS_SUCCESS;
+ cleanup:
+    return ret;
+}
index dd037f555c83e8c715dc567d353b83ca46c1b905..589c1e6e0919c830f9e8dba4db2d319593781def 100644 (file)
@@ -45,4 +45,8 @@ enum nss_status
 _nss_libvirt_gethostbyname3_r(const char *name, int af, struct hostent *result,
                               char *buffer, size_t buflen, int *errnop,
                               int *herrnop, int32_t *ttlp, char **canonp);
+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);
 #endif /* __LIBVIRT_NSS_H__ */
index b88b8be3a004e65e9cf56517aeb1d5d1a9356ced..5a793e47e63e965bb0299c442b449781f62f964c 100644 (file)
@@ -7,5 +7,6 @@ global:
     _nss_libvirt_gethostbyname_r;
     _nss_libvirt_gethostbyname2_r;
     _nss_libvirt_gethostbyname3_r;
+    _nss_libvirt_gethostbyname4_r;
 local: *;
 };