summaryrefslogtreecommitdiff
path: root/lib/libc/asr
diff options
context:
space:
mode:
authorEric Faurot <eric@cvs.openbsd.org>2012-11-24 18:58:50 +0000
committerEric Faurot <eric@cvs.openbsd.org>2012-11-24 18:58:50 +0000
commit8e17c0a531a8f51ea0660a4e318c33b30b443744 (patch)
tree8716a68071dd31db66f03d817c77caef11f80859 /lib/libc/asr
parentfcbc6cf70863a4f7958222f71957bceeaa9837db (diff)
Saner implementation for self-contained hostent and netent, and also
a couple of fixes.
Diffstat (limited to 'lib/libc/asr')
-rw-r--r--lib/libc/asr/gethostnamadr_async.c195
-rw-r--r--lib/libc/asr/getnetnamadr_async.c146
2 files changed, 177 insertions, 164 deletions
diff --git a/lib/libc/asr/gethostnamadr_async.c b/lib/libc/asr/gethostnamadr_async.c
index 3fa6cef699a..0283a77bd40 100644
--- a/lib/libc/asr/gethostnamadr_async.c
+++ b/lib/libc/asr/gethostnamadr_async.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gethostnamadr_async.c,v 1.10 2012/11/24 15:12:48 eric Exp $ */
+/* $OpenBSD: gethostnamadr_async.c,v 1.11 2012/11/24 18:58:49 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -36,27 +36,30 @@
#include "asr.h"
#include "asr_private.h"
-
#define MAXALIASES 16
#define MAXADDRS 16
-#define HOSTENT_PTR(h) ((char**)(((char*)h) + sizeof (*h)))
-#define HOSTENT_POS(h) HOSTENT_PTR(h)[0]
-#define HOSTENT_STOP(h) HOSTENT_PTR(h)[1]
-#define HOSTENT_LEFT(h) (HOSTENT_STOP(h) - HOSTENT_POS(h))
+struct hostent_ext {
+ struct hostent h;
+ char *aliases[MAXALIASES + 1];
+ char *addrs[MAXADDRS + 1];
+ char *end;
+ char *pos;
+};
ssize_t addr_as_fqdn(const char *, int, char *, size_t);
static int gethostnamadr_async_run(struct async *, struct async_res *);
-static struct hostent *hostent_alloc(int);
-static int hostent_set_cname(struct hostent *, const char *, int);
-static int hostent_add_alias(struct hostent *, const char *, int);
-static int hostent_add_addr(struct hostent *, const void *, int);
-static struct hostent *hostent_file_match(FILE *, int, int, const char *, int);
-static struct hostent *hostent_from_packet(int, int, char *, size_t);
+static struct hostent_ext *hostent_alloc(int);
+static int hostent_set_cname(struct hostent_ext *, const char *, int);
+static int hostent_add_alias(struct hostent_ext *, const char *, int);
+static int hostent_add_addr(struct hostent_ext *, const void *, size_t);
+static struct hostent_ext *hostent_file_match(FILE *, int, int, const char *,
+ int);
+static struct hostent_ext *hostent_from_packet(int, int, char *, size_t);
#ifdef YP
-static struct hostent *_yp_gethostnamadr(int, const void *);
-static struct hostent *hostent_from_yp(int, char *);
+static struct hostent_ext *_yp_gethostnamadr(int, const void *);
+static struct hostent_ext *hostent_from_yp(int, char *);
#endif
struct async *
@@ -140,9 +143,10 @@ gethostbyaddr_async_ctx(const void *addr, socklen_t len, int af,
static int
gethostnamadr_async_run(struct async *as, struct async_res *ar)
{
- int r, type;
- FILE *f;
- char dname[MAXDNAME], *data;
+ struct hostent_ext *h;
+ int r, type, saved_errno;
+ FILE *f;
+ char dname[MAXDNAME], *data;
next:
switch (as->as_state) {
@@ -246,13 +250,14 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar)
else
data = as->as.hostnamadr.addr;
- ar->ar_hostent = hostent_file_match(f, as->as_type,
+ h = hostent_file_match(f, as->as_type,
as->as.hostnamadr.family, data,
as->as.hostnamadr.addrlen);
-
+ saved_errno = errno;
fclose(f);
+ errno = saved_errno;
- if (ar->ar_hostent == NULL) {
+ if (h == NULL) {
if (errno) {
ar->ar_errno = errno;
ar->ar_h_errno = NETDB_INTERNAL;
@@ -261,7 +266,7 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar)
/* otherwise not found */
break;
}
-
+ ar->ar_hostent = &h->h;
ar->ar_h_errno = NETDB_SUCCESS;
async_set_state(as, ASR_STATE_HALT);
break;
@@ -274,8 +279,8 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar)
data = as->as.hostnamadr.dname;
else
data = as->as.hostnamadr.addr;
- ar->ar_hostent = _yp_gethostnamadr(as->as_type, data);
- if (ar->ar_hostent == NULL) {
+ h = _yp_gethostnamadr(as->as_type, data);
+ if (h == NULL) {
if (errno) {
ar->ar_errno = errno;
ar->ar_h_errno = NETDB_INTERNAL;
@@ -284,7 +289,7 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar)
/* otherwise not found */
break;
}
-
+ ar->ar_hostent = &h->h;
ar->ar_h_errno = NETDB_SUCCESS;
async_set_state(as, ASR_STATE_HALT);
break;
@@ -316,11 +321,10 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar)
/* Read the hostent from the packet. */
- ar->ar_hostent = hostent_from_packet(as->as_type,
+ h = hostent_from_packet(as->as_type,
as->as.hostnamadr.family, ar->ar_data, ar->ar_datalen);
free(ar->ar_data);
-
- if (ar->ar_hostent == NULL) {
+ if (h == NULL) {
ar->ar_errno = errno;
ar->ar_h_errno = NETDB_INTERNAL;
async_set_state(as, ASR_STATE_HALT);
@@ -328,10 +332,9 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar)
}
if (as->as_type == ASR_GETHOSTBYADDR) {
- if (hostent_add_addr(ar->ar_hostent,
- as->as.hostnamadr.addr,
+ if (hostent_add_addr(h, as->as.hostnamadr.addr,
as->as.hostnamadr.addrlen) == -1) {
- free(ar->ar_hostent);
+ free(h);
ar->ar_errno = errno;
ar->ar_h_errno = NETDB_INTERNAL;
async_set_state(as, ASR_STATE_HALT);
@@ -344,12 +347,13 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar)
* reports this as an error.
*/
if (as->as_type == ASR_GETHOSTBYNAME &&
- ar->ar_hostent->h_addr_list[0] == NULL) {
- free(ar->ar_hostent);
+ h->h.h_addr_list[0] == NULL) {
+ free(h);
async_set_state(as, ASR_STATE_NEXT_DB);
break;
}
+ ar->ar_hostent = &h->h;
ar->ar_h_errno = NETDB_SUCCESS;
async_set_state(as, ASR_STATE_HALT);
break;
@@ -381,12 +385,12 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar)
* Lookup the first matching entry in the hostfile, either by address or by
* name depending on reqtype, and build a hostent from the line.
*/
-static struct hostent *
+static struct hostent_ext *
hostent_file_match(FILE *f, int reqtype, int family, const char *data,
int datalen)
{
char *tokens[MAXTOKEN], addr[16];
- struct hostent *h;
+ struct hostent_ext *h;
int n, i;
for (;;) {
@@ -404,9 +408,9 @@ hostent_file_match(FILE *f, int reqtype, int family, const char *data,
goto found;
}
} else {
- if (inet_pton(family, tokens[0], addr) == 1)
- if (memcmp(addr, data, datalen) == 0)
- goto found;
+ if (inet_pton(family, tokens[0], addr) == 1 &&
+ memcmp(addr, data, datalen) == 0)
+ goto found;
}
}
@@ -418,7 +422,7 @@ found:
for (i = 2; i < n; i ++)
if (hostent_add_alias(h, tokens[i], 0) == -1)
goto fail;
- if (hostent_add_addr(h, addr, h->h_length) == -1)
+ if (hostent_add_addr(h, addr, h->h.h_length) == -1)
goto fail;
return (h);
fail:
@@ -429,10 +433,10 @@ fail:
/*
* Fill the hostent from the given DNS packet.
*/
-static struct hostent *
+static struct hostent_ext *
hostent_from_packet(int reqtype, int family, char *pkt, size_t pktlen)
{
- struct hostent *h;
+ struct hostent_ext *h;
struct unpack p;
struct header hdr;
struct query q;
@@ -499,95 +503,96 @@ fail:
return (NULL);
}
-static struct hostent *
+static struct hostent_ext *
hostent_alloc(int family)
{
- struct hostent *h;
- size_t alloc;
+ struct hostent_ext *h;
+ size_t alloc;
- alloc = sizeof(*h) + (2 + MAXALIASES + MAXADDRS) * sizeof(char*) + 1024;
+ alloc = sizeof(*h) + 1024;
if ((h = calloc(1, alloc)) == NULL)
return (NULL);
- h->h_addrtype = family;
- h->h_length = (family == AF_INET) ? 4 : 16;
- h->h_aliases = HOSTENT_PTR(h) + 2;
- h->h_addr_list = h->h_aliases + MAXALIASES;
-
- HOSTENT_STOP(h) = (char*)(h) + alloc;
- HOSTENT_POS(h) = (char*)(h->h_addr_list + MAXADDRS);
+ h->h.h_addrtype = family;
+ h->h.h_length = (family == AF_INET) ? 4 : 16;
+ h->h.h_aliases = h->aliases;
+ h->h.h_addr_list = h->addrs;
+ h->pos = (char*)(h) + sizeof(*h);
+ h->end = h->pos + 1024;
return (h);
}
static int
-hostent_set_cname(struct hostent *h, const char *name, int isdname)
+hostent_set_cname(struct hostent_ext *h, const char *name, int isdname)
{
char buf[MAXDNAME];
+ size_t n;
- if (h->h_name)
- return (0);
+ if (h->h.h_name)
+ return (-1);
if (isdname) {
asr_strdname(name, buf, sizeof buf);
buf[strlen(buf) - 1] = '\0';
name = buf;
}
- if (strlen(name) + 1 >= HOSTENT_LEFT(h))
- return (1);
- strlcpy(HOSTENT_POS(h), name, HOSTENT_LEFT(h));
- h->h_name = HOSTENT_POS(h);
- HOSTENT_POS(h) += strlen(name) + 1;
+ n = strlen(name) + 1;
+ if (h->pos + n >= h->end)
+ return (-1);
+ h->h.h_name = h->pos;
+ memmove(h->pos, name, n);
+ h->pos += n;
return (0);
}
static int
-hostent_add_alias(struct hostent *h, const char *name, int isdname)
+hostent_add_alias(struct hostent_ext *h, const char *name, int isdname)
{
char buf[MAXDNAME];
- size_t i;
+ size_t i, n;
- for (i = 0; i < MAXALIASES - 1; i++)
- if (h->h_aliases[i] == NULL)
+ for (i = 0; i < MAXALIASES; i++)
+ if (h->aliases[i] == NULL)
break;
- if (i == MAXALIASES - 1)
- return (0);
+ if (i == MAXALIASES)
+ return (-1);
if (isdname) {
asr_strdname(name, buf, sizeof buf);
buf[strlen(buf)-1] = '\0';
name = buf;
}
- if (strlen(name) + 1 >= HOSTENT_LEFT(h))
- return (1);
- strlcpy(HOSTENT_POS(h), name, HOSTENT_LEFT(h));
- h->h_aliases[i] = HOSTENT_POS(h);
- HOSTENT_POS(h) += strlen(name) + 1;
+ n = strlen(name) + 1;
+ if (h->pos + n >= h->end)
+ return (-1);
+ h->aliases[i] = h->pos;
+ memmove(h->pos, name, n);
+ h->pos += n;
return (0);
}
static int
-hostent_add_addr(struct hostent *h, const void *addr, int size)
+hostent_add_addr(struct hostent_ext *h, const void *addr, size_t size)
{
int i;
- for (i = 0; i < MAXADDRS - 1; i++)
- if (h->h_addr_list[i] == NULL)
+ for (i = 0; i < MAXADDRS; i++)
+ if (h->addrs[i] == NULL)
break;
- if (i == MAXADDRS - 1)
- return (0);
-
- if (size >= HOSTENT_LEFT(h))
- return (1);
+ if (i == MAXADDRS)
+ return (-1);
- memmove(HOSTENT_POS(h), addr, size);
- h->h_addr_list[i] = HOSTENT_POS(h);
- HOSTENT_POS(h) += size;
+ if (h->pos + size >= h->end)
+ return (-1);
+ h->addrs[i] = h->pos;
+ memmove(h->pos, addr, size);
+ h->pos += size;
return (0);
}
@@ -653,15 +658,15 @@ addr_as_fqdn(const char *addr, int family, char *dst, size_t max)
}
#ifdef YP
-static struct hostent *
+static struct hostent_ext *
_yp_gethostnamadr(int type, const void *data)
{
- static char *domain = NULL;
- struct hostent *h = NULL;
- const char *name;
- char buf[MAXHOSTNAMELEN];
- char *res = NULL;
- int r, len;
+ static char *domain = NULL;
+ struct hostent_ext *h = NULL;
+ const char *name;
+ char buf[MAXHOSTNAMELEN];
+ char *res = NULL;
+ int r, len;
if (!domain && _yp_check(&domain) == 0) {
errno = 0; /* ignore yp_bind errors */
@@ -705,12 +710,12 @@ strsplit(char *line, char **tokens, int ntokens)
return (ntok);
}
-static struct hostent *
+static struct hostent_ext *
hostent_from_yp(int family, char *line)
{
- struct hostent *h;
- char *next, *tokens[10], addr[IN6ADDRSZ];
- int i, ntok;
+ struct hostent_ext *h;
+ char *next, *tokens[10], addr[IN6ADDRSZ];
+ int i, ntok;
if ((h = hostent_alloc(family)) == NULL)
return (NULL);
@@ -727,15 +732,15 @@ hostent_from_yp(int family, char *line)
hostent_add_addr(h, addr, family == AF_INET ?
INADDRSZ : IN6ADDRSZ);
i = 2;
- if (!h->h_name)
+ if (h->h.h_name == NULL)
hostent_set_cname(h, tokens[1], 0);
- else if (strcmp(h->h_name, tokens[1]))
+ else if (strcmp(h->h.h_name, tokens[1]))
i = 1;
for (; i < ntok; i++)
hostent_add_alias(h, tokens[i], 0);
}
- if (h->h_name == NULL) {
+ if (h->h.h_name == NULL) {
free(h);
return (NULL);
}
diff --git a/lib/libc/asr/getnetnamadr_async.c b/lib/libc/asr/getnetnamadr_async.c
index a8e10d1ea20..8c045c764cf 100644
--- a/lib/libc/asr/getnetnamadr_async.c
+++ b/lib/libc/asr/getnetnamadr_async.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getnetnamadr_async.c,v 1.6 2012/11/24 15:12:48 eric Exp $ */
+/* $OpenBSD: getnetnamadr_async.c,v 1.7 2012/11/24 18:58:49 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -32,19 +32,21 @@
#define MAXALIASES 16
-#define NETENT_PTR(n) ((char**)(((char*)n) + sizeof (*n)))
-#define NETENT_POS(n) NETENT_PTR(n)[0]
-#define NETENT_STOP(n) NETENT_PTR(n)[1]
-#define NETENT_LEFT(n) (NETENT_STOP(n) - NETENT_POS(n))
+struct netent_ext {
+ struct netent n;
+ char *aliases[MAXALIASES + 1];
+ char *end;
+ char *pos;
+};
ssize_t addr_as_fqdn(const char *, int, char *, size_t);
static int getnetnamadr_async_run(struct async *, struct async_res *);
-static struct netent *netent_alloc(int);
-static int netent_set_cname(struct netent *, const char *, int);
-static int netent_add_alias(struct netent *, const char *, int);
-static struct netent *netent_file_match(FILE *, int, const char *);
-static struct netent *netent_from_packet(int, char *, size_t);
+static struct netent_ext *netent_alloc(int);
+static int netent_set_cname(struct netent_ext *, const char *, int);
+static int netent_add_alias(struct netent_ext *, const char *, int);
+static struct netent_ext *netent_file_match(FILE *, int, const char *);
+static struct netent_ext *netent_from_packet(int, char *, size_t);
struct async *
getnetbyname_async(const char *name, struct asr *asr)
@@ -105,10 +107,11 @@ getnetbyaddr_async(in_addr_t net, int family, struct asr *asr)
static int
getnetnamadr_async_run(struct async *as, struct async_res *ar)
{
- int r, type;
- FILE *f;
- char dname[MAXDNAME], *name, *data;
- in_addr_t in;
+ struct netent_ext *n;
+ int r, type, saved_errno;
+ FILE *f;
+ char dname[MAXDNAME], *name, *data;
+ in_addr_t in;
next:
switch (as->as_state) {
@@ -176,10 +179,11 @@ getnetnamadr_async_run(struct async *as, struct async_res *ar)
else
data = (void*)&as->as.netnamadr.addr;
- ar->ar_netent = netent_file_match(f, as->as_type, data);
+ n = netent_file_match(f, as->as_type, data);
+ saved_errno = errno;
fclose(f);
-
- if (ar->ar_netent == NULL) {
+ errno = saved_errno;
+ if (n == NULL) {
if (errno) {
ar->ar_errno = errno;
ar->ar_h_errno = NETDB_INTERNAL;
@@ -189,6 +193,7 @@ getnetnamadr_async_run(struct async *as, struct async_res *ar)
break;
}
+ ar->ar_netent = &n->n;
ar->ar_h_errno = NETDB_SUCCESS;
async_set_state(as, ASR_STATE_HALT);
break;
@@ -213,11 +218,10 @@ getnetnamadr_async_run(struct async *as, struct async_res *ar)
break;
}
- ar->ar_netent = netent_from_packet(as->as_type, ar->ar_data,
+ n = netent_from_packet(as->as_type, ar->ar_data,
ar->ar_datalen);
free(ar->ar_data);
-
- if (ar->ar_netent == NULL) {
+ if (n == NULL) {
ar->ar_errno = errno;
ar->ar_h_errno = NETDB_INTERNAL;
async_set_state(as, ASR_STATE_HALT);
@@ -225,21 +229,22 @@ getnetnamadr_async_run(struct async *as, struct async_res *ar)
}
if (as->as_type == ASR_GETNETBYADDR)
- ar->ar_netent->n_net = as->as.netnamadr.addr;
+ n->n.n_net = as->as.netnamadr.addr;
/*
* No address found in the dns packet. The blocking version
* reports this as an error.
*/
- if (as->as_type == ASR_GETNETBYNAME &&
- ar->ar_netent->n_net == 0) {
+ if (as->as_type == ASR_GETNETBYNAME && n->n.n_net == 0) {
/* XXX wrong */
- free(ar->ar_netent);
+ free(n);
async_set_state(as, ASR_STATE_NEXT_DB);
- } else {
- ar->ar_h_errno = NETDB_SUCCESS;
- async_set_state(as, ASR_STATE_HALT);
+ break;
}
+
+ ar->ar_netent = &n->n;
+ ar->ar_h_errno = NETDB_SUCCESS;
+ async_set_state(as, ASR_STATE_HALT);
break;
case ASR_STATE_NOT_FOUND:
@@ -267,13 +272,13 @@ getnetnamadr_async_run(struct async *as, struct async_res *ar)
goto next;
}
-static struct netent *
+static struct netent_ext *
netent_file_match(FILE *f, int reqtype, const char *data)
{
- struct netent *e;
- char *tokens[MAXTOKEN];
- int n, i;
- in_addr_t net;
+ struct netent_ext *e;
+ char *tokens[MAXTOKEN];
+ int n, i;
+ in_addr_t net;
for (;;) {
n = asr_parse_namedb_line(f, tokens, MAXTOKEN);
@@ -305,21 +310,21 @@ found:
for (i = 2; i < n; i ++)
if (netent_add_alias(e, tokens[i], 0) == -1)
goto fail;
- e->n_net = inet_network(tokens[1]);
+ e->n.n_net = inet_network(tokens[1]);
return (e);
fail:
free(e);
return (NULL);
}
-static struct netent *
+static struct netent_ext *
netent_from_packet(int reqtype, char *pkt, size_t pktlen)
{
- struct netent *n;
- struct unpack p;
- struct header hdr;
- struct query q;
- struct rr rr;
+ struct netent_ext *n;
+ struct unpack p;
+ struct header hdr;
+ struct query q;
+ struct rr rr;
if ((n = netent_alloc(AF_INET)) == NULL)
return (NULL);
@@ -352,11 +357,11 @@ netent_from_packet(int reqtype, char *pkt, size_t pktlen)
break;
case T_A:
- if (n->n_addrtype != AF_INET)
+ if (n->n.n_addrtype != AF_INET)
break;
if (netent_set_cname(n, rr.rr_dname, 1) == -1)
goto fail;
- n->n_net = ntohl(rr.rr.in_a.addr.s_addr);
+ n->n.n_net = ntohl(rr.rr.in_a.addr.s_addr);
break;
}
}
@@ -367,71 +372,74 @@ fail:
return (NULL);
}
-static struct netent *
+static struct netent_ext *
netent_alloc(int family)
{
- struct netent *n;
- size_t alloc;
+ struct netent_ext *n;
+ size_t alloc;
- alloc = sizeof(*n) + (2 + MAXALIASES) * sizeof(char*) + 1024;
+ alloc = sizeof(*n) + 1024;
if ((n = calloc(1, alloc)) == NULL)
return (NULL);
- n->n_addrtype = family;
- n->n_aliases = NETENT_PTR(n) + 2;
-
- NETENT_STOP(n) = (char*)(n) + alloc;
- NETENT_POS(n) = (char *)(n->n_aliases + MAXALIASES);
+ n->n.n_addrtype = family;
+ n->n.n_aliases = n->aliases;
+ n->pos = (char*)(n) + sizeof(*n);
+ n->end = n->pos + 1024;
return (n);
}
static int
-netent_set_cname(struct netent *n, const char *name, int isdname)
+netent_set_cname(struct netent_ext *n, const char *name, int isdname)
{
char buf[MAXDNAME];
+ size_t l;
- if (n->n_name)
- return (0);
+ if (n->n.n_name)
+ return (-1);
if (isdname) {
asr_strdname(name, buf, sizeof buf);
buf[strlen(buf) - 1] = '\0';
name = buf;
}
- if (strlen(name) + 1 >= NETENT_LEFT(n))
- return (1);
- strlcpy(NETENT_POS(n), name, NETENT_LEFT(n));
- n->n_name = NETENT_POS(n);
- NETENT_POS(n) += strlen(name) + 1;
+ l = strlen(name) + 1;
+ if (n->pos + l >= n->end)
+ return (-1);
+
+ n->n.n_name = n->pos;
+ memmove(n->pos, name, l);
+ n->pos += l;
return (0);
}
static int
-netent_add_alias(struct netent *n, const char *name, int isdname)
+netent_add_alias(struct netent_ext *n, const char *name, int isdname)
{
char buf[MAXDNAME];
- size_t i;
+ size_t i, l;
- for (i = 0; i < MAXALIASES - 1; i++)
- if (n->n_aliases[i] == NULL)
+ for (i = 0; i < MAXALIASES; i++)
+ if (n->aliases[i] == NULL)
break;
- if (i == MAXALIASES - 1)
- return (0);
+ if (i == MAXALIASES)
+ return (-1);
if (isdname) {
asr_strdname(name, buf, sizeof buf);
buf[strlen(buf)-1] = '\0';
name = buf;
}
- if (strlen(name) + 1 >= NETENT_LEFT(n))
- return (1);
- strlcpy(NETENT_POS(n), name, NETENT_LEFT(n));
- n->n_aliases[i] = NETENT_POS(n);
- NETENT_POS(n) += strlen(name) + 1;
+ l = strlen(name) + 1;
+ if (n->pos + l >= n->end)
+ return (-1);
+ n->aliases[i] = n->pos;
+ memmove(n->pos, name, l);
+ n->pos += l;
return (0);
}