diff options
Diffstat (limited to 'support')
-rw-r--r-- | support/export/client.c | 98 | ||||
-rw-r--r-- | support/include/exportfs.h | 2 | ||||
-rw-r--r-- | support/include/nfslib.h | 4 | ||||
-rw-r--r-- | support/nfs/cacheio.c | 16 |
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); +} + |