* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
*/
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <string.h>
#include <sys/types.h>
#include "nfslib.h"
#include "exportfs.h"
-nfs_export *exportlist[MCL_MAXTYPES] = { NULL, };
+exp_hash_table exportlist[MCL_MAXTYPES] = {{NULL, {{NULL,NULL}, }}, };
+static int export_hash(char *);
static void export_init(nfs_export *exp, nfs_client *clp,
struct exportent *nep);
nfs_export *exp;
setexportent(fname, "r");
- while ((eep = getexportent()) != NULL) {
- exp = export_lookup(eep->e_hostname, eep->e_path);
+ while ((eep = getexportent(0,1)) != NULL) {
+ exp = export_lookup(eep->e_hostname, eep->e_path, 0);
if (!exp)
- export_create(eep);
+ export_create(eep,0);
else {
if (exp->m_export.e_flags != eep->e_flags) {
xlog(L_ERROR, "incompatible duplicated export entries:");
* Create an in-core export struct from an export entry.
*/
nfs_export *
-export_create(struct exportent *xep)
+export_create(struct exportent *xep, int canonical)
{
nfs_client *clp;
nfs_export *exp;
- if (!(clp = client_lookup(xep->e_hostname))) {
+ if (!(clp = client_lookup(xep->e_hostname, canonical))) {
/* bad export entry; complaint already logged */
return NULL;
}
struct exportent *e = &exp->m_export;
dupexportent(e, nep);
+ if (nep->e_hostname)
+ e->e_hostname = xstrdup(nep->e_hostname);
exp->m_exported = 0;
exp->m_xtabent = 0;
exp->m_mayexport = 0;
exp->m_changed = 0;
+ exp->m_warned = 0;
exp->m_client = clp;
clp->m_count++;
}
new = (nfs_export *) xmalloc(sizeof(*new));
memcpy(new, exp, sizeof(*new));
dupexportent(&new->m_export, &exp->m_export);
+ if (exp->m_export.e_hostname)
+ new->m_export.e_hostname = xstrdup(exp->m_export.e_hostname);
clp = client_dup(exp->m_client, hp);
clp->m_count++;
new->m_client = clp;
new->m_exported = 0;
new->m_xtabent = 0;
new->m_changed = 0;
+ new->m_warned = 0;
export_add(new);
return new;
}
-
-void
+/*
+ * Add export entry to hash table
+ */
+void
export_add(nfs_export *exp)
{
- nfs_export **epp;
- int type = exp->m_client->m_type;
- int slen = strlen(exp->m_export.e_path);
-
- if (type < 0 || type >= MCL_MAXTYPES)
- xlog(L_FATAL, "unknown client type in export_add");
-
- epp = exportlist + type;
- while (*epp && slen < strlen((*epp)->m_export.e_path))
- epp = &((*epp)->m_next);
- exp->m_next = *epp;
- *epp = exp;
+ exp_hash_table *p_tbl;
+ exp_hash_entry *p_hen;
+ nfs_export *p_next;
+
+ int type = exp->m_client->m_type;
+ int pos;
+
+ pos = export_hash(exp->m_export.e_path);
+ p_tbl = &(exportlist[type]); /* pointer to hash table */
+ p_hen = &(p_tbl->entries[pos]); /* pointer to hash table entry */
+
+ if (!(p_hen->p_first)) { /* hash table entry is empty */
+ p_hen->p_first = exp;
+ p_hen->p_last = exp;
+
+ exp->m_next = p_tbl->p_head;
+ p_tbl->p_head = exp;
+ } else { /* hash table entry is NOT empty */
+ p_next = p_hen->p_last->m_next;
+ p_hen->p_last->m_next = exp;
+ exp->m_next = p_next;
+ p_hen->p_last = exp;
+ }
}
nfs_export *
int i;
for (i = 0; i < MCL_MAXTYPES; i++) {
- for (exp = exportlist[i]; exp; exp = exp->m_next) {
+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
if (!export_check(exp, hp, path))
continue;
if (exp->m_client->m_type == MCL_FQDN)
int i;
for (i = 0; i < MCL_MAXTYPES; i++) {
- for (exp = exportlist[i]; exp; exp = exp->m_next) {
+ for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
if (!exp->m_mayexport ||
!export_check(exp, hp, path))
continue;
return NULL;
}
-struct exportent *
+nfs_export *
export_allowed(struct hostent *hp, char *path)
{
- static struct exportent ee;
nfs_export *exp;
char epath[MAXPATHLEN+1];
char *p = NULL;
/* Try the longest matching exported pathname. */
while (1) {
exp = export_allowed_internal (hp, epath);
- if (exp) {
- dupexportent(&ee, &exp->m_export);
- return ⅇ
- }
+ if (exp)
+ return exp;
/* We have to treat the root, "/", specially. */
if (p == &epath[1]) break;
p = strrchr(epath, '/');
return NULL;
}
+/*
+ * Search hash table for export entry.
+ */
nfs_export *
-export_lookup(char *hname, char *path)
+export_lookup(char *hname, char *path, int canonical)
{
- nfs_client *clp;
- nfs_export *exp;
+ nfs_client *clp;
+ nfs_export *exp;
+ exp_hash_entry *p_hen;
- if (!(clp = client_lookup(hname)))
+ int pos;
+
+ clp = client_lookup(hname, canonical);
+ if(clp == NULL)
return NULL;
- for (exp = exportlist[clp->m_type]; exp; exp = exp->m_next)
- if (exp->m_client == clp && !strcmp(exp->m_export.e_path, path))
- return exp;
+
+ pos = export_hash(path);
+ p_hen = &(exportlist[clp->m_type].entries[pos]);
+ for(exp = p_hen->p_first; exp && (exp != p_hen->p_last->m_next);
+ exp = exp->m_next) {
+ if (exp->m_client == clp && !strcmp(exp->m_export.e_path, path)) {
+ return exp;
+ }
+ }
return NULL;
}
export_freeall(void)
{
nfs_export *exp, *nxt;
- int i;
+ int i, j;
for (i = 0; i < MCL_MAXTYPES; i++) {
- for (exp = exportlist[i]; exp; exp = nxt) {
+ for (exp = exportlist[i].p_head; exp; exp = nxt) {
nxt = exp->m_next;
client_release(exp->m_client);
if (exp->m_export.e_squids)
xfree(exp->m_export.e_squids);
if (exp->m_export.e_sqgids)
xfree(exp->m_export.e_sqgids);
+ if (exp->m_export.e_mountpoint)
+ free(exp->m_export.e_mountpoint);
+ if (exp->m_export.e_fslocdata)
+ xfree(exp->m_export.e_fslocdata);
+ xfree(exp->m_export.e_hostname);
xfree(exp);
}
- exportlist[i] = NULL;
+ for(j = 0; j < HASH_TABLE_SIZE; j++) {
+ exportlist[i].entries[j].p_first = NULL;
+ exportlist[i].entries[j].p_last = NULL;
+ }
+ exportlist[i].p_head = NULL;
}
client_freeall();
}
-void
-export_reset(nfs_export *exp)
+/*
+ * Compute and returns integer from string.
+ * Note: Its understood the smae integers can be same for
+ * different strings, but it should not matter.
+ */
+static unsigned int
+strtoint(char *str)
+{
+ int i = 0;
+ unsigned int n = 0;
+
+ while ( str[i] != '\0') {
+ n+=((int)str[i])*i;
+ i++;
+ }
+ return n;
+}
+
+/*
+ * Hash function
+ */
+static int
+export_hash(char *str)
{
- if (!exp)
- return;
+ int num = strtoint(str);
- /* Restore m_path. */
- strncpy(exp->m_export.m_path, exp->m_export.e_path,
- sizeof (exp->m_export.m_path) - 1);
- exp->m_export.m_path[sizeof (exp->m_export.m_path) - 1] = '\0';
+ return num % HASH_TABLE_SIZE;
}