#include <string.h>
#include <ctype.h>
#include <netdb.h>
-#include "xmalloc.h"
+
#include "misc.h"
#include "nfslib.h"
#include "exportfs.h"
#endif
static char *add_name(char *old, const char *add);
-static void client_init(nfs_client *clp, const char *hname,
- struct hostent *hp);
nfs_client *clientlist[MCL_MAXTYPES] = { NULL, };
static void
init_addrlist(nfs_client *clp, const struct hostent *hp)
{
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ };
char **ap;
int i;
return;
ap = hp->h_addr_list;
- for (i = 0; *ap != NULL && i < NFSCLNT_ADDRMAX; i++, ap++)
- clp->m_addrlist[i] = *(struct in_addr *)*ap;
-
+ for (i = 0; *ap != NULL && i < NFSCLNT_ADDRMAX; i++, ap++) {
+ sin.sin_addr = *(struct in_addr *)*ap;
+ set_addrlist_in(clp, i, &sin);
+ }
clp->m_naddr = i;
}
static void
client_free(nfs_client *clp)
{
- xfree(clp->m_hostname);
- xfree(clp);
+ free(clp->m_hostname);
+ free(clp);
+}
+
+static int
+init_netmask(nfs_client *clp, const char *slash)
+{
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ };
+
+ if (strchr(slash + 1, '.') != NULL)
+ sin.sin_addr.s_addr = inet_addr(slash + 1);
+ else {
+ int prefixlen = atoi(slash + 1);
+ if (0 < prefixlen && prefixlen <= 32)
+ sin.sin_addr.s_addr =
+ htonl((uint32_t)~0 << (32 - prefixlen));
+ else
+ goto out_badprefix;
+ }
+
+ set_addrlist_in(clp, 1, &sin);
+ return 1;
+
+out_badprefix:
+ xlog(L_ERROR, "Invalid prefix `%s' for %s", slash + 1, clp->m_hostname);
+ return 0;
+}
+
+static int
+init_subnetwork(nfs_client *clp)
+{
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ };
+ static char slash32[] = "/32";
+ char *cp;
+
+ cp = strchr(clp->m_hostname, '/');
+ if (cp == NULL)
+ cp = slash32;
+
+ *cp = '\0';
+ sin.sin_addr.s_addr = inet_addr(clp->m_hostname);
+ set_addrlist_in(clp, 0, &sin);
+ *cp = '/';
+
+ return init_netmask(clp, cp);
+}
+
+static int
+client_init(nfs_client *clp, const char *hname, const struct hostent *hp)
+{
+ clp->m_hostname = strdup(hname);
+ if (clp->m_hostname == NULL)
+ return 0;
+
+ clp->m_exported = 0;
+ clp->m_count = 0;
+ clp->m_naddr = 0;
+
+ if (clp->m_type == MCL_SUBNETWORK)
+ return init_subnetwork(clp);
+
+ init_addrlist(clp, hp);
+ return 1;
+}
+
+static void
+client_add(nfs_client *clp)
+{
+ nfs_client **cpp;
+
+ cpp = &clientlist[clp->m_type];
+ while (*cpp != NULL)
+ cpp = &((*cpp)->m_next);
+ clp->m_next = NULL;
+ *cpp = clp;
}
/* if canonical is set, then we *know* this is already a canonical name
}
}
- if (!clp) {
- clp = (nfs_client *) xmalloc(sizeof(*clp));
- memset(clp, 0, sizeof(*clp));
+ if (clp == NULL) {
+ clp = calloc(1, sizeof(*clp));
+ if (clp == NULL)
+ goto out;
clp->m_type = htype;
- client_init(clp, hname, NULL);
+ if (!client_init(clp, hname, NULL)) {
+ client_free(clp);
+ clp = NULL;
+ goto out;
+ }
client_add(clp);
}
if (htype == MCL_FQDN && clp->m_naddr == 0)
init_addrlist(clp, hp);
+out:
if (hp)
free (hp);
{
nfs_client *new;
- new = (nfs_client *) xmalloc(sizeof(*new));
+ new = (nfs_client *)malloc(sizeof(*new));
+ if (new == NULL)
+ return NULL;
memcpy(new, clp, sizeof(*new));
new->m_type = MCL_FQDN;
new->m_hostname = NULL;
- client_init(new, (char *) hp->h_name, hp);
+ if (!client_init(new, hp->h_name, hp)) {
+ client_free(new);
+ return NULL;
+ }
client_add(new);
return new;
}
-static void
-client_init(nfs_client *clp, const char *hname, struct hostent *hp)
-{
- xfree(clp->m_hostname);
- if (hp)
- clp->m_hostname = xstrdup(hp->h_name);
- else
- clp->m_hostname = xstrdup(hname);
-
- clp->m_exported = 0;
- clp->m_count = 0;
- clp->m_naddr = 0;
-
- if (clp->m_type == MCL_SUBNETWORK) {
- char *cp = strchr(clp->m_hostname, '/');
- static char slash32[] = "/32";
-
- if(!cp) cp = slash32;
- *cp = '\0';
- clp->m_addrlist[0].s_addr = inet_addr(clp->m_hostname);
- if (strchr(cp + 1, '.')) {
- clp->m_addrlist[1].s_addr = inet_addr(cp+1);
- }
- else {
- int netmask = atoi(cp + 1);
- if (0 < netmask && netmask <= 32) {
- clp->m_addrlist[1].s_addr =
- htonl ((uint32_t) ~0 << (32 - netmask));
- }
- else {
- xlog(L_FATAL, "invalid netmask `%s' for %s",
- cp + 1, clp->m_hostname);
- }
- }
- *cp = '/';
- return;
- }
-
- init_addrlist(clp, hp);
-}
-
-void
-client_add(nfs_client *clp)
-{
- nfs_client **cpp;
-
- if (clp->m_type < 0 || clp->m_type >= MCL_MAXTYPES)
- xlog(L_FATAL, "unknown client type in client_add");
- cpp = clientlist + clp->m_type;
- while (*cpp)
- cpp = &((*cpp)->m_next);
- clp->m_next = NULL;
- *cpp = clp;
-}
-
void
client_release(nfs_client *clp)
{
static int
check_fqdn(const nfs_client *clp, const struct hostent *hp)
{
+ const struct sockaddr_in *sin;
struct in_addr addr;
char **ap;
int i;
for (ap = hp->h_addr_list; *ap; ap++) {
addr = *(struct in_addr *)*ap;
- for (i = 0; i < clp->m_naddr; i++)
- if (clp->m_addrlist[i].s_addr == addr.s_addr)
+ for (i = 0; i < clp->m_naddr; i++) {
+ sin = get_addrlist_in(clp, i);
+ if (sin->sin_addr.s_addr == addr.s_addr)
return 1;
+ }
}
return 0;
}
static int
check_subnetwork(const nfs_client *clp, const struct hostent *hp)
{
+ const struct sockaddr_in *address, *mask;
struct in_addr addr;
char **ap;
for (ap = hp->h_addr_list; *ap; ap++) {
+ address = get_addrlist_in(clp, 0);
+ mask = get_addrlist_in(clp, 1);
addr = *(struct in_addr *)*ap;
- if (!((clp->m_addrlist[0].s_addr ^ addr.s_addr) &
- clp->m_addrlist[1].s_addr))
+ if (!((address->sin_addr.s_addr ^ addr.s_addr) &
+ mask->sin_addr.s_addr))
return 1;
}
return 0;