2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow/*
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * CDDL HEADER START
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * The contents of this file are subject to the terms of the
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Common Development and Distribution License (the "License").
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * You may not use this file except in compliance with the License.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * or http://www.opensolaris.org/os/licensing.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * See the License for the specific language governing permissions
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * and limitations under the License.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * When distributing Covered Code, include this CDDL HEADER in each
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * If applicable, add the following below this CDDL HEADER, with the
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * fields enclosed by brackets "[]" replaced with your own identifying
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * information: Portions Copyright [yyyy] [name of copyright owner]
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * CDDL HEADER END
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow/*
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Use is subject to license terms.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <stdio.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <unistd.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <strings.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <string.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <sys/types.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <sys/stat.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <sys/errno.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <limits.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <libnvpair.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <dlfcn.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <link.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <rp_plugin.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <fcntl.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <uuid/uuid.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <rpc/types.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <rpc/xdr.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <rpc/auth.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <rpc/clnt.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <rpc/rpc_msg.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <sys/param.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <nfs/nfs4.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include <rpcsvc/nfs4_prot.h>
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#include "ref_subr.h"
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowextern int errno;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#define SERVICE_TYPE "nfs-basic"
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowchar *nfs_basic_service_type(void);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowboolean_t nfs_basic_supports_svc(const char *);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowint nfs_basic_deref(const char *, const char *, char *, size_t *);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowint nfs_basic_form(const char *, const char *, char *, size_t *);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowstruct rp_plugin_ops rp_plugin_ops = {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow RP_PLUGIN_V1,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow NULL, /* rpo_init */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow NULL, /* rpo_fini */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow nfs_basic_service_type,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow nfs_basic_supports_svc,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow nfs_basic_form,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow nfs_basic_deref
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow};
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow/*
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * What service type does this module support?
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowchar *
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlownfs_basic_service_type()
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow{
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (SERVICE_TYPE);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow}
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow/*
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Does this module support a particular service type?
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowboolean_t
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlownfs_basic_supports_svc(const char *svc_type)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow{
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (!svc_type)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (0);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (!strncasecmp(svc_type, SERVICE_TYPE, strlen(SERVICE_TYPE)));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow}
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow/*
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Take a string with a set of locations like this:
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * host1:/path1 host2:/path2 host3:/path3
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * and convert it to an fs_locations4 for the deref routine.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowstatic fs_locations4 *
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowget_fs_locations(char *buf)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow{
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fs_locations4 *result = NULL;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fs_location4 *fsl_array;
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow int i, gothost;
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow int fsl_count = 0, escape = 0, delimiter = 0;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow int len;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow char *p, *sp, *dp, buf2[SYMLINK_MAX];
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (buf == NULL)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (NULL);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#ifdef DEBUG
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow printf("get_fs_locations: input %s\n", buf);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#endif
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /*
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Count fs_location entries by counting spaces.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Remember that escaped spaces ("\ ") may exist.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * We mark the location boundaries with null bytes.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Variable use:
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * escape - set if we have found a backspace,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * part of either "\ " or "\\"
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * delimiter - set if we have found a space and
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * used to skip multiple spaces
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow for (sp = buf; sp && *sp; sp++) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (*sp == '\\') {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow escape = 1;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow delimiter = 0;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow continue;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (*sp == ' ') {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (delimiter == 1)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow continue;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (escape == 0) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow delimiter = 1;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fsl_count++;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *sp = '\0';
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow } else
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow escape = 0;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow } else
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow delimiter = 0;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow len = sp - buf;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow sp--;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (escape == 0 && *sp != '\0')
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fsl_count++;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#ifdef DEBUG
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow printf("get_fs_locations: fsl_count %d\n", fsl_count);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#endif
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (fsl_count == 0)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow goto out;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Alloc space for everything */
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow result = calloc(1, sizeof (fs_locations4));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (result == NULL)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow goto out;
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow fsl_array = calloc(fsl_count, sizeof (fs_location4));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (fsl_array == NULL) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow free(result);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow result = NULL;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow goto out;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow result->locations.locations_len = fsl_count;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow result->locations.locations_val = fsl_array;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow result->fs_root.pathname4_len = 0;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow result->fs_root.pathname4_val = NULL;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /*
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Copy input, removing escapes from host:/path/to/my\ files
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow sp = buf;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow dp = buf2;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow bzero(buf2, sizeof (buf2));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow i = gothost = 0;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow while ((sp && *sp && (sp - buf < len)) || gothost) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (!gothost) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Drop leading spaces */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (*sp == ' ') {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow sp++;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow continue;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Look for the rightmost colon for host */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow p = strrchr(sp, ':');
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (!p) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#ifdef DEBUG
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow printf("get_fs_locations: skipping %s\n", sp);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#endif
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow fsl_count--;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow sp += strlen(sp) + 1;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow } else {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow bcopy(sp, dp, p - sp);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow sp = p + 1;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#ifdef DEBUG
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow printf("get_fs_locations: host %s\n", buf2);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#endif
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fsl_array[i].server.server_len = 1;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fsl_array[i].server.server_val =
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow malloc(sizeof (utf8string));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (fsl_array[i].server.server_val == NULL) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow int j;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow free(result);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow result = NULL;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow for (j = 0; j < i; j++)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow free(fsl_array[j].
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow server.server_val);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow free(fsl_array);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow goto out;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow str_to_utf8(buf2,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fsl_array[i].server.server_val);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow gothost = 1;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow dp = buf2;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow bzero(buf2, sizeof (buf2));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow continue;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* End of string should mean a pathname */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (*sp == '\0' && gothost) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#ifdef DEBUG
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow printf("get_fs_locations: path %s\n", buf2);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#endif
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow (void) make_pathname4(buf2, &fsl_array[i].rootpath);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow i++;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow gothost = 0;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow dp = buf2;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow bzero(buf2, sizeof (buf2));
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (sp - buf < len)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow sp++;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow continue;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Skip a single escape character */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (*sp == '\\')
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow sp++;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow /* Plain char, just copy it */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *dp++ = *sp++;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow /*
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow * If we're still expecting a path name, we don't have a
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow * server:/path pair and should discard the server and
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow * note that we got fewer locations than expected.
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow */
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow if (gothost) {
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow fsl_count--;
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow free(fsl_array[i].server.server_val);
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow fsl_array[i].server.server_val = NULL;
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow fsl_array[i].server.server_len = 0;
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow }
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow /*
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow * If we have zero entries, we never got a whole server:/path
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow * pair, and so cannot have anything else allocated.
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow */
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow if (fsl_count <= 0) {
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow free(result);
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow free(fsl_array);
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow return (NULL);
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow }
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow /*
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow * Make sure we reflect the right number of locations.
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow */
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow if (fsl_count < result->locations.locations_len)
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow result->locations.locations_len = fsl_count;
2457156514cfa0601bd17503b32b85ace84513a8Robert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowout:
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (result);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow}
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow/*
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Deref function for nfs-basic service type returns an fs_locations4.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowint
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlownfs_basic_deref(const char *svc_type, const char *svc_data, char *buf,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow size_t *bufsz)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow{
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow int slen, err;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fs_locations4 *fsl;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow XDR xdr;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if ((!svc_type) || (!svc_data) || (!buf) || (!bufsz) || (*bufsz == 0))
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (EINVAL);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (strcasecmp(svc_type, SERVICE_TYPE))
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (ENOTSUP);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow fsl = get_fs_locations((char *)svc_data);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (fsl == NULL)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (ENOENT);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#ifdef DEBUG
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow printf("nfs_basic_deref: past get_fs_locations()\n");
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#endif
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow slen = xdr_sizeof(xdr_fs_locations4, (void *)fsl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (slen > *bufsz) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *bufsz = slen;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow xdr_free(xdr_fs_locations4, (char *)fsl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (EOVERFLOW);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#ifdef DEBUG
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow printf("nfs_basic_deref: past buffer check\n");
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow print_referral_summary(fsl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#endif
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow xdrmem_create(&xdr, buf, *bufsz, XDR_ENCODE);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow err = xdr_fs_locations4(&xdr, fsl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow XDR_DESTROY(&xdr);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow xdr_free(xdr_fs_locations4, (char *)fsl);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (err != TRUE)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (EINVAL);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *bufsz = slen;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#ifdef DEBUG
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow printf("nfs_basic_deref: past xdr_fs_locations4() and done\n");
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow#endif
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (0);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow}
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow/*
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow * Form function for nfs-basic service type.
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow */
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlowint
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlownfs_basic_form(const char *svc_type, const char *svc_data, char *buf,
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow size_t *bufsz)
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow{
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow int slen;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if ((!svc_type) || (!svc_data) || (!buf) || (*bufsz == 0))
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (EINVAL);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (strcmp(svc_type, SERVICE_TYPE))
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (ENOTSUP);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow slen = strlen(svc_data) + 1;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow if (slen > *bufsz) {
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *bufsz = slen;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (EOVERFLOW);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow }
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow *bufsz = slen;
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow strncpy(buf, svc_data, slen);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow return (0);
2f172c55ef76964744bc62b4500ece87f3089b4dRobert Thurlow}