+static void remove_all_clients(exportnode *e)
+{
+ struct groupnode *g, *ng;
+
+ for (g = e->ex_groups; g; g = ng) {
+ ng = g->gr_next;
+ xfree(g->gr_name);
+ xfree(g);
+ }
+ e->ex_groups = NULL;
+}
+
+static void free_exportlist(exports *elist)
+{
+ struct exportnode *e, *ne;
+
+ for (e = *elist; e != NULL; e = ne) {
+ ne = e->ex_next;
+ remove_all_clients(e);
+ xfree(e->ex_dir);
+ xfree(e);
+ }
+ *elist = NULL;
+}
+
+static void prune_clients(nfs_export *exp, struct exportnode *e)
+{
+ struct addrinfo *ai = NULL;
+ struct groupnode *c, **cp;
+
+ cp = &e->ex_groups;
+ while ((c = *cp) != NULL) {
+ if (client_gettype(c->gr_name) == MCL_FQDN
+ && (ai = host_addrinfo(c->gr_name))) {
+ if (client_check(exp->m_client, ai)) {
+ *cp = c->gr_next;
+ xfree(c->gr_name);
+ xfree(c);
+ freeaddrinfo(ai);
+ continue;
+ }
+ freeaddrinfo(ai);
+ }
+ cp = &(c->gr_next);
+ }
+}
+
+static exportnode *lookup_or_create_elist_entry(exports *elist, nfs_export *exp)
+{
+ exportnode *e;
+
+ for (e = *elist; e != NULL; e = e->ex_next) {
+ if (!strcmp(exp->m_export.e_path, e->ex_dir))
+ return e;
+ }
+ e = xmalloc(sizeof(*e));
+ e->ex_next = *elist;
+ e->ex_groups = NULL;
+ e->ex_dir = xstrdup(exp->m_export.e_path);
+ *elist = e;
+ return e;
+}
+
+static void insert_group(struct exportnode *e, char *newname)
+{
+ struct groupnode *g;
+
+ for (g = e->ex_groups; g; g = g->gr_next)
+ if (!strcmp(g->gr_name, newname))
+ return;
+
+ g = xmalloc(sizeof(*g));
+ g->gr_name = xstrdup(newname);
+ g->gr_next = e->ex_groups;
+ e->ex_groups = g;
+}
+