1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include "nfs4_prot.h"
28 #include "nfstcl4.h"
29
30 /*
31 * Given the "claim" argument of:
32 * {claim_type {filename|delegate_type|{delegate_stateid filename}}
33 * fill in the open_claim4 structure.
34 * Return TCL_ERROR on failure.
35 */
36
37 int
38 set_openclaim(Tcl_Interp *interp, char *cargl, open_claim4 *cl)
39 {
40 int lc;
41 char **lv;
42 char buf[80];
43 char lv1[1024], lv2[1024];
44 int otype;
45 stateid4 stateid;
46
47 /* First split the "cargl" to get the correct argument */
48 if (Tcl_SplitList(interp, cargl, &lc,
49 (CONST84 char ***)&lv) != TCL_OK) {
50 sprintf(buf, "set_openclaim error, can't split {%s}", cargl);
51 interp->result = buf;
52 return (TCL_ERROR);
53 }
54 if (lc < 2) {
55 sprintf(buf,
56 "set_openclaim error, {%s} needs at least 2 fields",
57 cargl);
58 interp->result = buf;
59 if (lv)
60 free((char *)lv);
61 return (TCL_ERROR);
62 }
63
64 /* Get the opentype, set different argument value base on it */
65 substitution(interp, lv[0]);
66 otype = (int)atoi(interp->result);
67
68 substitution(interp, lv[1]);
69 strcpy(lv1, interp->result);
70 substitution(interp, lv[2]);
71 strcpy(lv2, interp->result);
72
73 switch (otype) {
74 case 0: /* CLAIM_NULL */
75 if (lc != 2) {
76 interp->result =
77 "set_openclaim of CLAIM_NULL, need (0 filename)";
78 if (lv)
79 free((char *)lv);
80 return (TCL_ERROR);
81 }
82 cl->claim = CLAIM_NULL;
83 cl->open_claim4_u.file = *str2utf8(lv1);
84 break;
85 case 1: /* CLAIM_PREVIOUS */
86 if (lc != 2) {
87 interp->result =
88 "set_openclaim of CLAIM_PREVIOUS,"
89 " need (delegate_type)";
90 if (lv)
91 free((char *)lv);
92 return (TCL_ERROR);
93 }
94 cl->claim = CLAIM_PREVIOUS;
95 cl->open_claim4_u.delegate_type = (uint32_t)atoi(lv1);
96 break;
97 case 2: /* CLAIM_DELEGATE_CUR */
98 if (lc != 3) {
99 interp->result =
100 "set_openclaim of CLAIM_DELEGATE_CUR,"
101 " need (filename delegate_stateid)";
102 if (lv)
103 free((char *)lv);
104 return (TCL_ERROR);
105 }
106 cl->claim = CLAIM_DELEGATE_CUR;
107 cl->open_claim4_u.delegate_cur_info.file = *str2utf8(lv1);
108 if (str2stateid(interp, lv2, &stateid) != TCL_OK) {
109 interp->result = "set_openclaim: str2stateid() error";
110 return (TCL_ERROR);
111 }
112 cl->open_claim4_u.delegate_cur_info.delegate_stateid = stateid;
113 break;
114 case 3: /* CLAIM_DELEGATE_PREV */
115 if (lc != 2) {
116 interp->result =
117 "set_openclaim of CLAIM_DELEGATE_PREV,"
118 " need (3 filename)";
119 if (lv)
120 free((char *)lv);
121 return (TCL_ERROR);
122 }
123 cl->claim = CLAIM_DELEGATE_PREV;
124 cl->open_claim4_u.file_delegate_prev = *str2utf8(lv1);
125 break;
126 default:
127 interp->result = "set_openclaim error, Unknown type";
128 if (lv)
129 free((char *)lv);
130 return (TCL_ERROR);
131 }
132
133 free((char *)lv);
134 return (TCL_OK);
135 }
136
137 /*
138 * Given the "opentype" argument ({type {mode attr} {mode verf}},
139 * fill in the opentype4 structure. Return TCL_ERROR on failure.
140 */
141
142 int
143 set_opentype(Tcl_Interp *interp, char *targl, openflag4 *of)
144 {
145 int lc;
146 char **lv;
147 char buf[80];
148 char lv1[1024], lv2[1024];
149 int otype;
150 int cmode;
151
152 /* First split the "targl" to get the correct argument */
153 if (Tcl_SplitList(interp, targl, &lc,
154 (CONST84 char ***)&lv) != TCL_OK) {
155 sprintf(buf, "set_opentype error, can't split {%s}", targl);
156 interp->result = buf;
157 return (TCL_ERROR);
158 }
159 if (lc < 3) {
160 sprintf(buf,
161 "set_opentype error, {%s} needs at least 3 fields", targl);
162 interp->result = buf;
163 if (lv)
164 free((char *)lv);
165 return (TCL_ERROR);
166 }
167
168 /* Get the type, set different argument value base on it */
169 substitution(interp, lv[0]);
170 otype = (int)atoi(interp->result);
171
172 substitution(interp, lv[1]);
173 strcpy(lv1, interp->result);
174 substitution(interp, lv[2]);
175 strcpy(lv2, interp->result);
176
177 switch (otype) {
178 case 0: /* OPEN4_NOCREATE */
179 of->opentype = OPEN4_NOCREATE;
180 break;
181 case 1: /* OPEN4_CREATE */
182 of->opentype = OPEN4_CREATE;
183 cmode = (int)atoi(lv1);
184
185 switch (cmode) {
186 bitmap4 bm;
187 attrlist4 av;
188 verifier4 verf;
189
190 case 0: /* UNCHECKED */
191 if (lc < 3) {
192 interp->result =
193 "set_opentype: OPEN4_CREATE/UNCHECKED,"
194 " need ({name val} ... createattrs)";
195 if (lv)
196 free((char *)lv);
197 return (TCL_ERROR);
198 }
199 of->openflag4_u.how.mode = UNCHECKED4;
200 if ((attr_encode(interp, lv2, &bm, &av)) != TCL_OK)
201 return (TCL_ERROR);
202 of->openflag4_u.how.createhow4_u.createattrs.attrmask
203 = bm;
204 of->openflag4_u.how.createhow4_u.createattrs.attr_vals
205 = av;
206 break;
207 case 1: /* GUARDED */
208 if (lc < 3) {
209 interp->result =
210 "set_opentype: OPEN4_CREATE/GUARDED,"
211 " need ({name val} ... createattrs)";
212 if (lv)
213 free((char *)lv);
214 return (TCL_ERROR);
215 }
216 of->openflag4_u.how.mode = GUARDED4;
217 if ((attr_encode(interp, lv2, &bm, &av)) != TCL_OK) {
218 if (lv)
219 free((char *)lv);
220 return (TCL_ERROR);
221 }
222 of->openflag4_u.how.createhow4_u.createattrs.attrmask
223 = bm;
224 of->openflag4_u.how.createhow4_u.createattrs.attr_vals
225 = av;
226 break;
227 case 2: /* EXCLUSIVE */
228 if (lc < 3) {
229 interp->result =
230 "set_opentype: OPEN4_CREATE/EXCLUSIVE,"
231 " need (createverf)";
232 if (lv)
233 free((char *)lv);
234 return (TCL_ERROR);
235 }
236 memcpy(&verf, hex2bin(lv2, sizeof (verf)),
237 sizeof (verf));
238 of->openflag4_u.how.mode = EXCLUSIVE4;
239 memcpy(of->openflag4_u.how.createhow4_u.createverf,
240 &verf, NFS4_VERIFIER_SIZE);
241 break;
242 default:
243 break;
244 }
245 break;
246 default:
247 break;
248 }
249
250 free((char *)lv);
251 return (TCL_OK);
252 }
253
254 /*
255 * Given the "openowner" argument (in form of {clientid owner})
256 * fill in the open_owner4 structure.
257 * Return TCL_ERROR on failure.
258 */
259
260 int
261 set_owner(Tcl_Interp *interp, char *argl, open_owner4 *oo)
262 {
263 int lc;
264 char **lv;
265 char buf[80];
266 char lv0[1024] = "";
267 static char lv1[1024];
268
269 lv1[0] = 0;
270 /* First split the "argl" to get the correct argument */
271 if (Tcl_SplitList(interp, argl, &lc, (CONST84 char ***)&lv) != TCL_OK) {
272 sprintf(buf, "set_owner error, can't split {%s}", argl);
273 interp->result = buf;
274 return (TCL_ERROR);
275 }
276 if (lc < 2) {
277 sprintf(buf,
278 "set_owner error, {%s} needs at least 2 fields", argl);
279 interp->result = buf;
280 if (lv)
281 free((char *)lv);
282 return (TCL_ERROR);
283 }
284 substitution(interp, lv[0]);
285 strcpy(lv0, interp->result);
286 oo->clientid = (clientid4) strtoull(lv0, NULL, 16);
287 substitution(interp, lv[1]);
288 strcpy(lv1, interp->result);
289 oo->owner.owner_len = strlen(lv1);
290 oo->owner.owner_val = lv1;
291
292 free((char *)lv);
293 return (TCL_OK);
294 }