summaryrefslogtreecommitdiffstats
path: root/support
diff options
context:
space:
mode:
Diffstat (limited to 'support')
-rw-r--r--support/export/client.c98
-rw-r--r--support/include/exportfs.h2
-rw-r--r--support/include/nfslib.h4
-rw-r--r--support/nfs/cacheio.c16
4 files changed, 120 insertions, 0 deletions
diff --git a/support/export/client.c b/support/export/client.c
index 6d5d306..3db21ae 100644
--- a/support/export/client.c
+++ b/support/export/client.c
@@ -230,6 +230,104 @@ client_find(struct hostent *hp)
}
/*
+ * Find client name given an IP address
+ * This is found by gathering all known names that match that IP address,
+ * sorting them and joining them with '+'
+ *
+ */
+static char *add_name(char *old, char *add);
+
+char *
+client_compose(struct in_addr addr)
+{
+ struct hostent *he = NULL;
+ char *name = NULL;
+ int i;
+
+ if (clientlist[MCL_WILDCARD] || clientlist[MCL_NETGROUP])
+ he = get_reliable_hostbyaddr((const char*)&addr, sizeof(addr), AF_INET);
+ if (he == NULL)
+ he = get_hostent((const char*)&addr, sizeof(addr), AF_INET);
+
+ for (i = 0 ; i < MCL_MAXTYPES; i++) {
+ nfs_client *clp;
+ for (clp = clientlist[i]; clp ; clp = clp->m_next) {
+ if (!client_check(clp, he))
+ continue;
+ name = add_name(name, clp->m_hostname);
+ }
+ }
+ return name;
+}
+
+int
+client_member(char *client, char *name)
+{
+ /* check if "client" (a ',' separated list of names)
+ * contains 'name' as a member
+ */
+ int l = strlen(name);
+ while (*client) {
+ if (strncmp(client, name, l) == 0 &&
+ (client[l] == ',' || client[l] == '\0'))
+ return 1;
+ client = strchr(client, ',');
+ if (client == NULL)
+ return 0;
+ client++;
+ }
+ return 0;
+}
+
+
+int
+name_cmp(char *a, char *b)
+{
+ /* compare strings a and b, but only upto ',' in a */
+ while (*a && *b && *a != ',' && *a == *b)
+ a++, b++;
+ if (!*b && (!*a || !a == ',') )
+ return 0;
+ if (!*b) return 1;
+ if (!*a || *a == ',') return -1;
+ return *a - *b;
+}
+
+static char *
+add_name(char *old, char *add)
+{
+ int len = strlen(add)+2;
+ char *new;
+ char *cp;
+ if (old) len += strlen(old);
+
+ new = malloc(len);
+ if (!new) {
+ free(old);
+ return NULL;
+ }
+ cp = old;
+ while (cp && *cp && name_cmp(cp, add) < 0) {
+ /* step cp forward over a name */
+ char *e = strchr(cp, ',');
+ if (e)
+ cp = e+1;
+ else
+ cp = cp + strlen(cp);
+ }
+ strncpy(new, old, cp-old);
+ new[cp-old] = 0;
+ if (cp != old && !*cp)
+ strcat(new, ",");
+ strcat(new, add);
+ if (cp && *cp) {
+ strcat(new, ",");
+ strcat(new, cp);
+ }
+ return new;
+}
+
+/*
* Match a host (given its hostent record) to a client record. This
* is usually called from mountd.
*/
diff --git a/support/include/exportfs.h b/support/include/exportfs.h
index 4021e60..dfd51f2 100644
--- a/support/include/exportfs.h
+++ b/support/include/exportfs.h
@@ -54,6 +54,8 @@ int client_check(nfs_client *, struct hostent *);
int client_match(nfs_client *, char *hname);
void client_release(nfs_client *);
void client_freeall(void);
+char * client_compose(struct in_addr addr);
+int client_member(char *client, char *name);
int export_read(char *fname);
void export_add(nfs_export *);
diff --git a/support/include/nfslib.h b/support/include/nfslib.h
index 90bd33a..5112b91 100644
--- a/support/include/nfslib.h
+++ b/support/include/nfslib.h
@@ -126,6 +126,10 @@ void qword_print(FILE *f, char *str);
void qword_printhex(FILE *f, char *str, int slen);
void qword_printint(FILE *f, int num);
void qword_eol(FILE *f);
+int readline(int fd, char **buf, int *lenp);
+int qword_get(char **bpp, char *dest, int bufsize);
+int qword_get_int(char **bpp, int *anint);
+int check_new_cache(void);
/* lockd. */
int lockdsvc();
diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c
index 960d801..2af4fa3 100644
--- a/support/nfs/cacheio.c
+++ b/support/nfs/cacheio.c
@@ -19,6 +19,10 @@
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
void qword_add(char **bpp, int *lp, char *str)
{
@@ -214,3 +218,15 @@ int readline(int fd, char **buf, int *lenp)
return 1;
}
+
+/* Check if we should use the new caching interface
+ * This succeeds iff the "nfsd" filesystem is mounted on
+ * /proc/fs/nfs
+ */
+int
+check_new_cache(void)
+{
+ struct stat stb;
+ return (stat("/proc/fs/nfs/filehandle", &stb) == 0);
+}
+