Every aligning requires at least one cast and it's hard to read. Let's
make a function that makes sure the pointer is moved according to the
alignment and use that to move throughout the data buffer.
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
v2:
- Initialize @idx in _nss_libvirt_gethostbyname4_r as well
tools/nss/libvirt_nss.c | 53 +++++++++++++++++++++++++++++++------------------
1 file changed, 34 insertions(+), 19 deletions(-)
diff --git a/tools/nss/libvirt_nss.c b/tools/nss/libvirt_nss.c
index ba3bb31b3569..218c62a64c88 100644
--- a/tools/nss/libvirt_nss.c
+++ b/tools/nss/libvirt_nss.c
@@ -252,17 +252,31 @@ _nss_libvirt_gethostbyname2_r(const char *name, int af, struct
hostent *result,
errnop, herrnop, NULL, NULL);
}
+static inline void *
+move_and_align(void *buf, size_t len, size_t *idx)
+{
+ char *buffer = buf;
+ size_t move = ALIGN(len);
+
+ if (!idx)
+ return buffer + move;
+
+ *idx += move;
+
+ return buffer + *idx;
+}
+
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 ret = NSS_STATUS_UNAVAIL;
- char *r_name, **r_aliases, *r_addr, **r_addr_list;
+ char *r_name, **r_aliases, *r_addr, *r_addr_next, **r_addr_list;
leaseAddress *addr = NULL;
size_t naddr, i;
bool found = false;
- size_t nameLen, need, idx;
+ size_t nameLen, need, idx = 0;
int alen;
int r;
@@ -319,23 +333,27 @@ _nss_libvirt_gethostbyname3_r(const char *name, int af, struct
hostent *result,
/* First, append name */
r_name = buffer;
memcpy(r_name, name, nameLen + 1);
- idx = ALIGN(nameLen + 1);
+
+ r_aliases = move_and_align(buffer, nameLen + 1, &idx);
/* Second, create aliases array */
- r_aliases = (char **) buffer + idx;
r_aliases[0] = NULL;
- idx += sizeof(char*);
/* Third, append address */
- r_addr = buffer + idx;
- for (i = 0; i < naddr; i++)
- memcpy(r_addr + i * ALIGN(alen), addr[i].addr, alen);
- idx += naddr * ALIGN(alen);
+ r_addr = move_and_align(buffer, sizeof(char *), &idx);
+ r_addr_next = r_addr;
+ for (i = 0; i < naddr; i++) {
+ memcpy(r_addr_next, addr[i].addr, alen);
+ r_addr_next = move_and_align(buffer, alen, &idx);
+ }
+ r_addr_list = move_and_align(buffer, 0, &idx);
+ r_addr_next = r_addr;
/* Third, append address pointer array */
- r_addr_list = (char **) buffer + idx;
- for (i = 0; i < naddr; i++)
- r_addr_list[i] = r_addr + i * ALIGN(alen);
+ for (i = 0; i < naddr; i++) {
+ r_addr_list[i] = r_addr_next;
+ r_addr_next = move_and_align(r_addr_next, alen, NULL);
+ }
r_addr_list[i] = NULL;
idx += (naddr + 1) * sizeof(char*);
@@ -375,7 +393,7 @@ _nss_libvirt_gethostbyname4_r(const char *name, struct gaih_addrtuple
**pat,
size_t naddr, i;
bool found = false;
int r;
- size_t nameLen, need, idx;
+ size_t nameLen, need, idx = 0;
struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL;
char *r_name;
@@ -420,25 +438,22 @@ _nss_libvirt_gethostbyname4_r(const char *name, struct
gaih_addrtuple **pat,
/* 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);
+ r_tuple_first = move_and_align(buffer, nameLen + 1, &idx);
for (i = 0; i < naddr; i++) {
int family = addr[i].af;
- r_tuple = (struct gaih_addrtuple*) (buffer + idx);
+ r_tuple = move_and_align(buffer, 0, &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->next = move_and_align(buffer, sizeof(struct gaih_addrtuple),
&idx);
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 */
--
2.7.3