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 }