111291SRobert.Thurlow@Sun.COM /*
211291SRobert.Thurlow@Sun.COM * CDDL HEADER START
311291SRobert.Thurlow@Sun.COM *
411291SRobert.Thurlow@Sun.COM * The contents of this file are subject to the terms of the
511291SRobert.Thurlow@Sun.COM * Common Development and Distribution License (the "License").
611291SRobert.Thurlow@Sun.COM * You may not use this file except in compliance with the License.
711291SRobert.Thurlow@Sun.COM *
811291SRobert.Thurlow@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911291SRobert.Thurlow@Sun.COM * or http://www.opensolaris.org/os/licensing.
1011291SRobert.Thurlow@Sun.COM * See the License for the specific language governing permissions
1111291SRobert.Thurlow@Sun.COM * and limitations under the License.
1211291SRobert.Thurlow@Sun.COM *
1311291SRobert.Thurlow@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1411291SRobert.Thurlow@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511291SRobert.Thurlow@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1611291SRobert.Thurlow@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1711291SRobert.Thurlow@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1811291SRobert.Thurlow@Sun.COM *
1911291SRobert.Thurlow@Sun.COM * CDDL HEADER END
2011291SRobert.Thurlow@Sun.COM */
2111291SRobert.Thurlow@Sun.COM
2211291SRobert.Thurlow@Sun.COM /*
2311291SRobert.Thurlow@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2411291SRobert.Thurlow@Sun.COM * Use is subject to license terms.
2511291SRobert.Thurlow@Sun.COM */
2611291SRobert.Thurlow@Sun.COM
2711291SRobert.Thurlow@Sun.COM #include <stdio.h>
2811291SRobert.Thurlow@Sun.COM #include <unistd.h>
2911291SRobert.Thurlow@Sun.COM #include <strings.h>
3011291SRobert.Thurlow@Sun.COM #include <string.h>
3111291SRobert.Thurlow@Sun.COM #include <sys/types.h>
3211291SRobert.Thurlow@Sun.COM #include <sys/stat.h>
3311291SRobert.Thurlow@Sun.COM #include <sys/errno.h>
3411291SRobert.Thurlow@Sun.COM #include <limits.h>
3511291SRobert.Thurlow@Sun.COM #include <libnvpair.h>
3611291SRobert.Thurlow@Sun.COM #include <dlfcn.h>
3711291SRobert.Thurlow@Sun.COM #include <link.h>
3811291SRobert.Thurlow@Sun.COM #include <rp_plugin.h>
3911291SRobert.Thurlow@Sun.COM #include <fcntl.h>
4011291SRobert.Thurlow@Sun.COM #include <uuid/uuid.h>
4111291SRobert.Thurlow@Sun.COM #include <rpc/types.h>
4211291SRobert.Thurlow@Sun.COM #include <rpc/xdr.h>
4311291SRobert.Thurlow@Sun.COM #include <rpc/auth.h>
4411291SRobert.Thurlow@Sun.COM #include <rpc/clnt.h>
4511291SRobert.Thurlow@Sun.COM #include <rpc/rpc_msg.h>
4611291SRobert.Thurlow@Sun.COM #include <sys/param.h>
4711291SRobert.Thurlow@Sun.COM #include <nfs/nfs4.h>
4811291SRobert.Thurlow@Sun.COM #include <rpcsvc/nfs4_prot.h>
4911291SRobert.Thurlow@Sun.COM #include "ref_subr.h"
5011291SRobert.Thurlow@Sun.COM
5111291SRobert.Thurlow@Sun.COM extern int errno;
5211291SRobert.Thurlow@Sun.COM
5311291SRobert.Thurlow@Sun.COM #define SERVICE_TYPE "nfs-basic"
5411291SRobert.Thurlow@Sun.COM
5511291SRobert.Thurlow@Sun.COM char *nfs_basic_service_type(void);
5611291SRobert.Thurlow@Sun.COM boolean_t nfs_basic_supports_svc(const char *);
5711291SRobert.Thurlow@Sun.COM int nfs_basic_deref(const char *, const char *, char *, size_t *);
5811291SRobert.Thurlow@Sun.COM int nfs_basic_form(const char *, const char *, char *, size_t *);
5911291SRobert.Thurlow@Sun.COM
6011291SRobert.Thurlow@Sun.COM struct rp_plugin_ops rp_plugin_ops = {
6111291SRobert.Thurlow@Sun.COM RP_PLUGIN_V1,
6211291SRobert.Thurlow@Sun.COM NULL, /* rpo_init */
6311291SRobert.Thurlow@Sun.COM NULL, /* rpo_fini */
6411291SRobert.Thurlow@Sun.COM nfs_basic_service_type,
6511291SRobert.Thurlow@Sun.COM nfs_basic_supports_svc,
6611291SRobert.Thurlow@Sun.COM nfs_basic_form,
6711291SRobert.Thurlow@Sun.COM nfs_basic_deref
6811291SRobert.Thurlow@Sun.COM };
6911291SRobert.Thurlow@Sun.COM
7011291SRobert.Thurlow@Sun.COM /*
7111291SRobert.Thurlow@Sun.COM * What service type does this module support?
7211291SRobert.Thurlow@Sun.COM */
7311291SRobert.Thurlow@Sun.COM char *
nfs_basic_service_type()7411291SRobert.Thurlow@Sun.COM nfs_basic_service_type()
7511291SRobert.Thurlow@Sun.COM {
7611291SRobert.Thurlow@Sun.COM return (SERVICE_TYPE);
7711291SRobert.Thurlow@Sun.COM }
7811291SRobert.Thurlow@Sun.COM
7911291SRobert.Thurlow@Sun.COM /*
8011291SRobert.Thurlow@Sun.COM * Does this module support a particular service type?
8111291SRobert.Thurlow@Sun.COM */
8211291SRobert.Thurlow@Sun.COM boolean_t
nfs_basic_supports_svc(const char * svc_type)8311291SRobert.Thurlow@Sun.COM nfs_basic_supports_svc(const char *svc_type)
8411291SRobert.Thurlow@Sun.COM {
8511291SRobert.Thurlow@Sun.COM if (!svc_type)
8611291SRobert.Thurlow@Sun.COM return (0);
8711291SRobert.Thurlow@Sun.COM return (!strncasecmp(svc_type, SERVICE_TYPE, strlen(SERVICE_TYPE)));
8811291SRobert.Thurlow@Sun.COM }
8911291SRobert.Thurlow@Sun.COM
9011291SRobert.Thurlow@Sun.COM /*
9111291SRobert.Thurlow@Sun.COM * Take a string with a set of locations like this:
9211291SRobert.Thurlow@Sun.COM * host1:/path1 host2:/path2 host3:/path3
9311291SRobert.Thurlow@Sun.COM * and convert it to an fs_locations4 for the deref routine.
9411291SRobert.Thurlow@Sun.COM */
9511291SRobert.Thurlow@Sun.COM static fs_locations4 *
get_fs_locations(char * buf)9611291SRobert.Thurlow@Sun.COM get_fs_locations(char *buf)
9711291SRobert.Thurlow@Sun.COM {
9811291SRobert.Thurlow@Sun.COM fs_locations4 *result = NULL;
9911291SRobert.Thurlow@Sun.COM fs_location4 *fsl_array;
100*11340SRobert.Thurlow@Sun.COM int i, gothost;
101*11340SRobert.Thurlow@Sun.COM int fsl_count = 0, escape = 0, delimiter = 0;
10211291SRobert.Thurlow@Sun.COM int len;
10311291SRobert.Thurlow@Sun.COM char *p, *sp, *dp, buf2[SYMLINK_MAX];
10411291SRobert.Thurlow@Sun.COM
10511291SRobert.Thurlow@Sun.COM if (buf == NULL)
10611291SRobert.Thurlow@Sun.COM return (NULL);
10711291SRobert.Thurlow@Sun.COM #ifdef DEBUG
10811291SRobert.Thurlow@Sun.COM printf("get_fs_locations: input %s\n", buf);
10911291SRobert.Thurlow@Sun.COM #endif
11011291SRobert.Thurlow@Sun.COM /*
11111291SRobert.Thurlow@Sun.COM * Count fs_location entries by counting spaces.
11211291SRobert.Thurlow@Sun.COM * Remember that escaped spaces ("\ ") may exist.
11311291SRobert.Thurlow@Sun.COM * We mark the location boundaries with null bytes.
11411291SRobert.Thurlow@Sun.COM * Variable use:
11511291SRobert.Thurlow@Sun.COM * escape - set if we have found a backspace,
11611291SRobert.Thurlow@Sun.COM * part of either "\ " or "\\"
11711291SRobert.Thurlow@Sun.COM * delimiter - set if we have found a space and
11811291SRobert.Thurlow@Sun.COM * used to skip multiple spaces
11911291SRobert.Thurlow@Sun.COM */
12011291SRobert.Thurlow@Sun.COM for (sp = buf; sp && *sp; sp++) {
12111291SRobert.Thurlow@Sun.COM if (*sp == '\\') {
12211291SRobert.Thurlow@Sun.COM escape = 1;
12311291SRobert.Thurlow@Sun.COM delimiter = 0;
12411291SRobert.Thurlow@Sun.COM continue;
12511291SRobert.Thurlow@Sun.COM }
12611291SRobert.Thurlow@Sun.COM if (*sp == ' ') {
12711291SRobert.Thurlow@Sun.COM if (delimiter == 1)
12811291SRobert.Thurlow@Sun.COM continue;
12911291SRobert.Thurlow@Sun.COM if (escape == 0) {
13011291SRobert.Thurlow@Sun.COM delimiter = 1;
13111291SRobert.Thurlow@Sun.COM fsl_count++;
13211291SRobert.Thurlow@Sun.COM *sp = '\0';
13311291SRobert.Thurlow@Sun.COM } else
13411291SRobert.Thurlow@Sun.COM escape = 0;
13511291SRobert.Thurlow@Sun.COM } else
13611291SRobert.Thurlow@Sun.COM delimiter = 0;
13711291SRobert.Thurlow@Sun.COM }
13811291SRobert.Thurlow@Sun.COM len = sp - buf;
13911291SRobert.Thurlow@Sun.COM sp--;
14011291SRobert.Thurlow@Sun.COM if (escape == 0 && *sp != '\0')
14111291SRobert.Thurlow@Sun.COM fsl_count++;
14211291SRobert.Thurlow@Sun.COM #ifdef DEBUG
14311291SRobert.Thurlow@Sun.COM printf("get_fs_locations: fsl_count %d\n", fsl_count);
14411291SRobert.Thurlow@Sun.COM #endif
14511291SRobert.Thurlow@Sun.COM if (fsl_count == 0)
14611291SRobert.Thurlow@Sun.COM goto out;
14711291SRobert.Thurlow@Sun.COM
14811291SRobert.Thurlow@Sun.COM /* Alloc space for everything */
149*11340SRobert.Thurlow@Sun.COM result = calloc(1, sizeof (fs_locations4));
15011291SRobert.Thurlow@Sun.COM if (result == NULL)
15111291SRobert.Thurlow@Sun.COM goto out;
152*11340SRobert.Thurlow@Sun.COM fsl_array = calloc(fsl_count, sizeof (fs_location4));
15311291SRobert.Thurlow@Sun.COM if (fsl_array == NULL) {
15411291SRobert.Thurlow@Sun.COM free(result);
15511291SRobert.Thurlow@Sun.COM result = NULL;
15611291SRobert.Thurlow@Sun.COM goto out;
15711291SRobert.Thurlow@Sun.COM }
15811291SRobert.Thurlow@Sun.COM result->locations.locations_len = fsl_count;
15911291SRobert.Thurlow@Sun.COM result->locations.locations_val = fsl_array;
16011291SRobert.Thurlow@Sun.COM result->fs_root.pathname4_len = 0;
16111291SRobert.Thurlow@Sun.COM result->fs_root.pathname4_val = NULL;
16211291SRobert.Thurlow@Sun.COM
16311291SRobert.Thurlow@Sun.COM /*
16411291SRobert.Thurlow@Sun.COM * Copy input, removing escapes from host:/path/to/my\ files
16511291SRobert.Thurlow@Sun.COM */
16611291SRobert.Thurlow@Sun.COM sp = buf;
16711291SRobert.Thurlow@Sun.COM dp = buf2;
16811291SRobert.Thurlow@Sun.COM bzero(buf2, sizeof (buf2));
16911291SRobert.Thurlow@Sun.COM
170*11340SRobert.Thurlow@Sun.COM i = gothost = 0;
17111291SRobert.Thurlow@Sun.COM while ((sp && *sp && (sp - buf < len)) || gothost) {
17211291SRobert.Thurlow@Sun.COM
17311291SRobert.Thurlow@Sun.COM if (!gothost) {
17411291SRobert.Thurlow@Sun.COM /* Drop leading spaces */
17511291SRobert.Thurlow@Sun.COM if (*sp == ' ') {
17611291SRobert.Thurlow@Sun.COM sp++;
17711291SRobert.Thurlow@Sun.COM continue;
17811291SRobert.Thurlow@Sun.COM }
17911291SRobert.Thurlow@Sun.COM
18011291SRobert.Thurlow@Sun.COM /* Look for the rightmost colon for host */
18111291SRobert.Thurlow@Sun.COM p = strrchr(sp, ':');
18211291SRobert.Thurlow@Sun.COM if (!p) {
18311291SRobert.Thurlow@Sun.COM #ifdef DEBUG
18411291SRobert.Thurlow@Sun.COM printf("get_fs_locations: skipping %s\n", sp);
18511291SRobert.Thurlow@Sun.COM #endif
186*11340SRobert.Thurlow@Sun.COM fsl_count--;
18711291SRobert.Thurlow@Sun.COM sp += strlen(sp) + 1;
18811291SRobert.Thurlow@Sun.COM } else {
18911291SRobert.Thurlow@Sun.COM bcopy(sp, dp, p - sp);
19011291SRobert.Thurlow@Sun.COM sp = p + 1;
19111291SRobert.Thurlow@Sun.COM #ifdef DEBUG
19211291SRobert.Thurlow@Sun.COM printf("get_fs_locations: host %s\n", buf2);
19311291SRobert.Thurlow@Sun.COM #endif
19411291SRobert.Thurlow@Sun.COM fsl_array[i].server.server_len = 1;
19511291SRobert.Thurlow@Sun.COM fsl_array[i].server.server_val =
19611291SRobert.Thurlow@Sun.COM malloc(sizeof (utf8string));
19711291SRobert.Thurlow@Sun.COM if (fsl_array[i].server.server_val == NULL) {
19811291SRobert.Thurlow@Sun.COM int j;
19911291SRobert.Thurlow@Sun.COM
20011291SRobert.Thurlow@Sun.COM free(result);
20111291SRobert.Thurlow@Sun.COM result = NULL;
20211291SRobert.Thurlow@Sun.COM for (j = 0; j < i; j++)
20311291SRobert.Thurlow@Sun.COM free(fsl_array[j].
20411291SRobert.Thurlow@Sun.COM server.server_val);
20511291SRobert.Thurlow@Sun.COM free(fsl_array);
20611291SRobert.Thurlow@Sun.COM goto out;
20711291SRobert.Thurlow@Sun.COM }
20811291SRobert.Thurlow@Sun.COM str_to_utf8(buf2,
20911291SRobert.Thurlow@Sun.COM fsl_array[i].server.server_val);
21011291SRobert.Thurlow@Sun.COM gothost = 1;
21111291SRobert.Thurlow@Sun.COM dp = buf2;
21211291SRobert.Thurlow@Sun.COM bzero(buf2, sizeof (buf2));
21311291SRobert.Thurlow@Sun.COM }
21411291SRobert.Thurlow@Sun.COM continue;
21511291SRobert.Thurlow@Sun.COM }
21611291SRobert.Thurlow@Sun.COM
21711291SRobert.Thurlow@Sun.COM /* End of string should mean a pathname */
21811291SRobert.Thurlow@Sun.COM if (*sp == '\0' && gothost) {
21911291SRobert.Thurlow@Sun.COM #ifdef DEBUG
22011291SRobert.Thurlow@Sun.COM printf("get_fs_locations: path %s\n", buf2);
22111291SRobert.Thurlow@Sun.COM #endif
22211291SRobert.Thurlow@Sun.COM (void) make_pathname4(buf2, &fsl_array[i].rootpath);
22311291SRobert.Thurlow@Sun.COM i++;
22411291SRobert.Thurlow@Sun.COM gothost = 0;
22511291SRobert.Thurlow@Sun.COM dp = buf2;
22611291SRobert.Thurlow@Sun.COM bzero(buf2, sizeof (buf2));
22711291SRobert.Thurlow@Sun.COM if (sp - buf < len)
22811291SRobert.Thurlow@Sun.COM sp++;
22911291SRobert.Thurlow@Sun.COM continue;
23011291SRobert.Thurlow@Sun.COM }
23111291SRobert.Thurlow@Sun.COM
23211291SRobert.Thurlow@Sun.COM /* Skip a single escape character */
23311291SRobert.Thurlow@Sun.COM if (*sp == '\\')
23411291SRobert.Thurlow@Sun.COM sp++;
23511291SRobert.Thurlow@Sun.COM
23611291SRobert.Thurlow@Sun.COM /* Plain char, just copy it */
23711291SRobert.Thurlow@Sun.COM *dp++ = *sp++;
23811291SRobert.Thurlow@Sun.COM }
23911291SRobert.Thurlow@Sun.COM
240*11340SRobert.Thurlow@Sun.COM /*
241*11340SRobert.Thurlow@Sun.COM * If we're still expecting a path name, we don't have a
242*11340SRobert.Thurlow@Sun.COM * server:/path pair and should discard the server and
243*11340SRobert.Thurlow@Sun.COM * note that we got fewer locations than expected.
244*11340SRobert.Thurlow@Sun.COM */
245*11340SRobert.Thurlow@Sun.COM if (gothost) {
246*11340SRobert.Thurlow@Sun.COM fsl_count--;
247*11340SRobert.Thurlow@Sun.COM free(fsl_array[i].server.server_val);
248*11340SRobert.Thurlow@Sun.COM fsl_array[i].server.server_val = NULL;
249*11340SRobert.Thurlow@Sun.COM fsl_array[i].server.server_len = 0;
250*11340SRobert.Thurlow@Sun.COM }
251*11340SRobert.Thurlow@Sun.COM
252*11340SRobert.Thurlow@Sun.COM /*
253*11340SRobert.Thurlow@Sun.COM * If we have zero entries, we never got a whole server:/path
254*11340SRobert.Thurlow@Sun.COM * pair, and so cannot have anything else allocated.
255*11340SRobert.Thurlow@Sun.COM */
256*11340SRobert.Thurlow@Sun.COM if (fsl_count <= 0) {
257*11340SRobert.Thurlow@Sun.COM free(result);
258*11340SRobert.Thurlow@Sun.COM free(fsl_array);
259*11340SRobert.Thurlow@Sun.COM return (NULL);
260*11340SRobert.Thurlow@Sun.COM }
261*11340SRobert.Thurlow@Sun.COM
262*11340SRobert.Thurlow@Sun.COM /*
263*11340SRobert.Thurlow@Sun.COM * Make sure we reflect the right number of locations.
264*11340SRobert.Thurlow@Sun.COM */
265*11340SRobert.Thurlow@Sun.COM if (fsl_count < result->locations.locations_len)
266*11340SRobert.Thurlow@Sun.COM result->locations.locations_len = fsl_count;
267*11340SRobert.Thurlow@Sun.COM
26811291SRobert.Thurlow@Sun.COM out:
26911291SRobert.Thurlow@Sun.COM return (result);
27011291SRobert.Thurlow@Sun.COM }
27111291SRobert.Thurlow@Sun.COM
27211291SRobert.Thurlow@Sun.COM /*
27311291SRobert.Thurlow@Sun.COM * Deref function for nfs-basic service type returns an fs_locations4.
27411291SRobert.Thurlow@Sun.COM */
27511291SRobert.Thurlow@Sun.COM int
nfs_basic_deref(const char * svc_type,const char * svc_data,char * buf,size_t * bufsz)27611291SRobert.Thurlow@Sun.COM nfs_basic_deref(const char *svc_type, const char *svc_data, char *buf,
27711291SRobert.Thurlow@Sun.COM size_t *bufsz)
27811291SRobert.Thurlow@Sun.COM {
27911291SRobert.Thurlow@Sun.COM int slen, err;
28011291SRobert.Thurlow@Sun.COM fs_locations4 *fsl;
28111291SRobert.Thurlow@Sun.COM XDR xdr;
28211291SRobert.Thurlow@Sun.COM
28311291SRobert.Thurlow@Sun.COM if ((!svc_type) || (!svc_data) || (!buf) || (!bufsz) || (*bufsz == 0))
28411291SRobert.Thurlow@Sun.COM return (EINVAL);
28511291SRobert.Thurlow@Sun.COM
28611291SRobert.Thurlow@Sun.COM if (strcasecmp(svc_type, SERVICE_TYPE))
28711291SRobert.Thurlow@Sun.COM return (ENOTSUP);
28811291SRobert.Thurlow@Sun.COM
28911291SRobert.Thurlow@Sun.COM fsl = get_fs_locations((char *)svc_data);
29011291SRobert.Thurlow@Sun.COM if (fsl == NULL)
29111291SRobert.Thurlow@Sun.COM return (ENOENT);
29211291SRobert.Thurlow@Sun.COM #ifdef DEBUG
29311291SRobert.Thurlow@Sun.COM printf("nfs_basic_deref: past get_fs_locations()\n");
29411291SRobert.Thurlow@Sun.COM #endif
29511291SRobert.Thurlow@Sun.COM slen = xdr_sizeof(xdr_fs_locations4, (void *)fsl);
29611291SRobert.Thurlow@Sun.COM if (slen > *bufsz) {
29711291SRobert.Thurlow@Sun.COM *bufsz = slen;
29811291SRobert.Thurlow@Sun.COM xdr_free(xdr_fs_locations4, (char *)fsl);
29911291SRobert.Thurlow@Sun.COM return (EOVERFLOW);
30011291SRobert.Thurlow@Sun.COM }
30111291SRobert.Thurlow@Sun.COM #ifdef DEBUG
30211291SRobert.Thurlow@Sun.COM printf("nfs_basic_deref: past buffer check\n");
30311291SRobert.Thurlow@Sun.COM print_referral_summary(fsl);
30411291SRobert.Thurlow@Sun.COM #endif
30511291SRobert.Thurlow@Sun.COM xdrmem_create(&xdr, buf, *bufsz, XDR_ENCODE);
30611291SRobert.Thurlow@Sun.COM err = xdr_fs_locations4(&xdr, fsl);
30711291SRobert.Thurlow@Sun.COM XDR_DESTROY(&xdr);
30811291SRobert.Thurlow@Sun.COM xdr_free(xdr_fs_locations4, (char *)fsl);
30911291SRobert.Thurlow@Sun.COM if (err != TRUE)
31011291SRobert.Thurlow@Sun.COM return (EINVAL);
31111291SRobert.Thurlow@Sun.COM *bufsz = slen;
31211291SRobert.Thurlow@Sun.COM #ifdef DEBUG
31311291SRobert.Thurlow@Sun.COM printf("nfs_basic_deref: past xdr_fs_locations4() and done\n");
31411291SRobert.Thurlow@Sun.COM #endif
31511291SRobert.Thurlow@Sun.COM return (0);
31611291SRobert.Thurlow@Sun.COM }
31711291SRobert.Thurlow@Sun.COM
31811291SRobert.Thurlow@Sun.COM /*
31911291SRobert.Thurlow@Sun.COM * Form function for nfs-basic service type.
32011291SRobert.Thurlow@Sun.COM */
32111291SRobert.Thurlow@Sun.COM int
nfs_basic_form(const char * svc_type,const char * svc_data,char * buf,size_t * bufsz)32211291SRobert.Thurlow@Sun.COM nfs_basic_form(const char *svc_type, const char *svc_data, char *buf,
32311291SRobert.Thurlow@Sun.COM size_t *bufsz)
32411291SRobert.Thurlow@Sun.COM {
32511291SRobert.Thurlow@Sun.COM int slen;
32611291SRobert.Thurlow@Sun.COM
32711291SRobert.Thurlow@Sun.COM if ((!svc_type) || (!svc_data) || (!buf) || (*bufsz == 0))
32811291SRobert.Thurlow@Sun.COM return (EINVAL);
32911291SRobert.Thurlow@Sun.COM
33011291SRobert.Thurlow@Sun.COM if (strcmp(svc_type, SERVICE_TYPE))
33111291SRobert.Thurlow@Sun.COM return (ENOTSUP);
33211291SRobert.Thurlow@Sun.COM
33311291SRobert.Thurlow@Sun.COM slen = strlen(svc_data) + 1;
33411291SRobert.Thurlow@Sun.COM if (slen > *bufsz) {
33511291SRobert.Thurlow@Sun.COM *bufsz = slen;
33611291SRobert.Thurlow@Sun.COM return (EOVERFLOW);
33711291SRobert.Thurlow@Sun.COM }
33811291SRobert.Thurlow@Sun.COM *bufsz = slen;
33911291SRobert.Thurlow@Sun.COM strncpy(buf, svc_data, slen);
34011291SRobert.Thurlow@Sun.COM return (0);
34111291SRobert.Thurlow@Sun.COM }
342