autofs-5.1.7 - add xdr_exports() From: Ian Kent Add an xdr_exports() function to get NFS exports from a server. Signed-off-by: Ian Kent --- CHANGELOG | 3 + include/rpc_subs.h | 14 ++++++ lib/rpc_subs.c | 120 +++++++++++++++++++++++++++++++++++------------- modules/lookup_hosts.c | 25 +++------- 4 files changed, 112 insertions(+), 50 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 2c48484b..84050e91 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ + +- add xdr_exports(). + 25/01/2021 autofs-5.1.7 - make bind mounts propagation slave by default. - update ldap READMEs and schema definitions. diff --git a/include/rpc_subs.h b/include/rpc_subs.h index 7ba4b93f..080f19d9 100644 --- a/include/rpc_subs.h +++ b/include/rpc_subs.h @@ -17,6 +17,7 @@ #define _RPC_SUBS_H #include +#include #include #include #include @@ -47,6 +48,17 @@ #define HOST_ENT_BUF_SIZE 2048 +struct hostinfo { + char *name; + struct hostinfo *next; +}; + +struct exportinfo { + char *dir; + struct hostinfo *hosts; + struct exportinfo *next; +}; + struct conn_info { const char *host; struct sockaddr *addr; @@ -71,6 +83,8 @@ int rpc_portmap_getport(struct conn_info *, struct pmap *, unsigned short *); int rpc_ping_proto(struct conn_info *); int rpc_ping(const char *, int, unsigned int, long, long, unsigned int); double monotonic_elapsed(struct timespec, struct timespec); +struct exportinfo *rpc_get_exports(const char *host, long seconds, long micros, unsigned int option); +void rpc_exports_free(struct exportinfo *exports); const char *get_addr_string(struct sockaddr *, char *, socklen_t); #endif diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c index 643b7687..7b8162b4 100644 --- a/lib/rpc_subs.c +++ b/lib/rpc_subs.c @@ -41,7 +41,6 @@ const rpcprog_t rpcb_prog = PMAPPROG; const rpcvers_t rpcb_version = PMAPVERS; #endif -#include "mount.h" #include "rpc_subs.h" #include "replicated.h" #include "automount.h" @@ -58,6 +57,17 @@ const rpcvers_t rpcb_version = PMAPVERS; #define MAX_NETWORK_LEN 255 +#define EXPPATHLEN 1024 +#define EXPNAMELEN 255 + +#define MOUNTPROG 100005 + +#define MOUNTVERS 1 +#define MOUNTVERS_NFSV3 3 +#define MOUNTVERS_POSIX 2 + +#define MOUNTPROC_EXPORT 5 + /* Get numeric value of the n bits starting at position p */ #define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n)) @@ -1102,7 +1112,55 @@ double monotonic_elapsed(struct timespec start, struct timespec end) return t2 - t1; } -static int rpc_get_exports_proto(struct conn_info *info, exports *exp) +static bool_t xdr_host(XDR *xdrs, struct hostinfo *host) +{ + if (!xdr_string(xdrs, &host->name, EXPNAMELEN)) + return FALSE; + return TRUE; +} + +static bool_t xdr_hosts(XDR *xdrs, struct hostinfo **hosts) +{ + unsigned int size = sizeof(struct hostinfo); + char **host; + + host = (char **) hosts; + while (1) { + if (!xdr_pointer(xdrs, host, size, (xdrproc_t) xdr_host)) + return FALSE; + if (!*host) + break; + host = (char **) &((struct hostinfo *) *host)->next; + } + return TRUE; +} + +static bool_t xdr_export(XDR *xdrs, struct exportinfo *export) +{ + if (!xdr_string(xdrs, &export->dir, EXPPATHLEN)) + return FALSE; + if (!xdr_hosts(xdrs, &export->hosts)) + return FALSE; + return TRUE; +} + +bool_t xdr_exports(XDR *xdrs, struct exportinfo **exports) +{ + unsigned int size = sizeof(struct exportinfo); + char **export; + + export = (char **) exports; + while (1) { + if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export)) + return FALSE; + if (!*export) + break; + export = (char **) &((struct exportinfo *) *export)->next; + } + return TRUE; +} + +static int rpc_get_exports_proto(struct conn_info *info, struct exportinfo **exports) { CLIENT *client; enum clnt_stat status; @@ -1133,7 +1191,7 @@ static int rpc_get_exports_proto(struct conn_info *info, exports *exp) while (1) { status = clnt_call(client, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void, NULL, - (xdrproc_t) xdr_exports, (caddr_t) exp, + (xdrproc_t) xdr_exports, (caddr_t) exports, info->timeout); if (status == RPC_SUCCESS) break; @@ -1168,41 +1226,43 @@ static int rpc_get_exports_proto(struct conn_info *info, exports *exp) return 1; } -static void rpc_export_free(exports item) +static void rpc_export_free(struct exportinfo *export) { - groups grp; - groups tmp; - - if (item->ex_dir) - free(item->ex_dir); - - grp = item->ex_groups; - while (grp) { - if (grp->gr_name) - free(grp->gr_name); - tmp = grp; - grp = grp->gr_next; + struct hostinfo *host, *tmp; + + if (export->dir) + free(export->dir); + + host = export->hosts; + while (host) { + if (host->name) + free(host->name); + tmp = host; + host = host->next; free(tmp); } - free(item); + free(export); } -void rpc_exports_free(exports list) +void rpc_exports_free(struct exportinfo *exports) { - exports tmp; + struct exportinfo *export, *tmp; - while (list) { - tmp = list; - list = list->ex_next; + export = exports; + while (export) { + tmp = export; + export = export->next; rpc_export_free(tmp); } return; } -exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option) +struct exportinfo *rpc_get_exports(const char *host, + long seconds, long micros, + unsigned int option) { struct conn_info info; - exports exportlist; + struct exportinfo *exports = NULL; struct pmap parms; int status; @@ -1231,11 +1291,9 @@ exports rpc_get_exports(const char *host, long seconds, long micros, unsigned in if (status < 0) goto try_tcp; - memset(&exportlist, '\0', sizeof(exportlist)); - - status = rpc_get_exports_proto(&info, &exportlist); + status = rpc_get_exports_proto(&info, &exports); if (status) - return exportlist; + return exports; try_tcp: info.proto = IPPROTO_TCP; @@ -1246,13 +1304,11 @@ try_tcp: if (status < 0) return NULL; - memset(&exportlist, '\0', sizeof(exportlist)); - - status = rpc_get_exports_proto(&info, &exportlist); + status = rpc_get_exports_proto(&info, &exports); if (!status) return NULL; - return exportlist; + return exports; } const char *get_addr_string(struct sockaddr *sa, char *name, socklen_t len) diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c index 744062e2..81a4eb18 100644 --- a/modules/lookup_hosts.c +++ b/modules/lookup_hosts.c @@ -20,14 +20,6 @@ #include #include -/* - * Avoid annoying compiler noise by using an alternate name for - * typedef name in mount.h - */ -#define name __dummy_type_name -#include "mount.h" -#undef name - #define MODULE_LOOKUP #include "automount.h" #include "nsswitch.h" @@ -43,9 +35,6 @@ struct lookup_context { int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ -exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option); -void rpc_exports_free(exports list); - int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) { @@ -99,7 +88,7 @@ static char *get_exports(struct autofs_point *ap, const char *host) { char buf[MAX_ERR_BUF]; char *mapent; - exports exp, this; + struct exportinfo *exp, *this; debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); @@ -111,7 +100,7 @@ static char *get_exports(struct autofs_point *ap, const char *host) if (mapent) { int len = strlen(mapent) + 1; - len += strlen(host) + 2*(strlen(this->ex_dir) + 2) + 3; + len += strlen(host) + 2*(strlen(this->dir) + 2) + 3; mapent = realloc(mapent, len); if (!mapent) { char *estr; @@ -121,10 +110,10 @@ static char *get_exports(struct autofs_point *ap, const char *host) return NULL; } strcat(mapent, " \""); - strcat(mapent, this->ex_dir); + strcat(mapent, this->dir); strcat(mapent, "\""); } else { - int len = 2*(strlen(this->ex_dir) + 2) + strlen(host) + 3; + int len = 2*(strlen(this->dir) + 2) + strlen(host) + 3; mapent = malloc(len); if (!mapent) { @@ -135,16 +124,16 @@ static char *get_exports(struct autofs_point *ap, const char *host) return NULL; } strcpy(mapent, "\""); - strcat(mapent, this->ex_dir); + strcat(mapent, this->dir); strcat(mapent, "\""); } strcat(mapent, " \""); strcat(mapent, host); strcat(mapent, ":"); - strcat(mapent, this->ex_dir); + strcat(mapent, this->dir); strcat(mapent, "\""); - this = this->ex_next; + this = this->next; } rpc_exports_free(exp);