4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
31 #include <sys/types.h>
33 #include <sys/errno.h>
35 #include <libnvpair.h>
38 #include <rp_plugin.h>
40 #include <uuid/uuid.h>
41 #include <rpc/types.h>
45 #include <rpc/rpc_msg.h>
46 #include <sys/param.h>
48 #include <rpcsvc/nfs4_prot.h>
53 #define SERVICE_TYPE "nfs-basic"
55 char *nfs_basic_service_type(void);
56 boolean_t
nfs_basic_supports_svc(const char *);
57 int nfs_basic_deref(const char *, const char *, char *, size_t *);
58 int nfs_basic_form(const char *, const char *, char *, size_t *);
60 struct rp_plugin_ops rp_plugin_ops
= {
64 nfs_basic_service_type
,
65 nfs_basic_supports_svc
,
71 * What service type does this module support?
74 nfs_basic_service_type()
76 return (SERVICE_TYPE
);
80 * Does this module support a particular service type?
83 nfs_basic_supports_svc(const char *svc_type
)
87 return (!strncasecmp(svc_type
, SERVICE_TYPE
, strlen(SERVICE_TYPE
)));
91 * Take a string with a set of locations like this:
92 * host1:/path1 host2:/path2 host3:/path3
93 * and convert it to an fs_locations4 for the deref routine.
95 static fs_locations4
*
96 get_fs_locations(char *buf
)
98 fs_locations4
*result
= NULL
;
99 fs_location4
*fsl_array
;
101 int fsl_count
= 0, escape
= 0, delimiter
= 0;
103 char *p
, *sp
, *dp
, buf2
[SYMLINK_MAX
];
108 printf("get_fs_locations: input %s\n", buf
);
111 * Count fs_location entries by counting spaces.
112 * Remember that escaped spaces ("\ ") may exist.
113 * We mark the location boundaries with null bytes.
115 * escape - set if we have found a backspace,
116 * part of either "\ " or "\\"
117 * delimiter - set if we have found a space and
118 * used to skip multiple spaces
120 for (sp
= buf
; sp
&& *sp
; sp
++) {
140 if (escape
== 0 && *sp
!= '\0')
143 printf("get_fs_locations: fsl_count %d\n", fsl_count
);
148 /* Alloc space for everything */
149 result
= calloc(1, sizeof (fs_locations4
));
152 fsl_array
= calloc(fsl_count
, sizeof (fs_location4
));
153 if (fsl_array
== NULL
) {
158 result
->locations
.locations_len
= fsl_count
;
159 result
->locations
.locations_val
= fsl_array
;
160 result
->fs_root
.pathname4_len
= 0;
161 result
->fs_root
.pathname4_val
= NULL
;
164 * Copy input, removing escapes from host:/path/to/my\ files
168 bzero(buf2
, sizeof (buf2
));
171 while ((sp
&& *sp
&& (sp
- buf
< len
)) || gothost
) {
174 /* Drop leading spaces */
180 /* Look for the rightmost colon for host */
181 p
= strrchr(sp
, ':');
184 printf("get_fs_locations: skipping %s\n", sp
);
187 sp
+= strlen(sp
) + 1;
189 bcopy(sp
, dp
, p
- sp
);
192 printf("get_fs_locations: host %s\n", buf2
);
194 fsl_array
[i
].server
.server_len
= 1;
195 fsl_array
[i
].server
.server_val
=
196 malloc(sizeof (utf8string
));
197 if (fsl_array
[i
].server
.server_val
== NULL
) {
202 for (j
= 0; j
< i
; j
++)
209 fsl_array
[i
].server
.server_val
);
212 bzero(buf2
, sizeof (buf2
));
217 /* End of string should mean a pathname */
218 if (*sp
== '\0' && gothost
) {
220 printf("get_fs_locations: path %s\n", buf2
);
222 (void) make_pathname4(buf2
, &fsl_array
[i
].rootpath
);
226 bzero(buf2
, sizeof (buf2
));
232 /* Skip a single escape character */
236 /* Plain char, just copy it */
241 * If we're still expecting a path name, we don't have a
242 * server:/path pair and should discard the server and
243 * note that we got fewer locations than expected.
247 free(fsl_array
[i
].server
.server_val
);
248 fsl_array
[i
].server
.server_val
= NULL
;
249 fsl_array
[i
].server
.server_len
= 0;
253 * If we have zero entries, we never got a whole server:/path
254 * pair, and so cannot have anything else allocated.
256 if (fsl_count
<= 0) {
263 * Make sure we reflect the right number of locations.
265 if (fsl_count
< result
->locations
.locations_len
)
266 result
->locations
.locations_len
= fsl_count
;
273 * Deref function for nfs-basic service type returns an fs_locations4.
276 nfs_basic_deref(const char *svc_type
, const char *svc_data
, char *buf
,
283 if ((!svc_type
) || (!svc_data
) || (!buf
) || (!bufsz
) || (*bufsz
== 0))
286 if (strcasecmp(svc_type
, SERVICE_TYPE
))
289 fsl
= get_fs_locations((char *)svc_data
);
293 printf("nfs_basic_deref: past get_fs_locations()\n");
295 slen
= xdr_sizeof(xdr_fs_locations4
, (void *)fsl
);
298 xdr_free(xdr_fs_locations4
, (char *)fsl
);
302 printf("nfs_basic_deref: past buffer check\n");
303 print_referral_summary(fsl
);
305 xdrmem_create(&xdr
, buf
, *bufsz
, XDR_ENCODE
);
306 err
= xdr_fs_locations4(&xdr
, fsl
);
308 xdr_free(xdr_fs_locations4
, (char *)fsl
);
313 printf("nfs_basic_deref: past xdr_fs_locations4() and done\n");
319 * Form function for nfs-basic service type.
322 nfs_basic_form(const char *svc_type
, const char *svc_data
, char *buf
,
327 if ((!svc_type
) || (!svc_data
) || (!buf
) || (*bufsz
== 0))
330 if (strcmp(svc_type
, SERVICE_TYPE
))
333 slen
= strlen(svc_data
) + 1;
339 strncpy(buf
, svc_data
, slen
);