1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 1999-2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * This module implements the routine to parse the configuration file. 31*7c478bd9Sstevel@tonic-gate */ 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate #include <stdio.h> 35*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 36*7c478bd9Sstevel@tonic-gate #include <unistd.h> 37*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 38*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 39*7c478bd9Sstevel@tonic-gate #include <string.h> 40*7c478bd9Sstevel@tonic-gate #include <ctype.h> 41*7c478bd9Sstevel@tonic-gate #include <alloca.h> 42*7c478bd9Sstevel@tonic-gate #include <limits.h> 43*7c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 44*7c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 46*7c478bd9Sstevel@tonic-gate #include <libintl.h> 47*7c478bd9Sstevel@tonic-gate #include <syslog.h> 48*7c478bd9Sstevel@tonic-gate #include <locale.h> 49*7c478bd9Sstevel@tonic-gate #include <picl.h> 50*7c478bd9Sstevel@tonic-gate #include <picltree.h> 51*7c478bd9Sstevel@tonic-gate #include "picld_pluginutil.h" 52*7c478bd9Sstevel@tonic-gate #include "picld_pluginutil_impl.h" 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate /* error codes returned from syntax checking */ 55*7c478bd9Sstevel@tonic-gate #define EC_SYNTAX_OK 0 56*7c478bd9Sstevel@tonic-gate #define EC_INSUFFICIENT_TOKEN 1 57*7c478bd9Sstevel@tonic-gate #define EC_SYNTAX_ERR 2 58*7c478bd9Sstevel@tonic-gate #define EC_UNSUPPORTED 3 59*7c478bd9Sstevel@tonic-gate #define EC_PATH_ERR 4 60*7c478bd9Sstevel@tonic-gate #define EC_NODE_MISMATCH 5 61*7c478bd9Sstevel@tonic-gate #define EC_FAILURE 6 62*7c478bd9Sstevel@tonic-gate #define EC_PICL_ERR 7 63*7c478bd9Sstevel@tonic-gate #define EC_TABLE_MISMATCH 8 64*7c478bd9Sstevel@tonic-gate #define EC_ROW_MISMATCH 9 65*7c478bd9Sstevel@tonic-gate #define EC_ROW_EMPTY 10 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate /* 68*7c478bd9Sstevel@tonic-gate * Error message texts 69*7c478bd9Sstevel@tonic-gate */ 70*7c478bd9Sstevel@tonic-gate static char *err_msg[] = { 71*7c478bd9Sstevel@tonic-gate "%s: Syntax OK", /* 0 */ 72*7c478bd9Sstevel@tonic-gate "%s::%s[line %d]: Insufficient token\n", /* 1 */ 73*7c478bd9Sstevel@tonic-gate "%s::%s[line %d]: Syntax error\n", /* 2 */ 74*7c478bd9Sstevel@tonic-gate "%s::%s[line %d]: Unsupported or missing version\n", /* 3 */ 75*7c478bd9Sstevel@tonic-gate "%s::%s[line %d]: Illegal use of nodepath or namepath\n", /* 4 */ 76*7c478bd9Sstevel@tonic-gate "%s::%s[line %d]: Node and endnode mismatch\n", /* 5 */ 77*7c478bd9Sstevel@tonic-gate "%s::%s[line %d]: General system failure\n", /* 6 */ 78*7c478bd9Sstevel@tonic-gate "%s: PICL error code %d\n", /* 7 */ 79*7c478bd9Sstevel@tonic-gate "%s::%s[line %d]: Table and endtable mismatch\n", /* 8 */ 80*7c478bd9Sstevel@tonic-gate "%s::%s[line %d]: Row and endrow mismatch\n", /* 9 */ 81*7c478bd9Sstevel@tonic-gate "%s::%s[line %d]: Row has no entries \n" /* 10 */ 82*7c478bd9Sstevel@tonic-gate }; 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate /* token per directive */ 85*7c478bd9Sstevel@tonic-gate #define TOK_CLASSPATH 0 86*7c478bd9Sstevel@tonic-gate #define TOK_NAMEPATH 1 87*7c478bd9Sstevel@tonic-gate #define TOK_NODE 2 88*7c478bd9Sstevel@tonic-gate #define TOK_ENDNODE 3 89*7c478bd9Sstevel@tonic-gate #define TOK_PROP 4 90*7c478bd9Sstevel@tonic-gate #define TOK_REFPROP 5 91*7c478bd9Sstevel@tonic-gate #define TOK_VERSION 6 92*7c478bd9Sstevel@tonic-gate #define TOK_REFNODE 7 93*7c478bd9Sstevel@tonic-gate #define TOK_VERBOSE 8 94*7c478bd9Sstevel@tonic-gate #define TOK_TABLE 9 95*7c478bd9Sstevel@tonic-gate #define TOK_ENDTABLE 10 96*7c478bd9Sstevel@tonic-gate #define TOK_ROW 11 97*7c478bd9Sstevel@tonic-gate #define TOK_ENDROW 12 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate static const char *tokens[] = { 100*7c478bd9Sstevel@tonic-gate "_class", /* _CLASS:<classpath> */ 101*7c478bd9Sstevel@tonic-gate "name", /* NAME:<namepath> */ 102*7c478bd9Sstevel@tonic-gate "node", /* NODE <name> <class> */ 103*7c478bd9Sstevel@tonic-gate "endnode", /* ENDNODE */ 104*7c478bd9Sstevel@tonic-gate "prop", /* PROP <name> <type> <access_mode> <size> <value> */ 105*7c478bd9Sstevel@tonic-gate "refprop", /* REFPROP <prop> <destnode> */ 106*7c478bd9Sstevel@tonic-gate "version", /* VERSION <version_number> */ 107*7c478bd9Sstevel@tonic-gate "refnode", /* REFNODE <node> <class> WITH <destnode> */ 108*7c478bd9Sstevel@tonic-gate "verbose", /* VERBOSE <level> */ 109*7c478bd9Sstevel@tonic-gate "table", /* TABLE <table_prop_name> */ 110*7c478bd9Sstevel@tonic-gate "endtable", /* ENDTABLE */ 111*7c478bd9Sstevel@tonic-gate "row", /* ROW */ 112*7c478bd9Sstevel@tonic-gate "endrow" /* ENDROW */ 113*7c478bd9Sstevel@tonic-gate }; 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate #define BUF_SIZE_MAX 1024 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate /* 118*7c478bd9Sstevel@tonic-gate * print error message 119*7c478bd9Sstevel@tonic-gate */ 120*7c478bd9Sstevel@tonic-gate /*VARARGS2*/ 121*7c478bd9Sstevel@tonic-gate static void 122*7c478bd9Sstevel@tonic-gate verbose_log(int pri, const char *fmt, ...) 123*7c478bd9Sstevel@tonic-gate { 124*7c478bd9Sstevel@tonic-gate va_list ap; 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate va_start(ap, fmt); 127*7c478bd9Sstevel@tonic-gate vsyslog(pri, fmt, ap); 128*7c478bd9Sstevel@tonic-gate va_end(ap); 129*7c478bd9Sstevel@tonic-gate } 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate /* 132*7c478bd9Sstevel@tonic-gate * Undo the commands which have created valid node/prop handle 133*7c478bd9Sstevel@tonic-gate * The undo order is from last command to the first command. 134*7c478bd9Sstevel@tonic-gate */ 135*7c478bd9Sstevel@tonic-gate static void 136*7c478bd9Sstevel@tonic-gate undo_commands(cmdbuf_t *cmds, int last_cmd_index) 137*7c478bd9Sstevel@tonic-gate { 138*7c478bd9Sstevel@tonic-gate int i; 139*7c478bd9Sstevel@tonic-gate command_t *com = cmds->commands; 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate for (i = last_cmd_index; i >= 0; i--) { 142*7c478bd9Sstevel@tonic-gate switch (com[i].type) { 143*7c478bd9Sstevel@tonic-gate case TOK_NODE: 144*7c478bd9Sstevel@tonic-gate if (com[i].nodecmd_nodeh == NULL) 145*7c478bd9Sstevel@tonic-gate break; 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate (void) ptree_delete_node(com[i].nodecmd_nodeh); 148*7c478bd9Sstevel@tonic-gate (void) ptree_destroy_node(com[i].nodecmd_nodeh); 149*7c478bd9Sstevel@tonic-gate break; 150*7c478bd9Sstevel@tonic-gate case TOK_REFNODE: 151*7c478bd9Sstevel@tonic-gate if (com[i].refnodecmd_nodeh == NULL) 152*7c478bd9Sstevel@tonic-gate break; 153*7c478bd9Sstevel@tonic-gate (void) ptree_delete_node(com[i].refnodecmd_nodeh); 154*7c478bd9Sstevel@tonic-gate (void) ptree_destroy_node(com[i].refnodecmd_nodeh); 155*7c478bd9Sstevel@tonic-gate break; 156*7c478bd9Sstevel@tonic-gate case TOK_PROP: 157*7c478bd9Sstevel@tonic-gate if (com[i].propcmd_proph == NULL) 158*7c478bd9Sstevel@tonic-gate break; 159*7c478bd9Sstevel@tonic-gate (void) ptree_delete_prop(com[i].propcmd_proph); 160*7c478bd9Sstevel@tonic-gate (void) ptree_destroy_prop(com[i].propcmd_proph); 161*7c478bd9Sstevel@tonic-gate break; 162*7c478bd9Sstevel@tonic-gate case TOK_REFPROP: 163*7c478bd9Sstevel@tonic-gate if (com[i].refpropcmd_proph == NULL) 164*7c478bd9Sstevel@tonic-gate break; 165*7c478bd9Sstevel@tonic-gate (void) ptree_delete_prop(com[i].refpropcmd_proph); 166*7c478bd9Sstevel@tonic-gate (void) ptree_destroy_prop(com[i].refpropcmd_proph); 167*7c478bd9Sstevel@tonic-gate break; 168*7c478bd9Sstevel@tonic-gate case TOK_TABLE: 169*7c478bd9Sstevel@tonic-gate if ((com[i].tablecmd_tblh == NULL) || 170*7c478bd9Sstevel@tonic-gate (com[i].tablecmd_newtbl == 0)) 171*7c478bd9Sstevel@tonic-gate break; 172*7c478bd9Sstevel@tonic-gate (void) ptree_delete_prop(com[i].tablecmd_tblh); 173*7c478bd9Sstevel@tonic-gate (void) ptree_destroy_prop(com[i].tablecmd_tblh); 174*7c478bd9Sstevel@tonic-gate break; 175*7c478bd9Sstevel@tonic-gate case TOK_ENDTABLE: 176*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 177*7c478bd9Sstevel@tonic-gate case TOK_ROW: 178*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 179*7c478bd9Sstevel@tonic-gate case TOK_ENDROW: 180*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 181*7c478bd9Sstevel@tonic-gate case TOK_NAMEPATH: 182*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 183*7c478bd9Sstevel@tonic-gate case TOK_CLASSPATH: 184*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 185*7c478bd9Sstevel@tonic-gate case TOK_ENDNODE: 186*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 187*7c478bd9Sstevel@tonic-gate case TOK_VERBOSE: 188*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 189*7c478bd9Sstevel@tonic-gate default: 190*7c478bd9Sstevel@tonic-gate break; 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate } 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate /* 196*7c478bd9Sstevel@tonic-gate * Get the token index from the tokens table 197*7c478bd9Sstevel@tonic-gate */ 198*7c478bd9Sstevel@tonic-gate static int 199*7c478bd9Sstevel@tonic-gate get_token_id(char *t) 200*7c478bd9Sstevel@tonic-gate { 201*7c478bd9Sstevel@tonic-gate int i; 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (tokens)/ sizeof (char *); ++i) 204*7c478bd9Sstevel@tonic-gate if (strcasecmp(tokens[i], t) == 0) 205*7c478bd9Sstevel@tonic-gate return (i); 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate return (-1); 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate /* 211*7c478bd9Sstevel@tonic-gate * Check the version syntax and set the version_no 212*7c478bd9Sstevel@tonic-gate * 213*7c478bd9Sstevel@tonic-gate * VERSION <version_num> -- specify the configuration version 214*7c478bd9Sstevel@tonic-gate */ 215*7c478bd9Sstevel@tonic-gate static int 216*7c478bd9Sstevel@tonic-gate parse_version(cmdbuf_t *cmds, char *line) 217*7c478bd9Sstevel@tonic-gate { 218*7c478bd9Sstevel@tonic-gate char *tok; 219*7c478bd9Sstevel@tonic-gate char *vertok; 220*7c478bd9Sstevel@tonic-gate char *last; 221*7c478bd9Sstevel@tonic-gate char *endptr; 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate /* get the VERSION directive */ 224*7c478bd9Sstevel@tonic-gate tok = strtok_r(line, WHITESPACE, &last); 225*7c478bd9Sstevel@tonic-gate if (tok == NULL) 226*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate /* get the version number */ 229*7c478bd9Sstevel@tonic-gate vertok = strtok_r(last, WHITESPACE, &last); 230*7c478bd9Sstevel@tonic-gate if (vertok == NULL) 231*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate cmds->version_no = (float)strtod(vertok, &endptr); 234*7c478bd9Sstevel@tonic-gate if (endptr != (vertok + strlen(vertok))) 235*7c478bd9Sstevel@tonic-gate return (EC_UNSUPPORTED); 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate if (cmds->version_no > (float)SUPPORTED_VERSION_NUM) 238*7c478bd9Sstevel@tonic-gate return (EC_UNSUPPORTED); 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate /* check if more tokens */ 241*7c478bd9Sstevel@tonic-gate tok = strtok_r(last, WHITESPACE, &last); 242*7c478bd9Sstevel@tonic-gate if (tok != NULL) 243*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 246*7c478bd9Sstevel@tonic-gate } 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate /* 249*7c478bd9Sstevel@tonic-gate * free path_cmd_t 250*7c478bd9Sstevel@tonic-gate */ 251*7c478bd9Sstevel@tonic-gate static void 252*7c478bd9Sstevel@tonic-gate free_path(command_t *command) 253*7c478bd9Sstevel@tonic-gate { 254*7c478bd9Sstevel@tonic-gate free(command->pathcmd_name); 255*7c478bd9Sstevel@tonic-gate } 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate /* 258*7c478bd9Sstevel@tonic-gate * Check the path syntax 259*7c478bd9Sstevel@tonic-gate * NAMEPATH:<namepath> -- gives the anchor node 260*7c478bd9Sstevel@tonic-gate * or 261*7c478bd9Sstevel@tonic-gate * CLASSPATH:<classpath> -- gives the anchor node 262*7c478bd9Sstevel@tonic-gate */ 263*7c478bd9Sstevel@tonic-gate static int 264*7c478bd9Sstevel@tonic-gate parse_path(char *line, command_t *command) 265*7c478bd9Sstevel@tonic-gate { 266*7c478bd9Sstevel@tonic-gate char *tok; 267*7c478bd9Sstevel@tonic-gate char *pathtok; 268*7c478bd9Sstevel@tonic-gate char *last; 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate pathtok = strtok_r(line, WHITESPACE, &last); 271*7c478bd9Sstevel@tonic-gate if (pathtok == NULL) 272*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate /* check if more tokens */ 275*7c478bd9Sstevel@tonic-gate tok = strtok_r(last, WHITESPACE, &last); 276*7c478bd9Sstevel@tonic-gate if (tok != NULL) 277*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate command->pathcmd_name = strdup(pathtok); 280*7c478bd9Sstevel@tonic-gate if (command->pathcmd_name == NULL) 281*7c478bd9Sstevel@tonic-gate return (EC_FAILURE); 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate /* 287*7c478bd9Sstevel@tonic-gate * Process the path command and return PICL node handle 288*7c478bd9Sstevel@tonic-gate */ 289*7c478bd9Sstevel@tonic-gate static int 290*7c478bd9Sstevel@tonic-gate process_path(command_t *command, picl_nodehdl_t *nodeh) 291*7c478bd9Sstevel@tonic-gate { 292*7c478bd9Sstevel@tonic-gate int err; 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate err = ptree_get_node_by_path(command->pathcmd_name, nodeh); 295*7c478bd9Sstevel@tonic-gate return (err); 296*7c478bd9Sstevel@tonic-gate } 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate /* 299*7c478bd9Sstevel@tonic-gate * free node_cmd_t 300*7c478bd9Sstevel@tonic-gate */ 301*7c478bd9Sstevel@tonic-gate static void 302*7c478bd9Sstevel@tonic-gate free_node(command_t *command) 303*7c478bd9Sstevel@tonic-gate { 304*7c478bd9Sstevel@tonic-gate free(command->nodecmd_nodename); 305*7c478bd9Sstevel@tonic-gate free(command->nodecmd_classname); 306*7c478bd9Sstevel@tonic-gate } 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate /* 309*7c478bd9Sstevel@tonic-gate * Check the NODE syntax 310*7c478bd9Sstevel@tonic-gate * NODE <name> <class> 311*7c478bd9Sstevel@tonic-gate */ 312*7c478bd9Sstevel@tonic-gate static int 313*7c478bd9Sstevel@tonic-gate parse_node(char *line, command_t *command) 314*7c478bd9Sstevel@tonic-gate { 315*7c478bd9Sstevel@tonic-gate char *tok; 316*7c478bd9Sstevel@tonic-gate char *nametok; 317*7c478bd9Sstevel@tonic-gate char *classtok; 318*7c478bd9Sstevel@tonic-gate char *last; 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate /* get the NODE directive */ 321*7c478bd9Sstevel@tonic-gate tok = strtok_r(line, WHITESPACE, &last); 322*7c478bd9Sstevel@tonic-gate if (tok == NULL) 323*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate /* get name */ 326*7c478bd9Sstevel@tonic-gate nametok = strtok_r(last, WHITESPACE, &last); 327*7c478bd9Sstevel@tonic-gate if (nametok == NULL) 328*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate classtok = strtok_r(last, WHITESPACE, &last); 331*7c478bd9Sstevel@tonic-gate if (classtok == NULL) 332*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 333*7c478bd9Sstevel@tonic-gate 334*7c478bd9Sstevel@tonic-gate /* check if more tokens */ 335*7c478bd9Sstevel@tonic-gate tok = strtok_r(last, WHITESPACE, &last); 336*7c478bd9Sstevel@tonic-gate if (tok != NULL) 337*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate command->nodecmd_nodename = strdup(nametok); 340*7c478bd9Sstevel@tonic-gate command->nodecmd_classname = strdup(classtok); 341*7c478bd9Sstevel@tonic-gate command->nodecmd_nodeh = NULL; 342*7c478bd9Sstevel@tonic-gate if ((command->nodecmd_nodename == NULL) || 343*7c478bd9Sstevel@tonic-gate (command->nodecmd_classname == NULL)) 344*7c478bd9Sstevel@tonic-gate return (EC_FAILURE); 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate /* 350*7c478bd9Sstevel@tonic-gate * Process the NODE command and return PICL node handle 351*7c478bd9Sstevel@tonic-gate */ 352*7c478bd9Sstevel@tonic-gate static int 353*7c478bd9Sstevel@tonic-gate process_node(command_t *command, picl_nodehdl_t parh, picl_nodehdl_t *nodeh) 354*7c478bd9Sstevel@tonic-gate { 355*7c478bd9Sstevel@tonic-gate int err; 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate err = ptree_create_and_add_node(parh, command->nodecmd_nodename, 358*7c478bd9Sstevel@tonic-gate command->nodecmd_classname, nodeh); 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS) 361*7c478bd9Sstevel@tonic-gate command->nodecmd_nodeh = *nodeh; 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate return (err); 364*7c478bd9Sstevel@tonic-gate } 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate /* 367*7c478bd9Sstevel@tonic-gate * get the PICL property type 368*7c478bd9Sstevel@tonic-gate */ 369*7c478bd9Sstevel@tonic-gate static int 370*7c478bd9Sstevel@tonic-gate getpicltype(char *type) 371*7c478bd9Sstevel@tonic-gate { 372*7c478bd9Sstevel@tonic-gate if (strcasecmp(type, KEYWORD_INT_TYPE) == 0) 373*7c478bd9Sstevel@tonic-gate return (PICL_PTYPE_INT); 374*7c478bd9Sstevel@tonic-gate else if (strcasecmp(type, KEYWORD_UINT_TYPE) == 0) 375*7c478bd9Sstevel@tonic-gate return (PICL_PTYPE_UNSIGNED_INT); 376*7c478bd9Sstevel@tonic-gate else if (strcasecmp(type, KEYWORD_FLOAT_TYPE) == 0) 377*7c478bd9Sstevel@tonic-gate return (PICL_PTYPE_FLOAT); 378*7c478bd9Sstevel@tonic-gate else if (strcasecmp(type, KEYWORD_STRING_TYPE) == 0) 379*7c478bd9Sstevel@tonic-gate return (PICL_PTYPE_CHARSTRING); 380*7c478bd9Sstevel@tonic-gate else if (strcasecmp(type, KEYWORD_VOID_TYPE) == 0) 381*7c478bd9Sstevel@tonic-gate return (PICL_PTYPE_VOID); 382*7c478bd9Sstevel@tonic-gate else 383*7c478bd9Sstevel@tonic-gate return (-1); 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate /* 387*7c478bd9Sstevel@tonic-gate * get the PICL accessmode mode 388*7c478bd9Sstevel@tonic-gate */ 389*7c478bd9Sstevel@tonic-gate static int 390*7c478bd9Sstevel@tonic-gate getpiclmode(char *mode) 391*7c478bd9Sstevel@tonic-gate { 392*7c478bd9Sstevel@tonic-gate if (strcasecmp(mode, KEYWORD_READ_MODE) == 0) 393*7c478bd9Sstevel@tonic-gate return (PICL_READ); 394*7c478bd9Sstevel@tonic-gate else if (strcasecmp(mode, KEYWORD_WRITE_MODE) == 0) 395*7c478bd9Sstevel@tonic-gate return (PICL_WRITE); 396*7c478bd9Sstevel@tonic-gate else if (strcasecmp(mode, KEYWORD_READWRITE_MODE) == 0) 397*7c478bd9Sstevel@tonic-gate return (PICL_READ|PICL_WRITE); 398*7c478bd9Sstevel@tonic-gate else 399*7c478bd9Sstevel@tonic-gate return (-1); 400*7c478bd9Sstevel@tonic-gate } 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate /* 403*7c478bd9Sstevel@tonic-gate * check if the size and value are valid given by the prop type 404*7c478bd9Sstevel@tonic-gate */ 405*7c478bd9Sstevel@tonic-gate static int 406*7c478bd9Sstevel@tonic-gate validate_size_and_cvt_val(void *outbuf, size_t size, int type, char *val) 407*7c478bd9Sstevel@tonic-gate { 408*7c478bd9Sstevel@tonic-gate int64_t llval; 409*7c478bd9Sstevel@tonic-gate int32_t intval; 410*7c478bd9Sstevel@tonic-gate int16_t sval; 411*7c478bd9Sstevel@tonic-gate int8_t cval; 412*7c478bd9Sstevel@tonic-gate uint64_t ullval; 413*7c478bd9Sstevel@tonic-gate uint32_t uintval; 414*7c478bd9Sstevel@tonic-gate uint16_t usval; 415*7c478bd9Sstevel@tonic-gate uint8_t ucval; 416*7c478bd9Sstevel@tonic-gate float fval; 417*7c478bd9Sstevel@tonic-gate double dval; 418*7c478bd9Sstevel@tonic-gate char *endptr; 419*7c478bd9Sstevel@tonic-gate 420*7c478bd9Sstevel@tonic-gate switch (type) { 421*7c478bd9Sstevel@tonic-gate case PICL_PTYPE_CHARSTRING: 422*7c478bd9Sstevel@tonic-gate break; 423*7c478bd9Sstevel@tonic-gate case PICL_PTYPE_INT: 424*7c478bd9Sstevel@tonic-gate switch (size) { 425*7c478bd9Sstevel@tonic-gate case sizeof (int64_t): 426*7c478bd9Sstevel@tonic-gate llval = strtoll(val, &endptr, 0); 427*7c478bd9Sstevel@tonic-gate if (endptr != (val + strlen(val))) 428*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 429*7c478bd9Sstevel@tonic-gate (void) memcpy(outbuf, &llval, size); 430*7c478bd9Sstevel@tonic-gate break; 431*7c478bd9Sstevel@tonic-gate case sizeof (int32_t): 432*7c478bd9Sstevel@tonic-gate intval = strtol(val, &endptr, 0); 433*7c478bd9Sstevel@tonic-gate if (endptr != (val + strlen(val))) 434*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 435*7c478bd9Sstevel@tonic-gate (void) memcpy(outbuf, &intval, size); 436*7c478bd9Sstevel@tonic-gate break; 437*7c478bd9Sstevel@tonic-gate case sizeof (int16_t): 438*7c478bd9Sstevel@tonic-gate sval = (int16_t)strtol(val, &endptr, 0); 439*7c478bd9Sstevel@tonic-gate if (endptr != (val + strlen(val))) 440*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 441*7c478bd9Sstevel@tonic-gate (void) memcpy(outbuf, &sval, size); 442*7c478bd9Sstevel@tonic-gate break; 443*7c478bd9Sstevel@tonic-gate case sizeof (int8_t): 444*7c478bd9Sstevel@tonic-gate cval = (int8_t)strtol(val, &endptr, 0); 445*7c478bd9Sstevel@tonic-gate if (endptr != (val + strlen(val))) 446*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 447*7c478bd9Sstevel@tonic-gate (void) memcpy(outbuf, &cval, size); 448*7c478bd9Sstevel@tonic-gate break; 449*7c478bd9Sstevel@tonic-gate default: /* invalid size */ 450*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 451*7c478bd9Sstevel@tonic-gate } 452*7c478bd9Sstevel@tonic-gate break; 453*7c478bd9Sstevel@tonic-gate case PICL_PTYPE_UNSIGNED_INT: 454*7c478bd9Sstevel@tonic-gate switch (size) { 455*7c478bd9Sstevel@tonic-gate case sizeof (uint64_t): 456*7c478bd9Sstevel@tonic-gate ullval = strtoull(val, &endptr, 0); 457*7c478bd9Sstevel@tonic-gate if (endptr != (val + strlen(val))) 458*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 459*7c478bd9Sstevel@tonic-gate (void) memcpy(outbuf, &ullval, size); 460*7c478bd9Sstevel@tonic-gate break; 461*7c478bd9Sstevel@tonic-gate case sizeof (uint32_t): 462*7c478bd9Sstevel@tonic-gate uintval = strtoul(val, &endptr, 0); 463*7c478bd9Sstevel@tonic-gate if (endptr != (val + strlen(val))) 464*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 465*7c478bd9Sstevel@tonic-gate (void) memcpy(outbuf, &uintval, size); 466*7c478bd9Sstevel@tonic-gate break; 467*7c478bd9Sstevel@tonic-gate case sizeof (uint16_t): 468*7c478bd9Sstevel@tonic-gate usval = (uint16_t)strtoul(val, &endptr, 0); 469*7c478bd9Sstevel@tonic-gate if (endptr != (val + strlen(val))) 470*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 471*7c478bd9Sstevel@tonic-gate (void) memcpy(outbuf, &usval, size); 472*7c478bd9Sstevel@tonic-gate break; 473*7c478bd9Sstevel@tonic-gate case sizeof (uint8_t): 474*7c478bd9Sstevel@tonic-gate ucval = (uint8_t)strtoul(val, &endptr, 0); 475*7c478bd9Sstevel@tonic-gate if (endptr != (val + strlen(val))) 476*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 477*7c478bd9Sstevel@tonic-gate (void) memcpy(outbuf, &ucval, size); 478*7c478bd9Sstevel@tonic-gate break; 479*7c478bd9Sstevel@tonic-gate default: /* invalid size */ 480*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 481*7c478bd9Sstevel@tonic-gate } 482*7c478bd9Sstevel@tonic-gate break; 483*7c478bd9Sstevel@tonic-gate case PICL_PTYPE_FLOAT: 484*7c478bd9Sstevel@tonic-gate switch (size) { 485*7c478bd9Sstevel@tonic-gate case sizeof (double): 486*7c478bd9Sstevel@tonic-gate dval = strtod(val, &endptr); 487*7c478bd9Sstevel@tonic-gate if (endptr != (val + strlen(val))) 488*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 489*7c478bd9Sstevel@tonic-gate (void) memcpy(outbuf, &dval, size); 490*7c478bd9Sstevel@tonic-gate break; 491*7c478bd9Sstevel@tonic-gate case sizeof (float): 492*7c478bd9Sstevel@tonic-gate fval = (float)strtod(val, &endptr); 493*7c478bd9Sstevel@tonic-gate if (endptr != (val + strlen(val))) 494*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 495*7c478bd9Sstevel@tonic-gate (void) memcpy(outbuf, &fval, size); 496*7c478bd9Sstevel@tonic-gate break; 497*7c478bd9Sstevel@tonic-gate default: /* invalid size */ 498*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 499*7c478bd9Sstevel@tonic-gate } 500*7c478bd9Sstevel@tonic-gate break; 501*7c478bd9Sstevel@tonic-gate default: /* not supported type */ 502*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate /* 509*7c478bd9Sstevel@tonic-gate * free prop_cmd_t 510*7c478bd9Sstevel@tonic-gate */ 511*7c478bd9Sstevel@tonic-gate static void 512*7c478bd9Sstevel@tonic-gate free_prop(command_t *command) 513*7c478bd9Sstevel@tonic-gate { 514*7c478bd9Sstevel@tonic-gate free(command->propcmd_pname); 515*7c478bd9Sstevel@tonic-gate if (command->propcmd_type != PICL_PTYPE_VOID) 516*7c478bd9Sstevel@tonic-gate free(command->propcmd_valbuf); 517*7c478bd9Sstevel@tonic-gate } 518*7c478bd9Sstevel@tonic-gate 519*7c478bd9Sstevel@tonic-gate /* 520*7c478bd9Sstevel@tonic-gate * return the string token in two double quotes 521*7c478bd9Sstevel@tonic-gate * The current version won't support multiple-line string 522*7c478bd9Sstevel@tonic-gate */ 523*7c478bd9Sstevel@tonic-gate static int 524*7c478bd9Sstevel@tonic-gate get_string_token(char *line, char **valtok) 525*7c478bd9Sstevel@tonic-gate { 526*7c478bd9Sstevel@tonic-gate char *optr; /* ptr to the open quote */ 527*7c478bd9Sstevel@tonic-gate char *cptr; /* ptr to the close quote */ 528*7c478bd9Sstevel@tonic-gate char *ptr; 529*7c478bd9Sstevel@tonic-gate char *tmpbuf; 530*7c478bd9Sstevel@tonic-gate 531*7c478bd9Sstevel@tonic-gate if (line == NULL) 532*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 533*7c478bd9Sstevel@tonic-gate 534*7c478bd9Sstevel@tonic-gate /* skipping leading white spaces */ 535*7c478bd9Sstevel@tonic-gate optr = line; 536*7c478bd9Sstevel@tonic-gate while ((*optr == ' ') || (*optr == '\t') || (*optr == '\n')) 537*7c478bd9Sstevel@tonic-gate optr++; 538*7c478bd9Sstevel@tonic-gate 539*7c478bd9Sstevel@tonic-gate /* reach end of string */ 540*7c478bd9Sstevel@tonic-gate if (*optr == '\0') 541*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate /* it's not an open double quote */ 544*7c478bd9Sstevel@tonic-gate if (*optr != '"') 545*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 546*7c478bd9Sstevel@tonic-gate 547*7c478bd9Sstevel@tonic-gate /* skipping ending white spaces */ 548*7c478bd9Sstevel@tonic-gate cptr = line + strlen(line) - 1; 549*7c478bd9Sstevel@tonic-gate while ((*cptr == ' ') || (*cptr == '\t') || (*cptr == '\n')) 550*7c478bd9Sstevel@tonic-gate cptr--; 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate /* it's not an close double quote */ 553*7c478bd9Sstevel@tonic-gate if (*cptr != '"') 554*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 555*7c478bd9Sstevel@tonic-gate 556*7c478bd9Sstevel@tonic-gate /* close double quote is missing */ 557*7c478bd9Sstevel@tonic-gate if (cptr == optr) 558*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 559*7c478bd9Sstevel@tonic-gate 560*7c478bd9Sstevel@tonic-gate /* replace close qoute by null to make a string */ 561*7c478bd9Sstevel@tonic-gate *cptr = '\0'; 562*7c478bd9Sstevel@tonic-gate /* move the begin pointer to the first char of string */ 563*7c478bd9Sstevel@tonic-gate optr++; 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate tmpbuf = malloc(strlen(optr) + 1); 566*7c478bd9Sstevel@tonic-gate if (tmpbuf == NULL) 567*7c478bd9Sstevel@tonic-gate return (EC_FAILURE); 568*7c478bd9Sstevel@tonic-gate 569*7c478bd9Sstevel@tonic-gate for (ptr = tmpbuf; *optr != '\0'; ptr++, optr++) { 570*7c478bd9Sstevel@tonic-gate /* if escape character, go to next character */ 571*7c478bd9Sstevel@tonic-gate if (*optr == '\\') { 572*7c478bd9Sstevel@tonic-gate optr++; 573*7c478bd9Sstevel@tonic-gate if (*optr == '\0') { /* for exampe, "xxx\" */ 574*7c478bd9Sstevel@tonic-gate free(tmpbuf); 575*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 576*7c478bd9Sstevel@tonic-gate } 577*7c478bd9Sstevel@tonic-gate } 578*7c478bd9Sstevel@tonic-gate *ptr = *optr; 579*7c478bd9Sstevel@tonic-gate } 580*7c478bd9Sstevel@tonic-gate 581*7c478bd9Sstevel@tonic-gate *ptr = '\0'; 582*7c478bd9Sstevel@tonic-gate *valtok = tmpbuf; 583*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 584*7c478bd9Sstevel@tonic-gate } 585*7c478bd9Sstevel@tonic-gate 586*7c478bd9Sstevel@tonic-gate /* 587*7c478bd9Sstevel@tonic-gate * Check the PROP syntax 588*7c478bd9Sstevel@tonic-gate * PROP <name> <type> <access_mode> [<size> <value>] 589*7c478bd9Sstevel@tonic-gate * supported prop types: void, int, uint, float, string 590*7c478bd9Sstevel@tonic-gate * supported prop access_modes: r, w, rw 591*7c478bd9Sstevel@tonic-gate * For void prop, <size> and <value> are not needed 592*7c478bd9Sstevel@tonic-gate * For string prop, <size> will be set the actual string size if <size> 593*7c478bd9Sstevel@tonic-gate * is 0 594*7c478bd9Sstevel@tonic-gate */ 595*7c478bd9Sstevel@tonic-gate static int 596*7c478bd9Sstevel@tonic-gate parse_prop(char *line, command_t *command) 597*7c478bd9Sstevel@tonic-gate { 598*7c478bd9Sstevel@tonic-gate char *tok; 599*7c478bd9Sstevel@tonic-gate char *pnametok; 600*7c478bd9Sstevel@tonic-gate int typetok; 601*7c478bd9Sstevel@tonic-gate size_t sizetok; 602*7c478bd9Sstevel@tonic-gate int modetok; 603*7c478bd9Sstevel@tonic-gate char *valtok; 604*7c478bd9Sstevel@tonic-gate char *last; 605*7c478bd9Sstevel@tonic-gate char *endptr; 606*7c478bd9Sstevel@tonic-gate int err; 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate /* get the PROP directive */ 609*7c478bd9Sstevel@tonic-gate tok = strtok_r(line, WHITESPACE, &last); 610*7c478bd9Sstevel@tonic-gate if (tok == NULL) 611*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 612*7c478bd9Sstevel@tonic-gate 613*7c478bd9Sstevel@tonic-gate /* get the property name */ 614*7c478bd9Sstevel@tonic-gate pnametok = strtok_r(last, WHITESPACE, &last); 615*7c478bd9Sstevel@tonic-gate if (pnametok == NULL) 616*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate /* get the type */ 619*7c478bd9Sstevel@tonic-gate tok = strtok_r(last, WHITESPACE, &last); 620*7c478bd9Sstevel@tonic-gate if (tok == NULL) 621*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 622*7c478bd9Sstevel@tonic-gate 623*7c478bd9Sstevel@tonic-gate if ((typetok = getpicltype(tok)) < 0) 624*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate /* get mode */ 627*7c478bd9Sstevel@tonic-gate tok = strtok_r(last, WHITESPACE, &last); 628*7c478bd9Sstevel@tonic-gate if (tok == NULL) 629*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 630*7c478bd9Sstevel@tonic-gate 631*7c478bd9Sstevel@tonic-gate if ((modetok = getpiclmode(tok)) < 0) 632*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate if (typetok == PICL_PTYPE_VOID) { 635*7c478bd9Sstevel@tonic-gate /* ignore the rest of arguments */ 636*7c478bd9Sstevel@tonic-gate command->propcmd_valbuf = NULL; 637*7c478bd9Sstevel@tonic-gate command->propcmd_pname = strdup(pnametok); 638*7c478bd9Sstevel@tonic-gate if (command->propcmd_pname == NULL) 639*7c478bd9Sstevel@tonic-gate return (EC_FAILURE); 640*7c478bd9Sstevel@tonic-gate command->propcmd_type = typetok; 641*7c478bd9Sstevel@tonic-gate command->propcmd_accessmode = modetok; 642*7c478bd9Sstevel@tonic-gate command->propcmd_size = 0; 643*7c478bd9Sstevel@tonic-gate command->propcmd_proph = NULL; 644*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 645*7c478bd9Sstevel@tonic-gate } 646*7c478bd9Sstevel@tonic-gate 647*7c478bd9Sstevel@tonic-gate /* get size */ 648*7c478bd9Sstevel@tonic-gate tok = strtok_r(last, WHITESPACE, &last); 649*7c478bd9Sstevel@tonic-gate if (tok == NULL) 650*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 651*7c478bd9Sstevel@tonic-gate 652*7c478bd9Sstevel@tonic-gate sizetok = (size_t)strtol(tok, &endptr, 0); 653*7c478bd9Sstevel@tonic-gate if (endptr != (tok + strlen(tok))) 654*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate /* get val */ 657*7c478bd9Sstevel@tonic-gate if (typetok == PICL_PTYPE_CHARSTRING) { 658*7c478bd9Sstevel@tonic-gate err = get_string_token(last, &valtok); 659*7c478bd9Sstevel@tonic-gate if (err != EC_SYNTAX_OK) 660*7c478bd9Sstevel@tonic-gate return (err); 661*7c478bd9Sstevel@tonic-gate if (sizetok == 0) 662*7c478bd9Sstevel@tonic-gate sizetok = strlen(valtok) + 1; 663*7c478bd9Sstevel@tonic-gate command->propcmd_valbuf = valtok; 664*7c478bd9Sstevel@tonic-gate } else { 665*7c478bd9Sstevel@tonic-gate valtok = strtok_r(last, WHITESPACE, &last); 666*7c478bd9Sstevel@tonic-gate if (valtok == NULL) 667*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 668*7c478bd9Sstevel@tonic-gate /* check if more tokens */ 669*7c478bd9Sstevel@tonic-gate tok = strtok_r(last, WHITESPACE, &last); 670*7c478bd9Sstevel@tonic-gate if (tok != NULL) 671*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 672*7c478bd9Sstevel@tonic-gate command->propcmd_valbuf = malloc(sizetok); 673*7c478bd9Sstevel@tonic-gate if (command->propcmd_valbuf == NULL) 674*7c478bd9Sstevel@tonic-gate return (EC_FAILURE); 675*7c478bd9Sstevel@tonic-gate err = validate_size_and_cvt_val(command->propcmd_valbuf, 676*7c478bd9Sstevel@tonic-gate sizetok, typetok, valtok); 677*7c478bd9Sstevel@tonic-gate if (err != EC_SYNTAX_OK) { 678*7c478bd9Sstevel@tonic-gate free(command->propcmd_valbuf); 679*7c478bd9Sstevel@tonic-gate return (err); 680*7c478bd9Sstevel@tonic-gate } 681*7c478bd9Sstevel@tonic-gate } 682*7c478bd9Sstevel@tonic-gate 683*7c478bd9Sstevel@tonic-gate command->propcmd_pname = strdup(pnametok); 684*7c478bd9Sstevel@tonic-gate if (command->propcmd_pname == NULL) 685*7c478bd9Sstevel@tonic-gate return (EC_FAILURE); 686*7c478bd9Sstevel@tonic-gate command->propcmd_type = typetok; 687*7c478bd9Sstevel@tonic-gate command->propcmd_accessmode = modetok; 688*7c478bd9Sstevel@tonic-gate command->propcmd_size = sizetok; 689*7c478bd9Sstevel@tonic-gate command->propcmd_proph = NULL; 690*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 691*7c478bd9Sstevel@tonic-gate } 692*7c478bd9Sstevel@tonic-gate 693*7c478bd9Sstevel@tonic-gate /* 694*7c478bd9Sstevel@tonic-gate * Add a property to the row, the row gets added to the node at endrow 695*7c478bd9Sstevel@tonic-gate */ 696*7c478bd9Sstevel@tonic-gate static int 697*7c478bd9Sstevel@tonic-gate add_proph_to_row(command_t *command, picl_prophdl_t proph) 698*7c478bd9Sstevel@tonic-gate { 699*7c478bd9Sstevel@tonic-gate if (command->rowcmd_index >= command->rowcmd_nproph) 700*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 701*7c478bd9Sstevel@tonic-gate command->rowcmd_prophs[command->rowcmd_index] = proph; 702*7c478bd9Sstevel@tonic-gate command->rowcmd_index++; 703*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 704*7c478bd9Sstevel@tonic-gate } 705*7c478bd9Sstevel@tonic-gate 706*7c478bd9Sstevel@tonic-gate /* 707*7c478bd9Sstevel@tonic-gate * Process the PROP command and add the specified property under the given 708*7c478bd9Sstevel@tonic-gate * node handle 709*7c478bd9Sstevel@tonic-gate */ 710*7c478bd9Sstevel@tonic-gate static int 711*7c478bd9Sstevel@tonic-gate process_prop(cmdbuf_t *cmds, command_t *command, picl_nodehdl_t nodeh) 712*7c478bd9Sstevel@tonic-gate { 713*7c478bd9Sstevel@tonic-gate ptree_propinfo_t propinfo; 714*7c478bd9Sstevel@tonic-gate picl_prophdl_t proph; 715*7c478bd9Sstevel@tonic-gate int err; 716*7c478bd9Sstevel@tonic-gate 717*7c478bd9Sstevel@tonic-gate /* prop in discarded row */ 718*7c478bd9Sstevel@tonic-gate if (cmds->inside_row_block && 719*7c478bd9Sstevel@tonic-gate cmds->commands[cmds->current_row].rowcmd_nproph == 0) 720*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 721*7c478bd9Sstevel@tonic-gate 722*7c478bd9Sstevel@tonic-gate err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, 723*7c478bd9Sstevel@tonic-gate command->propcmd_type, command->propcmd_accessmode, 724*7c478bd9Sstevel@tonic-gate command->propcmd_size, command->propcmd_pname, NULL, 725*7c478bd9Sstevel@tonic-gate NULL); 726*7c478bd9Sstevel@tonic-gate 727*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 728*7c478bd9Sstevel@tonic-gate return (err); 729*7c478bd9Sstevel@tonic-gate 730*7c478bd9Sstevel@tonic-gate err = ptree_create_prop(&propinfo, command->propcmd_valbuf, &proph); 731*7c478bd9Sstevel@tonic-gate 732*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 733*7c478bd9Sstevel@tonic-gate return (err); 734*7c478bd9Sstevel@tonic-gate 735*7c478bd9Sstevel@tonic-gate command->propcmd_proph = proph; 736*7c478bd9Sstevel@tonic-gate 737*7c478bd9Sstevel@tonic-gate if (cmds->inside_row_block) { 738*7c478bd9Sstevel@tonic-gate err = add_proph_to_row(&cmds->commands[cmds->current_row], 739*7c478bd9Sstevel@tonic-gate proph); 740*7c478bd9Sstevel@tonic-gate } else { 741*7c478bd9Sstevel@tonic-gate err = ptree_add_prop(nodeh, proph); 742*7c478bd9Sstevel@tonic-gate } 743*7c478bd9Sstevel@tonic-gate 744*7c478bd9Sstevel@tonic-gate return (err); 745*7c478bd9Sstevel@tonic-gate } 746*7c478bd9Sstevel@tonic-gate 747*7c478bd9Sstevel@tonic-gate /* 748*7c478bd9Sstevel@tonic-gate * free refnode_cmd_t 749*7c478bd9Sstevel@tonic-gate */ 750*7c478bd9Sstevel@tonic-gate static void 751*7c478bd9Sstevel@tonic-gate free_refnode(command_t *command) 752*7c478bd9Sstevel@tonic-gate { 753*7c478bd9Sstevel@tonic-gate free(command->refnodecmd_name); 754*7c478bd9Sstevel@tonic-gate free(command->refnodecmd_class); 755*7c478bd9Sstevel@tonic-gate free(command->refnodecmd_dstnode); 756*7c478bd9Sstevel@tonic-gate } 757*7c478bd9Sstevel@tonic-gate 758*7c478bd9Sstevel@tonic-gate /* 759*7c478bd9Sstevel@tonic-gate * Check the REFNODE syntax 760*7c478bd9Sstevel@tonic-gate * 761*7c478bd9Sstevel@tonic-gate * REFNODE <name> <class> with <destnode> -- if <destnode> exists, 762*7c478bd9Sstevel@tonic-gate * create node with nodename <name> and piclclass <class> 763*7c478bd9Sstevel@tonic-gate */ 764*7c478bd9Sstevel@tonic-gate static int 765*7c478bd9Sstevel@tonic-gate parse_refnode(char *line, command_t *command) 766*7c478bd9Sstevel@tonic-gate { 767*7c478bd9Sstevel@tonic-gate char *tok; 768*7c478bd9Sstevel@tonic-gate char *dsttok; 769*7c478bd9Sstevel@tonic-gate char *classnm; 770*7c478bd9Sstevel@tonic-gate char *nodenm; 771*7c478bd9Sstevel@tonic-gate char *last; 772*7c478bd9Sstevel@tonic-gate 773*7c478bd9Sstevel@tonic-gate /* get the directive */ 774*7c478bd9Sstevel@tonic-gate tok = strtok_r(line, WHITESPACE, &last); 775*7c478bd9Sstevel@tonic-gate if (tok == NULL) 776*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate /* get the nodename */ 779*7c478bd9Sstevel@tonic-gate nodenm = strtok_r(last, WHITESPACE, &last); 780*7c478bd9Sstevel@tonic-gate if (nodenm == NULL) 781*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 782*7c478bd9Sstevel@tonic-gate 783*7c478bd9Sstevel@tonic-gate /* get the class */ 784*7c478bd9Sstevel@tonic-gate classnm = strtok_r(last, WHITESPACE, &last); 785*7c478bd9Sstevel@tonic-gate if (classnm == NULL) 786*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 787*7c478bd9Sstevel@tonic-gate 788*7c478bd9Sstevel@tonic-gate /* get the WITH keyword */ 789*7c478bd9Sstevel@tonic-gate tok = strtok_r(last, WHITESPACE, &last); 790*7c478bd9Sstevel@tonic-gate if (tok == NULL) 791*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 792*7c478bd9Sstevel@tonic-gate 793*7c478bd9Sstevel@tonic-gate if (strcasecmp(tok, KEYWORD_WITH_STR) != 0) 794*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gate /* get the dst node */ 797*7c478bd9Sstevel@tonic-gate dsttok = strtok_r(last, WHITESPACE, &last); 798*7c478bd9Sstevel@tonic-gate if (dsttok == NULL) 799*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 800*7c478bd9Sstevel@tonic-gate 801*7c478bd9Sstevel@tonic-gate /* check if more tokens */ 802*7c478bd9Sstevel@tonic-gate tok = strtok_r(last, WHITESPACE, &last); 803*7c478bd9Sstevel@tonic-gate if (tok != NULL) 804*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 805*7c478bd9Sstevel@tonic-gate 806*7c478bd9Sstevel@tonic-gate command->refnodecmd_name = strdup(nodenm); 807*7c478bd9Sstevel@tonic-gate command->refnodecmd_class = strdup(classnm); 808*7c478bd9Sstevel@tonic-gate command->refnodecmd_dstnode = strdup(dsttok); 809*7c478bd9Sstevel@tonic-gate command->refnodecmd_nodeh = NULL; 810*7c478bd9Sstevel@tonic-gate if ((command->refnodecmd_name == NULL) || 811*7c478bd9Sstevel@tonic-gate (command->refnodecmd_class == NULL) || 812*7c478bd9Sstevel@tonic-gate (command->refnodecmd_dstnode == NULL)) 813*7c478bd9Sstevel@tonic-gate return (EC_FAILURE); 814*7c478bd9Sstevel@tonic-gate 815*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 816*7c478bd9Sstevel@tonic-gate } 817*7c478bd9Sstevel@tonic-gate 818*7c478bd9Sstevel@tonic-gate /* 819*7c478bd9Sstevel@tonic-gate * Process the REFNODE command 820*7c478bd9Sstevel@tonic-gate */ 821*7c478bd9Sstevel@tonic-gate static int 822*7c478bd9Sstevel@tonic-gate process_refnode(command_t *command, picl_nodehdl_t parh) 823*7c478bd9Sstevel@tonic-gate { 824*7c478bd9Sstevel@tonic-gate picl_nodehdl_t dsth; 825*7c478bd9Sstevel@tonic-gate picl_nodehdl_t nodeh; 826*7c478bd9Sstevel@tonic-gate int err; 827*7c478bd9Sstevel@tonic-gate 828*7c478bd9Sstevel@tonic-gate if ((ptree_get_node_by_path(command->refnodecmd_dstnode, 829*7c478bd9Sstevel@tonic-gate &dsth) == PICL_SUCCESS)) { 830*7c478bd9Sstevel@tonic-gate err = ptree_create_and_add_node(parh, command->refnodecmd_name, 831*7c478bd9Sstevel@tonic-gate command->refnodecmd_class, &nodeh); 832*7c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS) 833*7c478bd9Sstevel@tonic-gate command->refnodecmd_nodeh = nodeh; 834*7c478bd9Sstevel@tonic-gate 835*7c478bd9Sstevel@tonic-gate return (err); 836*7c478bd9Sstevel@tonic-gate } 837*7c478bd9Sstevel@tonic-gate 838*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 839*7c478bd9Sstevel@tonic-gate } 840*7c478bd9Sstevel@tonic-gate 841*7c478bd9Sstevel@tonic-gate /* 842*7c478bd9Sstevel@tonic-gate * free refprop_cmd_t 843*7c478bd9Sstevel@tonic-gate */ 844*7c478bd9Sstevel@tonic-gate static void 845*7c478bd9Sstevel@tonic-gate free_refprop(command_t *command) 846*7c478bd9Sstevel@tonic-gate { 847*7c478bd9Sstevel@tonic-gate free(command->refpropcmd_pname); 848*7c478bd9Sstevel@tonic-gate free(command->refpropcmd_dstnode); 849*7c478bd9Sstevel@tonic-gate } 850*7c478bd9Sstevel@tonic-gate 851*7c478bd9Sstevel@tonic-gate /* 852*7c478bd9Sstevel@tonic-gate * Check the REFPROP syntax 853*7c478bd9Sstevel@tonic-gate * 854*7c478bd9Sstevel@tonic-gate * REFPROP <prop> <destnode> -- creates a reference property to <destnode> 855*7c478bd9Sstevel@tonic-gate */ 856*7c478bd9Sstevel@tonic-gate static int 857*7c478bd9Sstevel@tonic-gate parse_refprop(char *line, command_t *command) 858*7c478bd9Sstevel@tonic-gate { 859*7c478bd9Sstevel@tonic-gate char *tok; 860*7c478bd9Sstevel@tonic-gate char *pnametok; 861*7c478bd9Sstevel@tonic-gate char *dsttok; 862*7c478bd9Sstevel@tonic-gate char *last; 863*7c478bd9Sstevel@tonic-gate 864*7c478bd9Sstevel@tonic-gate /* get the REFPROP directive */ 865*7c478bd9Sstevel@tonic-gate tok = strtok_r(line, WHITESPACE, &last); 866*7c478bd9Sstevel@tonic-gate if (tok == NULL) 867*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 868*7c478bd9Sstevel@tonic-gate 869*7c478bd9Sstevel@tonic-gate /* get the propname */ 870*7c478bd9Sstevel@tonic-gate pnametok = strtok_r(last, WHITESPACE, &last); 871*7c478bd9Sstevel@tonic-gate if (pnametok == NULL) 872*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 873*7c478bd9Sstevel@tonic-gate 874*7c478bd9Sstevel@tonic-gate dsttok = strtok_r(last, WHITESPACE, &last); 875*7c478bd9Sstevel@tonic-gate if (dsttok == NULL) 876*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate /* check if more tokens */ 879*7c478bd9Sstevel@tonic-gate tok = strtok_r(last, WHITESPACE, &last); 880*7c478bd9Sstevel@tonic-gate if (tok != NULL) 881*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 882*7c478bd9Sstevel@tonic-gate 883*7c478bd9Sstevel@tonic-gate command->refpropcmd_pname = strdup(pnametok); 884*7c478bd9Sstevel@tonic-gate command->refpropcmd_dstnode = strdup(dsttok); 885*7c478bd9Sstevel@tonic-gate command->refpropcmd_proph = NULL; 886*7c478bd9Sstevel@tonic-gate if ((command->refpropcmd_pname == NULL) || 887*7c478bd9Sstevel@tonic-gate (command->refpropcmd_dstnode == NULL)) 888*7c478bd9Sstevel@tonic-gate return (EC_FAILURE); 889*7c478bd9Sstevel@tonic-gate 890*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 891*7c478bd9Sstevel@tonic-gate } 892*7c478bd9Sstevel@tonic-gate 893*7c478bd9Sstevel@tonic-gate /* 894*7c478bd9Sstevel@tonic-gate * Process the REFPROP command 895*7c478bd9Sstevel@tonic-gate */ 896*7c478bd9Sstevel@tonic-gate static int 897*7c478bd9Sstevel@tonic-gate process_refprop(cmdbuf_t *cmds, command_t *command, picl_nodehdl_t nodeh) 898*7c478bd9Sstevel@tonic-gate { 899*7c478bd9Sstevel@tonic-gate int err; 900*7c478bd9Sstevel@tonic-gate picl_nodehdl_t dsth; 901*7c478bd9Sstevel@tonic-gate picl_prophdl_t proph; 902*7c478bd9Sstevel@tonic-gate ptree_propinfo_t propinfo; 903*7c478bd9Sstevel@tonic-gate 904*7c478bd9Sstevel@tonic-gate /* refprop in discarded row */ 905*7c478bd9Sstevel@tonic-gate if (cmds->inside_row_block && 906*7c478bd9Sstevel@tonic-gate cmds->commands[cmds->current_row].rowcmd_nproph == 0) 907*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 908*7c478bd9Sstevel@tonic-gate 909*7c478bd9Sstevel@tonic-gate /* try finding the refprop's dstnode */ 910*7c478bd9Sstevel@tonic-gate err = ptree_get_node_by_path(command->refpropcmd_dstnode, &dsth); 911*7c478bd9Sstevel@tonic-gate 912*7c478bd9Sstevel@tonic-gate /* dstnode doesn't exist, return */ 913*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 914*7c478bd9Sstevel@tonic-gate return (err); 915*7c478bd9Sstevel@tonic-gate 916*7c478bd9Sstevel@tonic-gate /* dstnode exists, try adding the refprop to nodeh */ 917*7c478bd9Sstevel@tonic-gate err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, 918*7c478bd9Sstevel@tonic-gate PICL_PTYPE_REFERENCE, PICL_READ, sizeof (picl_nodehdl_t), 919*7c478bd9Sstevel@tonic-gate command->refpropcmd_pname, NULL, NULL); 920*7c478bd9Sstevel@tonic-gate 921*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 922*7c478bd9Sstevel@tonic-gate return (err); 923*7c478bd9Sstevel@tonic-gate 924*7c478bd9Sstevel@tonic-gate err = ptree_create_prop(&propinfo, &dsth, &proph); 925*7c478bd9Sstevel@tonic-gate 926*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 927*7c478bd9Sstevel@tonic-gate return (err); 928*7c478bd9Sstevel@tonic-gate 929*7c478bd9Sstevel@tonic-gate command->refpropcmd_proph = proph; 930*7c478bd9Sstevel@tonic-gate 931*7c478bd9Sstevel@tonic-gate if (cmds->inside_row_block) { 932*7c478bd9Sstevel@tonic-gate err = add_proph_to_row(&cmds->commands[cmds->current_row], 933*7c478bd9Sstevel@tonic-gate proph); 934*7c478bd9Sstevel@tonic-gate } else { 935*7c478bd9Sstevel@tonic-gate err = ptree_add_prop(nodeh, proph); 936*7c478bd9Sstevel@tonic-gate } 937*7c478bd9Sstevel@tonic-gate 938*7c478bd9Sstevel@tonic-gate return (err); 939*7c478bd9Sstevel@tonic-gate } 940*7c478bd9Sstevel@tonic-gate 941*7c478bd9Sstevel@tonic-gate /* 942*7c478bd9Sstevel@tonic-gate * free table_cmd_t 943*7c478bd9Sstevel@tonic-gate */ 944*7c478bd9Sstevel@tonic-gate static void 945*7c478bd9Sstevel@tonic-gate free_table(command_t *command) 946*7c478bd9Sstevel@tonic-gate { 947*7c478bd9Sstevel@tonic-gate if (command->tablecmd_tname) 948*7c478bd9Sstevel@tonic-gate free(command->tablecmd_tname); 949*7c478bd9Sstevel@tonic-gate } 950*7c478bd9Sstevel@tonic-gate 951*7c478bd9Sstevel@tonic-gate /* 952*7c478bd9Sstevel@tonic-gate * Check the TABLE syntax 953*7c478bd9Sstevel@tonic-gate * TABLE <table_prop_name> 954*7c478bd9Sstevel@tonic-gate * 955*7c478bd9Sstevel@tonic-gate */ 956*7c478bd9Sstevel@tonic-gate static int 957*7c478bd9Sstevel@tonic-gate parse_table(char *line, command_t *command) 958*7c478bd9Sstevel@tonic-gate { 959*7c478bd9Sstevel@tonic-gate char *tok = NULL; 960*7c478bd9Sstevel@tonic-gate char *tnametok = NULL; 961*7c478bd9Sstevel@tonic-gate char *last = NULL; 962*7c478bd9Sstevel@tonic-gate 963*7c478bd9Sstevel@tonic-gate /* get the TABLE directive */ 964*7c478bd9Sstevel@tonic-gate tok = strtok_r(line, WHITESPACE, &last); 965*7c478bd9Sstevel@tonic-gate if (tok == NULL) 966*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 967*7c478bd9Sstevel@tonic-gate 968*7c478bd9Sstevel@tonic-gate /* get the property name */ 969*7c478bd9Sstevel@tonic-gate tnametok = strtok_r(last, WHITESPACE, &last); 970*7c478bd9Sstevel@tonic-gate if (tnametok == NULL) 971*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 972*7c478bd9Sstevel@tonic-gate 973*7c478bd9Sstevel@tonic-gate command->tablecmd_tname = strdup(tnametok); 974*7c478bd9Sstevel@tonic-gate if (command->tablecmd_tname == NULL) 975*7c478bd9Sstevel@tonic-gate return (EC_FAILURE); 976*7c478bd9Sstevel@tonic-gate 977*7c478bd9Sstevel@tonic-gate command->tablecmd_newtbl = 0; 978*7c478bd9Sstevel@tonic-gate command->tablecmd_tblh = NULL; 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 981*7c478bd9Sstevel@tonic-gate } 982*7c478bd9Sstevel@tonic-gate 983*7c478bd9Sstevel@tonic-gate /* 984*7c478bd9Sstevel@tonic-gate * Process the TABLE command and add the specified property under the given 985*7c478bd9Sstevel@tonic-gate * node handle 986*7c478bd9Sstevel@tonic-gate */ 987*7c478bd9Sstevel@tonic-gate static int 988*7c478bd9Sstevel@tonic-gate process_table(command_t *command, picl_nodehdl_t nodeh) 989*7c478bd9Sstevel@tonic-gate { 990*7c478bd9Sstevel@tonic-gate int err; 991*7c478bd9Sstevel@tonic-gate picl_prophdl_t tblh; 992*7c478bd9Sstevel@tonic-gate picl_prophdl_t proph; 993*7c478bd9Sstevel@tonic-gate ptree_propinfo_t propinfo; 994*7c478bd9Sstevel@tonic-gate 995*7c478bd9Sstevel@tonic-gate /* find if table already exists */ 996*7c478bd9Sstevel@tonic-gate err = ptree_get_prop_by_name(nodeh, command->tablecmd_tname, &tblh); 997*7c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS) { 998*7c478bd9Sstevel@tonic-gate err = ptree_get_propinfo(tblh, &propinfo); 999*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 1000*7c478bd9Sstevel@tonic-gate return (err); 1001*7c478bd9Sstevel@tonic-gate /* prop with the same name as table? */ 1002*7c478bd9Sstevel@tonic-gate if (propinfo.piclinfo.type != PICL_PTYPE_TABLE) 1003*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 1004*7c478bd9Sstevel@tonic-gate command->tablecmd_newtbl = 0; 1005*7c478bd9Sstevel@tonic-gate command->tablecmd_tblh = tblh; 1006*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1007*7c478bd9Sstevel@tonic-gate } 1008*7c478bd9Sstevel@tonic-gate 1009*7c478bd9Sstevel@tonic-gate /* init and create a new table */ 1010*7c478bd9Sstevel@tonic-gate err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, 1011*7c478bd9Sstevel@tonic-gate PICL_PTYPE_TABLE, PICL_READ|PICL_WRITE, 1012*7c478bd9Sstevel@tonic-gate sizeof (picl_prophdl_t), command->tablecmd_tname, NULL, NULL); 1013*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 1014*7c478bd9Sstevel@tonic-gate return (err); 1015*7c478bd9Sstevel@tonic-gate 1016*7c478bd9Sstevel@tonic-gate err = ptree_create_table(&tblh); 1017*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 1018*7c478bd9Sstevel@tonic-gate return (err); 1019*7c478bd9Sstevel@tonic-gate 1020*7c478bd9Sstevel@tonic-gate command->tablecmd_newtbl = 1; 1021*7c478bd9Sstevel@tonic-gate command->tablecmd_tblh = tblh; 1022*7c478bd9Sstevel@tonic-gate 1023*7c478bd9Sstevel@tonic-gate err = ptree_create_prop(&propinfo, &tblh, &proph); 1024*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 1025*7c478bd9Sstevel@tonic-gate return (err); 1026*7c478bd9Sstevel@tonic-gate 1027*7c478bd9Sstevel@tonic-gate err = ptree_add_prop(nodeh, proph); 1028*7c478bd9Sstevel@tonic-gate 1029*7c478bd9Sstevel@tonic-gate return (err); 1030*7c478bd9Sstevel@tonic-gate } 1031*7c478bd9Sstevel@tonic-gate 1032*7c478bd9Sstevel@tonic-gate /* 1033*7c478bd9Sstevel@tonic-gate * Process the ROW command by alloc'ing space to store the prop handles for 1034*7c478bd9Sstevel@tonic-gate * the whole row. The number of props in the row gets known while parsing. 1035*7c478bd9Sstevel@tonic-gate */ 1036*7c478bd9Sstevel@tonic-gate static int 1037*7c478bd9Sstevel@tonic-gate process_row(command_t *command) 1038*7c478bd9Sstevel@tonic-gate { 1039*7c478bd9Sstevel@tonic-gate command->rowcmd_index = 0; 1040*7c478bd9Sstevel@tonic-gate command->rowcmd_prophs = 1041*7c478bd9Sstevel@tonic-gate malloc(command->rowcmd_nproph * sizeof (picl_prophdl_t)); 1042*7c478bd9Sstevel@tonic-gate 1043*7c478bd9Sstevel@tonic-gate if (command->rowcmd_prophs == NULL) 1044*7c478bd9Sstevel@tonic-gate return (PICL_FAILURE); 1045*7c478bd9Sstevel@tonic-gate 1046*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1047*7c478bd9Sstevel@tonic-gate } 1048*7c478bd9Sstevel@tonic-gate 1049*7c478bd9Sstevel@tonic-gate /* 1050*7c478bd9Sstevel@tonic-gate * Process the ENDROW command. If a valid row, add the row to the ptree. 1051*7c478bd9Sstevel@tonic-gate */ 1052*7c478bd9Sstevel@tonic-gate static int 1053*7c478bd9Sstevel@tonic-gate process_endrow(cmdbuf_t *cmds) 1054*7c478bd9Sstevel@tonic-gate { 1055*7c478bd9Sstevel@tonic-gate int err; 1056*7c478bd9Sstevel@tonic-gate int i; 1057*7c478bd9Sstevel@tonic-gate command_t *curr_row; 1058*7c478bd9Sstevel@tonic-gate 1059*7c478bd9Sstevel@tonic-gate curr_row = &cmds->commands[cmds->current_row]; 1060*7c478bd9Sstevel@tonic-gate 1061*7c478bd9Sstevel@tonic-gate /* if nproph == 0, some row prop had problems, don't add */ 1062*7c478bd9Sstevel@tonic-gate if (curr_row->rowcmd_nproph == 0) { 1063*7c478bd9Sstevel@tonic-gate for (i = 0; i < curr_row->rowcmd_index; i++) { 1064*7c478bd9Sstevel@tonic-gate (void) ptree_delete_prop(curr_row->rowcmd_prophs[i]); 1065*7c478bd9Sstevel@tonic-gate (void) ptree_destroy_prop(curr_row->rowcmd_prophs[i]); 1066*7c478bd9Sstevel@tonic-gate } 1067*7c478bd9Sstevel@tonic-gate err = PICL_SUCCESS; 1068*7c478bd9Sstevel@tonic-gate } else 1069*7c478bd9Sstevel@tonic-gate err = ptree_add_row_to_table( 1070*7c478bd9Sstevel@tonic-gate cmds->commands[cmds->current_tbl].tablecmd_tblh, 1071*7c478bd9Sstevel@tonic-gate curr_row->rowcmd_nproph, 1072*7c478bd9Sstevel@tonic-gate curr_row->rowcmd_prophs); 1073*7c478bd9Sstevel@tonic-gate 1074*7c478bd9Sstevel@tonic-gate /* let go the space alloc'd in process_row */ 1075*7c478bd9Sstevel@tonic-gate free(curr_row->rowcmd_prophs); 1076*7c478bd9Sstevel@tonic-gate curr_row->rowcmd_prophs = NULL; 1077*7c478bd9Sstevel@tonic-gate 1078*7c478bd9Sstevel@tonic-gate return (err); 1079*7c478bd9Sstevel@tonic-gate } 1080*7c478bd9Sstevel@tonic-gate 1081*7c478bd9Sstevel@tonic-gate /* 1082*7c478bd9Sstevel@tonic-gate * Check the VERBOSE syntax 1083*7c478bd9Sstevel@tonic-gate * VERBOSE <level> 1084*7c478bd9Sstevel@tonic-gate */ 1085*7c478bd9Sstevel@tonic-gate static int 1086*7c478bd9Sstevel@tonic-gate parse_verbose(cmdbuf_t *cmds, char *line, command_t *command) 1087*7c478bd9Sstevel@tonic-gate { 1088*7c478bd9Sstevel@tonic-gate char *tok; 1089*7c478bd9Sstevel@tonic-gate char *level; 1090*7c478bd9Sstevel@tonic-gate char *last; 1091*7c478bd9Sstevel@tonic-gate char *endptr; 1092*7c478bd9Sstevel@tonic-gate int verbose_level; 1093*7c478bd9Sstevel@tonic-gate 1094*7c478bd9Sstevel@tonic-gate /* get the VERBOSE directive */ 1095*7c478bd9Sstevel@tonic-gate tok = strtok_r(line, WHITESPACE, &last); 1096*7c478bd9Sstevel@tonic-gate if (tok == NULL) 1097*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 1098*7c478bd9Sstevel@tonic-gate 1099*7c478bd9Sstevel@tonic-gate /* get verbose level */ 1100*7c478bd9Sstevel@tonic-gate level = strtok_r(last, WHITESPACE, &last); 1101*7c478bd9Sstevel@tonic-gate if (level == NULL) 1102*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 1103*7c478bd9Sstevel@tonic-gate verbose_level = strtol(level, &endptr, 0); 1104*7c478bd9Sstevel@tonic-gate if (endptr != (level + strlen(level))) 1105*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 1106*7c478bd9Sstevel@tonic-gate 1107*7c478bd9Sstevel@tonic-gate /* check if more tokens */ 1108*7c478bd9Sstevel@tonic-gate tok = strtok_r(last, WHITESPACE, &last); 1109*7c478bd9Sstevel@tonic-gate if (tok != NULL) 1110*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 1111*7c478bd9Sstevel@tonic-gate 1112*7c478bd9Sstevel@tonic-gate cmds->verbose = verbose_level; 1113*7c478bd9Sstevel@tonic-gate command->verbosecmd_level = verbose_level; 1114*7c478bd9Sstevel@tonic-gate 1115*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 1116*7c478bd9Sstevel@tonic-gate } 1117*7c478bd9Sstevel@tonic-gate 1118*7c478bd9Sstevel@tonic-gate /* 1119*7c478bd9Sstevel@tonic-gate * Process the VERBOSE command to set the verbose level 1120*7c478bd9Sstevel@tonic-gate */ 1121*7c478bd9Sstevel@tonic-gate static int 1122*7c478bd9Sstevel@tonic-gate process_verbose(cmdbuf_t *cmds, command_t *command) 1123*7c478bd9Sstevel@tonic-gate { 1124*7c478bd9Sstevel@tonic-gate cmds->verbose = command->verbosecmd_level; 1125*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1126*7c478bd9Sstevel@tonic-gate } 1127*7c478bd9Sstevel@tonic-gate 1128*7c478bd9Sstevel@tonic-gate /* 1129*7c478bd9Sstevel@tonic-gate * parse and tokenize the line 1130*7c478bd9Sstevel@tonic-gate */ 1131*7c478bd9Sstevel@tonic-gate static int 1132*7c478bd9Sstevel@tonic-gate parse_and_tokenize_line(cmdbuf_t *cmds, char *buf, command_t *command) 1133*7c478bd9Sstevel@tonic-gate { 1134*7c478bd9Sstevel@tonic-gate char rec[RECORD_SIZE_MAX]; 1135*7c478bd9Sstevel@tonic-gate char *tok; 1136*7c478bd9Sstevel@tonic-gate int err; 1137*7c478bd9Sstevel@tonic-gate char *last; 1138*7c478bd9Sstevel@tonic-gate int id; 1139*7c478bd9Sstevel@tonic-gate 1140*7c478bd9Sstevel@tonic-gate (void) strcpy(rec, buf); 1141*7c478bd9Sstevel@tonic-gate tok = strtok_r(rec, RECORD_WHITESPACE, &last); 1142*7c478bd9Sstevel@tonic-gate if (tok == NULL) 1143*7c478bd9Sstevel@tonic-gate return (EC_INSUFFICIENT_TOKEN); 1144*7c478bd9Sstevel@tonic-gate 1145*7c478bd9Sstevel@tonic-gate id = get_token_id(tok); 1146*7c478bd9Sstevel@tonic-gate 1147*7c478bd9Sstevel@tonic-gate (void) strcpy(rec, buf); 1148*7c478bd9Sstevel@tonic-gate 1149*7c478bd9Sstevel@tonic-gate switch (id) { 1150*7c478bd9Sstevel@tonic-gate case TOK_VERSION: 1151*7c478bd9Sstevel@tonic-gate err = parse_version(cmds, rec); 1152*7c478bd9Sstevel@tonic-gate break; 1153*7c478bd9Sstevel@tonic-gate case TOK_CLASSPATH: 1154*7c478bd9Sstevel@tonic-gate case TOK_NAMEPATH: 1155*7c478bd9Sstevel@tonic-gate if (cmds->inside_node_block != 0) 1156*7c478bd9Sstevel@tonic-gate return (EC_PATH_ERR); 1157*7c478bd9Sstevel@tonic-gate 1158*7c478bd9Sstevel@tonic-gate err = parse_path(rec, command); 1159*7c478bd9Sstevel@tonic-gate if (err != EC_SYNTAX_OK) 1160*7c478bd9Sstevel@tonic-gate return (err); 1161*7c478bd9Sstevel@tonic-gate break; 1162*7c478bd9Sstevel@tonic-gate case TOK_NODE: 1163*7c478bd9Sstevel@tonic-gate /* Check for NODE outside of TABLE, ROW */ 1164*7c478bd9Sstevel@tonic-gate if ((cmds->inside_table_block != 0) || 1165*7c478bd9Sstevel@tonic-gate (cmds->inside_row_block != 0)) 1166*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 1167*7c478bd9Sstevel@tonic-gate err = parse_node(rec, command); 1168*7c478bd9Sstevel@tonic-gate if (err != EC_SYNTAX_OK) 1169*7c478bd9Sstevel@tonic-gate return (err); 1170*7c478bd9Sstevel@tonic-gate cmds->inside_node_block++; 1171*7c478bd9Sstevel@tonic-gate break; 1172*7c478bd9Sstevel@tonic-gate case TOK_ENDNODE: 1173*7c478bd9Sstevel@tonic-gate /* Check for ENDNODE outside of TABLE, ROW */ 1174*7c478bd9Sstevel@tonic-gate if ((cmds->inside_table_block != 0) || 1175*7c478bd9Sstevel@tonic-gate (cmds->inside_row_block != 0)) 1176*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 1177*7c478bd9Sstevel@tonic-gate cmds->inside_node_block--; 1178*7c478bd9Sstevel@tonic-gate err = EC_SYNTAX_OK; 1179*7c478bd9Sstevel@tonic-gate break; 1180*7c478bd9Sstevel@tonic-gate case TOK_PROP: 1181*7c478bd9Sstevel@tonic-gate /* Check if inside TABLE, but not in ROW */ 1182*7c478bd9Sstevel@tonic-gate if ((cmds->inside_table_block != 0) && 1183*7c478bd9Sstevel@tonic-gate (cmds->inside_row_block == 0)) 1184*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 1185*7c478bd9Sstevel@tonic-gate err = parse_prop(rec, command); 1186*7c478bd9Sstevel@tonic-gate if (err != EC_SYNTAX_OK) 1187*7c478bd9Sstevel@tonic-gate return (err); 1188*7c478bd9Sstevel@tonic-gate if (cmds->inside_row_block) { 1189*7c478bd9Sstevel@tonic-gate cmds->commands[cmds->current_row].rowcmd_nproph++; 1190*7c478bd9Sstevel@tonic-gate } 1191*7c478bd9Sstevel@tonic-gate break; 1192*7c478bd9Sstevel@tonic-gate case TOK_REFNODE: 1193*7c478bd9Sstevel@tonic-gate err = parse_refnode(rec, command); 1194*7c478bd9Sstevel@tonic-gate if (err != EC_SYNTAX_OK) 1195*7c478bd9Sstevel@tonic-gate return (err); 1196*7c478bd9Sstevel@tonic-gate break; 1197*7c478bd9Sstevel@tonic-gate case TOK_REFPROP: 1198*7c478bd9Sstevel@tonic-gate /* Check if inside TABLE, but not in ROW */ 1199*7c478bd9Sstevel@tonic-gate if ((cmds->inside_table_block != 0) && 1200*7c478bd9Sstevel@tonic-gate (cmds->inside_row_block == 0)) 1201*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 1202*7c478bd9Sstevel@tonic-gate err = parse_refprop(rec, command); 1203*7c478bd9Sstevel@tonic-gate if (err != EC_SYNTAX_OK) 1204*7c478bd9Sstevel@tonic-gate return (err); 1205*7c478bd9Sstevel@tonic-gate if (cmds->inside_row_block) { 1206*7c478bd9Sstevel@tonic-gate cmds->commands[cmds->current_row].rowcmd_nproph++; 1207*7c478bd9Sstevel@tonic-gate } 1208*7c478bd9Sstevel@tonic-gate break; 1209*7c478bd9Sstevel@tonic-gate case TOK_TABLE: 1210*7c478bd9Sstevel@tonic-gate /* Table/Row supported in version 1.1 and above */ 1211*7c478bd9Sstevel@tonic-gate if (cmds->version_no < (float)SUPPORTED_VERSION_NUM) 1212*7c478bd9Sstevel@tonic-gate return (EC_UNSUPPORTED); 1213*7c478bd9Sstevel@tonic-gate if (cmds->inside_table_block != 0) 1214*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 1215*7c478bd9Sstevel@tonic-gate err = parse_table(rec, command); 1216*7c478bd9Sstevel@tonic-gate if (err != EC_SYNTAX_OK) 1217*7c478bd9Sstevel@tonic-gate return (err); 1218*7c478bd9Sstevel@tonic-gate cmds->inside_table_block = 1; 1219*7c478bd9Sstevel@tonic-gate break; 1220*7c478bd9Sstevel@tonic-gate case TOK_ENDTABLE: 1221*7c478bd9Sstevel@tonic-gate /* Check for ENDTABLE before TABLE */ 1222*7c478bd9Sstevel@tonic-gate if (cmds->inside_table_block == 0) 1223*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 1224*7c478bd9Sstevel@tonic-gate 1225*7c478bd9Sstevel@tonic-gate cmds->inside_table_block = 0; 1226*7c478bd9Sstevel@tonic-gate 1227*7c478bd9Sstevel@tonic-gate break; 1228*7c478bd9Sstevel@tonic-gate case TOK_ROW: 1229*7c478bd9Sstevel@tonic-gate /* Check for ROW outside of TABLE, ROW inside ROW */ 1230*7c478bd9Sstevel@tonic-gate if ((cmds->inside_table_block == 0) || 1231*7c478bd9Sstevel@tonic-gate (cmds->inside_row_block != 0)) 1232*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 1233*7c478bd9Sstevel@tonic-gate cmds->inside_row_block = 1; 1234*7c478bd9Sstevel@tonic-gate break; 1235*7c478bd9Sstevel@tonic-gate case TOK_ENDROW: 1236*7c478bd9Sstevel@tonic-gate /* Check for ENDROW outside of TABLE, ENDROW before ROW */ 1237*7c478bd9Sstevel@tonic-gate if ((cmds->inside_table_block == 0) || 1238*7c478bd9Sstevel@tonic-gate (cmds->inside_row_block == 0)) 1239*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 1240*7c478bd9Sstevel@tonic-gate else 1241*7c478bd9Sstevel@tonic-gate err = EC_SYNTAX_OK; 1242*7c478bd9Sstevel@tonic-gate 1243*7c478bd9Sstevel@tonic-gate cmds->inside_row_block = 0; 1244*7c478bd9Sstevel@tonic-gate 1245*7c478bd9Sstevel@tonic-gate /* error if row is empty */ 1246*7c478bd9Sstevel@tonic-gate if (cmds->commands[cmds->current_row].rowcmd_nproph <= 0) 1247*7c478bd9Sstevel@tonic-gate return (EC_ROW_EMPTY); 1248*7c478bd9Sstevel@tonic-gate break; 1249*7c478bd9Sstevel@tonic-gate case TOK_VERBOSE: 1250*7c478bd9Sstevel@tonic-gate err = parse_verbose(cmds, rec, command); 1251*7c478bd9Sstevel@tonic-gate if (err != EC_SYNTAX_OK) 1252*7c478bd9Sstevel@tonic-gate return (err); 1253*7c478bd9Sstevel@tonic-gate break; 1254*7c478bd9Sstevel@tonic-gate default: /* unsupported command */ 1255*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_ERR); 1256*7c478bd9Sstevel@tonic-gate } 1257*7c478bd9Sstevel@tonic-gate 1258*7c478bd9Sstevel@tonic-gate command->type = id; 1259*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 1260*7c478bd9Sstevel@tonic-gate } 1261*7c478bd9Sstevel@tonic-gate 1262*7c478bd9Sstevel@tonic-gate /* 1263*7c478bd9Sstevel@tonic-gate * Check the syntax and save the tokens in the commands buffer 1264*7c478bd9Sstevel@tonic-gate */ 1265*7c478bd9Sstevel@tonic-gate static int 1266*7c478bd9Sstevel@tonic-gate check_line_syntax(cmdbuf_t *cmds, char *buf) 1267*7c478bd9Sstevel@tonic-gate { 1268*7c478bd9Sstevel@tonic-gate int err; 1269*7c478bd9Sstevel@tonic-gate command_t command; 1270*7c478bd9Sstevel@tonic-gate 1271*7c478bd9Sstevel@tonic-gate (void) memset(&command, 0, sizeof (command_t)); 1272*7c478bd9Sstevel@tonic-gate err = parse_and_tokenize_line(cmds, buf, &command); 1273*7c478bd9Sstevel@tonic-gate if (err != EC_SYNTAX_OK) 1274*7c478bd9Sstevel@tonic-gate return (err); 1275*7c478bd9Sstevel@tonic-gate 1276*7c478bd9Sstevel@tonic-gate /* 1277*7c478bd9Sstevel@tonic-gate * don't add and count version command in the command buffer 1278*7c478bd9Sstevel@tonic-gate */ 1279*7c478bd9Sstevel@tonic-gate if (command.type == TOK_VERSION) 1280*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 1281*7c478bd9Sstevel@tonic-gate 1282*7c478bd9Sstevel@tonic-gate /* 1283*7c478bd9Sstevel@tonic-gate * check if the commands buffer has been filled 1284*7c478bd9Sstevel@tonic-gate * If it is full, reallocate the buffer. 1285*7c478bd9Sstevel@tonic-gate */ 1286*7c478bd9Sstevel@tonic-gate if (cmds->count == cmds->allocated) { 1287*7c478bd9Sstevel@tonic-gate cmds->commands = realloc(cmds->commands, 1288*7c478bd9Sstevel@tonic-gate sizeof (command_t) * (cmds->allocated + PER_ALLOC_COUNT)); 1289*7c478bd9Sstevel@tonic-gate if (cmds->commands == NULL) 1290*7c478bd9Sstevel@tonic-gate return (EC_FAILURE); 1291*7c478bd9Sstevel@tonic-gate cmds->allocated += PER_ALLOC_COUNT; 1292*7c478bd9Sstevel@tonic-gate } 1293*7c478bd9Sstevel@tonic-gate 1294*7c478bd9Sstevel@tonic-gate cmds->commands[cmds->count] = command; /* copy */ 1295*7c478bd9Sstevel@tonic-gate 1296*7c478bd9Sstevel@tonic-gate /* 1297*7c478bd9Sstevel@tonic-gate * make a note of the row/endrow command, to keep track of # of props 1298*7c478bd9Sstevel@tonic-gate */ 1299*7c478bd9Sstevel@tonic-gate if (command.type == TOK_ROW) 1300*7c478bd9Sstevel@tonic-gate cmds->current_row = cmds->count; 1301*7c478bd9Sstevel@tonic-gate 1302*7c478bd9Sstevel@tonic-gate if (command.type == TOK_ENDROW) 1303*7c478bd9Sstevel@tonic-gate cmds->current_row = 0; 1304*7c478bd9Sstevel@tonic-gate 1305*7c478bd9Sstevel@tonic-gate cmds->count++; 1306*7c478bd9Sstevel@tonic-gate 1307*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 1308*7c478bd9Sstevel@tonic-gate } 1309*7c478bd9Sstevel@tonic-gate 1310*7c478bd9Sstevel@tonic-gate /* 1311*7c478bd9Sstevel@tonic-gate * get the line control information 1312*7c478bd9Sstevel@tonic-gate * return 1 if it's the line control information, else return 0 1313*7c478bd9Sstevel@tonic-gate */ 1314*7c478bd9Sstevel@tonic-gate static int 1315*7c478bd9Sstevel@tonic-gate get_line_control_info(char *buf, uint32_t *linenum, char *filename) 1316*7c478bd9Sstevel@tonic-gate { 1317*7c478bd9Sstevel@tonic-gate char *ptr; 1318*7c478bd9Sstevel@tonic-gate char *last; 1319*7c478bd9Sstevel@tonic-gate uint32_t num; 1320*7c478bd9Sstevel@tonic-gate char *fname; 1321*7c478bd9Sstevel@tonic-gate char *endptr; 1322*7c478bd9Sstevel@tonic-gate 1323*7c478bd9Sstevel@tonic-gate /* skip # and get next string */ 1324*7c478bd9Sstevel@tonic-gate ptr = strtok_r(buf + 1, WHITESPACE, &last); 1325*7c478bd9Sstevel@tonic-gate if (ptr == NULL) { 1326*7c478bd9Sstevel@tonic-gate return (0); 1327*7c478bd9Sstevel@tonic-gate } 1328*7c478bd9Sstevel@tonic-gate 1329*7c478bd9Sstevel@tonic-gate num = strtoul(ptr, &endptr, 0); 1330*7c478bd9Sstevel@tonic-gate 1331*7c478bd9Sstevel@tonic-gate /* 1332*7c478bd9Sstevel@tonic-gate * It's not the line control information 1333*7c478bd9Sstevel@tonic-gate */ 1334*7c478bd9Sstevel@tonic-gate if (endptr != (ptr + strlen(ptr))) { 1335*7c478bd9Sstevel@tonic-gate return (0); 1336*7c478bd9Sstevel@tonic-gate } 1337*7c478bd9Sstevel@tonic-gate 1338*7c478bd9Sstevel@tonic-gate /* 1339*7c478bd9Sstevel@tonic-gate * get the filename 1340*7c478bd9Sstevel@tonic-gate */ 1341*7c478bd9Sstevel@tonic-gate 1342*7c478bd9Sstevel@tonic-gate /* get the beginning double quote */ 1343*7c478bd9Sstevel@tonic-gate last = strchr(last, '"'); 1344*7c478bd9Sstevel@tonic-gate if (last == NULL) 1345*7c478bd9Sstevel@tonic-gate return (0); 1346*7c478bd9Sstevel@tonic-gate 1347*7c478bd9Sstevel@tonic-gate last++; 1348*7c478bd9Sstevel@tonic-gate 1349*7c478bd9Sstevel@tonic-gate /* get the ending double quote */ 1350*7c478bd9Sstevel@tonic-gate fname = strtok_r(last, DOUBLE_QUOTE, &last); 1351*7c478bd9Sstevel@tonic-gate if (fname == NULL) 1352*7c478bd9Sstevel@tonic-gate return (0); 1353*7c478bd9Sstevel@tonic-gate 1354*7c478bd9Sstevel@tonic-gate *linenum = num; 1355*7c478bd9Sstevel@tonic-gate (void) strlcpy(filename, fname, PATH_MAX); 1356*7c478bd9Sstevel@tonic-gate return (1); 1357*7c478bd9Sstevel@tonic-gate } 1358*7c478bd9Sstevel@tonic-gate 1359*7c478bd9Sstevel@tonic-gate /* 1360*7c478bd9Sstevel@tonic-gate * check the syntax of the configuration file 1361*7c478bd9Sstevel@tonic-gate */ 1362*7c478bd9Sstevel@tonic-gate static int 1363*7c478bd9Sstevel@tonic-gate check_conffile_syntax(cmdbuf_t *cmds, FILE *fp) 1364*7c478bd9Sstevel@tonic-gate { 1365*7c478bd9Sstevel@tonic-gate char lbuf[RECORD_SIZE_MAX]; 1366*7c478bd9Sstevel@tonic-gate char buf[RECORD_SIZE_MAX]; 1367*7c478bd9Sstevel@tonic-gate uint32_t linenum; 1368*7c478bd9Sstevel@tonic-gate char cppfile[PATH_MAX] = ""; 1369*7c478bd9Sstevel@tonic-gate int err = EC_SYNTAX_OK; 1370*7c478bd9Sstevel@tonic-gate 1371*7c478bd9Sstevel@tonic-gate linenum = 0; 1372*7c478bd9Sstevel@tonic-gate while (fgets(buf, sizeof (buf), fp) != NULL) { 1373*7c478bd9Sstevel@tonic-gate /* 1374*7c478bd9Sstevel@tonic-gate * get cpp line control information, if any 1375*7c478bd9Sstevel@tonic-gate */ 1376*7c478bd9Sstevel@tonic-gate if (buf[0] == '#') { 1377*7c478bd9Sstevel@tonic-gate if (!get_line_control_info(buf, &linenum, cppfile)) 1378*7c478bd9Sstevel@tonic-gate ++linenum; 1379*7c478bd9Sstevel@tonic-gate continue; 1380*7c478bd9Sstevel@tonic-gate } 1381*7c478bd9Sstevel@tonic-gate 1382*7c478bd9Sstevel@tonic-gate ++linenum; 1383*7c478bd9Sstevel@tonic-gate /* 1384*7c478bd9Sstevel@tonic-gate * skip line whose first char is a newline char 1385*7c478bd9Sstevel@tonic-gate */ 1386*7c478bd9Sstevel@tonic-gate if (buf[0] == '\n') { 1387*7c478bd9Sstevel@tonic-gate continue; 1388*7c478bd9Sstevel@tonic-gate } 1389*7c478bd9Sstevel@tonic-gate 1390*7c478bd9Sstevel@tonic-gate if (err == EC_SYNTAX_OK) 1391*7c478bd9Sstevel@tonic-gate (void) strlcpy(lbuf, buf, RECORD_SIZE_MAX); 1392*7c478bd9Sstevel@tonic-gate else if (strlcat(lbuf, buf, RECORD_SIZE_MAX) >= 1393*7c478bd9Sstevel@tonic-gate RECORD_SIZE_MAX) { /* buffer overflow */ 1394*7c478bd9Sstevel@tonic-gate err = EC_FAILURE; 1395*7c478bd9Sstevel@tonic-gate break; 1396*7c478bd9Sstevel@tonic-gate } 1397*7c478bd9Sstevel@tonic-gate 1398*7c478bd9Sstevel@tonic-gate err = check_line_syntax(cmds, lbuf); 1399*7c478bd9Sstevel@tonic-gate if ((err != EC_INSUFFICIENT_TOKEN) && (err != EC_SYNTAX_OK)) 1400*7c478bd9Sstevel@tonic-gate break; 1401*7c478bd9Sstevel@tonic-gate } 1402*7c478bd9Sstevel@tonic-gate 1403*7c478bd9Sstevel@tonic-gate if (err != EC_SYNTAX_OK) { 1404*7c478bd9Sstevel@tonic-gate if (cmds->verbose) { 1405*7c478bd9Sstevel@tonic-gate verbose_log(LOG_ERR, err_msg[err], 1406*7c478bd9Sstevel@tonic-gate cmds->fname, cppfile, linenum); 1407*7c478bd9Sstevel@tonic-gate } 1408*7c478bd9Sstevel@tonic-gate return (err); 1409*7c478bd9Sstevel@tonic-gate } 1410*7c478bd9Sstevel@tonic-gate 1411*7c478bd9Sstevel@tonic-gate /* 1412*7c478bd9Sstevel@tonic-gate * check if the version has been set 1413*7c478bd9Sstevel@tonic-gate */ 1414*7c478bd9Sstevel@tonic-gate if (cmds->version_no > (float)SUPPORTED_VERSION_NUM) { 1415*7c478bd9Sstevel@tonic-gate if (cmds->verbose) { 1416*7c478bd9Sstevel@tonic-gate verbose_log(LOG_ERR, err_msg[EC_UNSUPPORTED], 1417*7c478bd9Sstevel@tonic-gate cmds->fname, cppfile, linenum); 1418*7c478bd9Sstevel@tonic-gate } 1419*7c478bd9Sstevel@tonic-gate return (EC_UNSUPPORTED); 1420*7c478bd9Sstevel@tonic-gate } 1421*7c478bd9Sstevel@tonic-gate 1422*7c478bd9Sstevel@tonic-gate /* 1423*7c478bd9Sstevel@tonic-gate * check if node and endnode command mismatch 1424*7c478bd9Sstevel@tonic-gate */ 1425*7c478bd9Sstevel@tonic-gate if (cmds->inside_node_block != 0) { 1426*7c478bd9Sstevel@tonic-gate if (cmds->verbose) { 1427*7c478bd9Sstevel@tonic-gate verbose_log(LOG_ERR, err_msg[EC_NODE_MISMATCH], 1428*7c478bd9Sstevel@tonic-gate cmds->fname, cppfile, linenum); 1429*7c478bd9Sstevel@tonic-gate } 1430*7c478bd9Sstevel@tonic-gate return (EC_NODE_MISMATCH); 1431*7c478bd9Sstevel@tonic-gate } 1432*7c478bd9Sstevel@tonic-gate 1433*7c478bd9Sstevel@tonic-gate /* 1434*7c478bd9Sstevel@tonic-gate * check if row and endrow command mismatch 1435*7c478bd9Sstevel@tonic-gate */ 1436*7c478bd9Sstevel@tonic-gate if (cmds->inside_row_block != 0) { 1437*7c478bd9Sstevel@tonic-gate if (cmds->verbose) { 1438*7c478bd9Sstevel@tonic-gate verbose_log(LOG_ERR, err_msg[EC_ROW_MISMATCH], 1439*7c478bd9Sstevel@tonic-gate cmds->fname, cppfile, linenum); 1440*7c478bd9Sstevel@tonic-gate } 1441*7c478bd9Sstevel@tonic-gate return (EC_ROW_MISMATCH); 1442*7c478bd9Sstevel@tonic-gate } 1443*7c478bd9Sstevel@tonic-gate 1444*7c478bd9Sstevel@tonic-gate /* 1445*7c478bd9Sstevel@tonic-gate * check if table and endtable command mismatch 1446*7c478bd9Sstevel@tonic-gate */ 1447*7c478bd9Sstevel@tonic-gate if (cmds->inside_table_block != 0) { 1448*7c478bd9Sstevel@tonic-gate if (cmds->verbose) { 1449*7c478bd9Sstevel@tonic-gate verbose_log(LOG_ERR, err_msg[EC_TABLE_MISMATCH], 1450*7c478bd9Sstevel@tonic-gate cmds->fname, cppfile, linenum); 1451*7c478bd9Sstevel@tonic-gate } 1452*7c478bd9Sstevel@tonic-gate return (EC_TABLE_MISMATCH); 1453*7c478bd9Sstevel@tonic-gate } 1454*7c478bd9Sstevel@tonic-gate 1455*7c478bd9Sstevel@tonic-gate return (EC_SYNTAX_OK); 1456*7c478bd9Sstevel@tonic-gate } 1457*7c478bd9Sstevel@tonic-gate 1458*7c478bd9Sstevel@tonic-gate /* 1459*7c478bd9Sstevel@tonic-gate * If classpath/namepath given is not found in the picl tree, 1460*7c478bd9Sstevel@tonic-gate * skip the whole blocks until next valid classpath or namepath 1461*7c478bd9Sstevel@tonic-gate */ 1462*7c478bd9Sstevel@tonic-gate static void 1463*7c478bd9Sstevel@tonic-gate skip_to_next_valid_path(cmdbuf_t *cmds, int starting_index, 1464*7c478bd9Sstevel@tonic-gate picl_nodehdl_t *parent, int *last_processed_index) 1465*7c478bd9Sstevel@tonic-gate { 1466*7c478bd9Sstevel@tonic-gate int err; 1467*7c478bd9Sstevel@tonic-gate int index; 1468*7c478bd9Sstevel@tonic-gate 1469*7c478bd9Sstevel@tonic-gate for (index = starting_index; index < cmds->count; ++index) { 1470*7c478bd9Sstevel@tonic-gate switch (cmds->commands[index].type) { 1471*7c478bd9Sstevel@tonic-gate case TOK_CLASSPATH: 1472*7c478bd9Sstevel@tonic-gate case TOK_NAMEPATH: 1473*7c478bd9Sstevel@tonic-gate err = process_path(&cmds->commands[index], parent); 1474*7c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS) { 1475*7c478bd9Sstevel@tonic-gate *last_processed_index = index; 1476*7c478bd9Sstevel@tonic-gate return; 1477*7c478bd9Sstevel@tonic-gate } 1478*7c478bd9Sstevel@tonic-gate default: 1479*7c478bd9Sstevel@tonic-gate /* skipped this line */ 1480*7c478bd9Sstevel@tonic-gate break; 1481*7c478bd9Sstevel@tonic-gate } 1482*7c478bd9Sstevel@tonic-gate } 1483*7c478bd9Sstevel@tonic-gate 1484*7c478bd9Sstevel@tonic-gate /* reach last command */ 1485*7c478bd9Sstevel@tonic-gate *last_processed_index = cmds->count - 1; 1486*7c478bd9Sstevel@tonic-gate } 1487*7c478bd9Sstevel@tonic-gate 1488*7c478bd9Sstevel@tonic-gate /* 1489*7c478bd9Sstevel@tonic-gate * Process the command buffer and return last command index and the new head of 1490*7c478bd9Sstevel@tonic-gate * the handle list 1491*7c478bd9Sstevel@tonic-gate */ 1492*7c478bd9Sstevel@tonic-gate static int 1493*7c478bd9Sstevel@tonic-gate process_commands(cmdbuf_t *cmds, int starting_index, picl_nodehdl_t parent, 1494*7c478bd9Sstevel@tonic-gate int *last_processed_index) 1495*7c478bd9Sstevel@tonic-gate { 1496*7c478bd9Sstevel@tonic-gate int err; 1497*7c478bd9Sstevel@tonic-gate int index; 1498*7c478bd9Sstevel@tonic-gate picl_nodehdl_t rooth; 1499*7c478bd9Sstevel@tonic-gate picl_nodehdl_t nodeh; 1500*7c478bd9Sstevel@tonic-gate command_t *commands = cmds->commands; 1501*7c478bd9Sstevel@tonic-gate 1502*7c478bd9Sstevel@tonic-gate for (index = starting_index; index < cmds->count; ++index) { 1503*7c478bd9Sstevel@tonic-gate switch (commands[index].type) { 1504*7c478bd9Sstevel@tonic-gate case TOK_CLASSPATH: 1505*7c478bd9Sstevel@tonic-gate case TOK_NAMEPATH: 1506*7c478bd9Sstevel@tonic-gate err = process_path(&commands[index], &rooth); 1507*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 1508*7c478bd9Sstevel@tonic-gate index++; 1509*7c478bd9Sstevel@tonic-gate (void) skip_to_next_valid_path(cmds, index, 1510*7c478bd9Sstevel@tonic-gate &rooth, &index); 1511*7c478bd9Sstevel@tonic-gate } 1512*7c478bd9Sstevel@tonic-gate parent = rooth; 1513*7c478bd9Sstevel@tonic-gate continue; 1514*7c478bd9Sstevel@tonic-gate case TOK_NODE: 1515*7c478bd9Sstevel@tonic-gate err = process_node(&commands[index], parent, &nodeh); 1516*7c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS) { 1517*7c478bd9Sstevel@tonic-gate index++; 1518*7c478bd9Sstevel@tonic-gate err = process_commands(cmds, index, nodeh, 1519*7c478bd9Sstevel@tonic-gate &index); 1520*7c478bd9Sstevel@tonic-gate } 1521*7c478bd9Sstevel@tonic-gate break; 1522*7c478bd9Sstevel@tonic-gate case TOK_ENDNODE: 1523*7c478bd9Sstevel@tonic-gate *last_processed_index = index; 1524*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1525*7c478bd9Sstevel@tonic-gate case TOK_PROP: 1526*7c478bd9Sstevel@tonic-gate err = process_prop(cmds, &commands[index], parent); 1527*7c478bd9Sstevel@tonic-gate break; 1528*7c478bd9Sstevel@tonic-gate case TOK_REFPROP: 1529*7c478bd9Sstevel@tonic-gate err = process_refprop(cmds, &commands[index], parent); 1530*7c478bd9Sstevel@tonic-gate /* no reference node */ 1531*7c478bd9Sstevel@tonic-gate if (err == PICL_NOTNODE) { 1532*7c478bd9Sstevel@tonic-gate err = PICL_SUCCESS; /* discard prop */ 1533*7c478bd9Sstevel@tonic-gate /* discard row by setting nproph = 0 */ 1534*7c478bd9Sstevel@tonic-gate if (cmds->inside_row_block) 1535*7c478bd9Sstevel@tonic-gate cmds->commands[cmds->current_row] 1536*7c478bd9Sstevel@tonic-gate .rowcmd_nproph = 0; 1537*7c478bd9Sstevel@tonic-gate } 1538*7c478bd9Sstevel@tonic-gate break; 1539*7c478bd9Sstevel@tonic-gate case TOK_REFNODE: 1540*7c478bd9Sstevel@tonic-gate err = process_refnode(&commands[index], parent); 1541*7c478bd9Sstevel@tonic-gate break; 1542*7c478bd9Sstevel@tonic-gate case TOK_TABLE: 1543*7c478bd9Sstevel@tonic-gate cmds->inside_table_block = 1; 1544*7c478bd9Sstevel@tonic-gate err = process_table(&commands[index], parent); 1545*7c478bd9Sstevel@tonic-gate cmds->current_tbl = index; 1546*7c478bd9Sstevel@tonic-gate break; 1547*7c478bd9Sstevel@tonic-gate case TOK_ENDTABLE: 1548*7c478bd9Sstevel@tonic-gate cmds->inside_table_block = 0; 1549*7c478bd9Sstevel@tonic-gate cmds->current_tbl = 0; 1550*7c478bd9Sstevel@tonic-gate break; 1551*7c478bd9Sstevel@tonic-gate case TOK_ROW: 1552*7c478bd9Sstevel@tonic-gate cmds->inside_row_block = 1; 1553*7c478bd9Sstevel@tonic-gate err = process_row(&commands[index]); 1554*7c478bd9Sstevel@tonic-gate cmds->current_row = index; 1555*7c478bd9Sstevel@tonic-gate break; 1556*7c478bd9Sstevel@tonic-gate case TOK_ENDROW: 1557*7c478bd9Sstevel@tonic-gate err = process_endrow(cmds); 1558*7c478bd9Sstevel@tonic-gate cmds->inside_row_block = 0; 1559*7c478bd9Sstevel@tonic-gate cmds->current_row = 0; 1560*7c478bd9Sstevel@tonic-gate break; 1561*7c478bd9Sstevel@tonic-gate case TOK_VERBOSE: 1562*7c478bd9Sstevel@tonic-gate err = process_verbose(cmds, &commands[index]); 1563*7c478bd9Sstevel@tonic-gate break; 1564*7c478bd9Sstevel@tonic-gate default: /* won't reach here */ 1565*7c478bd9Sstevel@tonic-gate err = PICL_FAILURE; 1566*7c478bd9Sstevel@tonic-gate break; 1567*7c478bd9Sstevel@tonic-gate } 1568*7c478bd9Sstevel@tonic-gate 1569*7c478bd9Sstevel@tonic-gate if ((err != PICL_SUCCESS) && (err != PICL_PROPEXISTS)) { 1570*7c478bd9Sstevel@tonic-gate *last_processed_index = index; 1571*7c478bd9Sstevel@tonic-gate return (err); 1572*7c478bd9Sstevel@tonic-gate } 1573*7c478bd9Sstevel@tonic-gate } 1574*7c478bd9Sstevel@tonic-gate 1575*7c478bd9Sstevel@tonic-gate /* reach last command */ 1576*7c478bd9Sstevel@tonic-gate *last_processed_index = cmds->count - 1; 1577*7c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); 1578*7c478bd9Sstevel@tonic-gate } 1579*7c478bd9Sstevel@tonic-gate 1580*7c478bd9Sstevel@tonic-gate /* 1581*7c478bd9Sstevel@tonic-gate * clean up the commands buffer 1582*7c478bd9Sstevel@tonic-gate */ 1583*7c478bd9Sstevel@tonic-gate static void 1584*7c478bd9Sstevel@tonic-gate clean_up(cmdbuf_t *cmds) 1585*7c478bd9Sstevel@tonic-gate { 1586*7c478bd9Sstevel@tonic-gate int cmd_index; 1587*7c478bd9Sstevel@tonic-gate 1588*7c478bd9Sstevel@tonic-gate for (cmd_index = 0; cmd_index < cmds->count; cmd_index++) { 1589*7c478bd9Sstevel@tonic-gate switch (cmds->commands[cmd_index].type) { 1590*7c478bd9Sstevel@tonic-gate case TOK_CLASSPATH: 1591*7c478bd9Sstevel@tonic-gate case TOK_NAMEPATH: 1592*7c478bd9Sstevel@tonic-gate free_path(&cmds->commands[cmd_index]); 1593*7c478bd9Sstevel@tonic-gate break; 1594*7c478bd9Sstevel@tonic-gate case TOK_NODE: 1595*7c478bd9Sstevel@tonic-gate free_node(&cmds->commands[cmd_index]); 1596*7c478bd9Sstevel@tonic-gate break; 1597*7c478bd9Sstevel@tonic-gate case TOK_PROP: 1598*7c478bd9Sstevel@tonic-gate free_prop(&cmds->commands[cmd_index]); 1599*7c478bd9Sstevel@tonic-gate break; 1600*7c478bd9Sstevel@tonic-gate case TOK_REFPROP: 1601*7c478bd9Sstevel@tonic-gate free_refprop(&cmds->commands[cmd_index]); 1602*7c478bd9Sstevel@tonic-gate break; 1603*7c478bd9Sstevel@tonic-gate case TOK_REFNODE: 1604*7c478bd9Sstevel@tonic-gate free_refnode(&cmds->commands[cmd_index]); 1605*7c478bd9Sstevel@tonic-gate break; 1606*7c478bd9Sstevel@tonic-gate case TOK_TABLE: 1607*7c478bd9Sstevel@tonic-gate free_table(&cmds->commands[cmd_index]); 1608*7c478bd9Sstevel@tonic-gate break; 1609*7c478bd9Sstevel@tonic-gate case TOK_ENDTABLE: 1610*7c478bd9Sstevel@tonic-gate case TOK_ROW: 1611*7c478bd9Sstevel@tonic-gate case TOK_ENDROW: 1612*7c478bd9Sstevel@tonic-gate case TOK_ENDNODE: 1613*7c478bd9Sstevel@tonic-gate case TOK_VERBOSE: 1614*7c478bd9Sstevel@tonic-gate default: 1615*7c478bd9Sstevel@tonic-gate break; 1616*7c478bd9Sstevel@tonic-gate } 1617*7c478bd9Sstevel@tonic-gate } 1618*7c478bd9Sstevel@tonic-gate if (cmds->commands) 1619*7c478bd9Sstevel@tonic-gate free(cmds->commands); 1620*7c478bd9Sstevel@tonic-gate } 1621*7c478bd9Sstevel@tonic-gate 1622*7c478bd9Sstevel@tonic-gate /* 1623*7c478bd9Sstevel@tonic-gate * Parse the configuration file and create nodes/properties under nh 1624*7c478bd9Sstevel@tonic-gate * 1625*7c478bd9Sstevel@tonic-gate * It checks the syntax first. If there is any syntax error, 1626*7c478bd9Sstevel@tonic-gate * it returns 1 and won't continue processing the file to add nodes or props. 1627*7c478bd9Sstevel@tonic-gate * 1628*7c478bd9Sstevel@tonic-gate * If any error happens during command processing, all nodes 1629*7c478bd9Sstevel@tonic-gate * and properties just created will be deleted, i.e. undo 1630*7c478bd9Sstevel@tonic-gate * commands which have been processed. It returns 1. 1631*7c478bd9Sstevel@tonic-gate * 1632*7c478bd9Sstevel@tonic-gate * If success, return 0. 1633*7c478bd9Sstevel@tonic-gate */ 1634*7c478bd9Sstevel@tonic-gate int 1635*7c478bd9Sstevel@tonic-gate picld_pluginutil_parse_config_file(picl_nodehdl_t nh, const char *filename) 1636*7c478bd9Sstevel@tonic-gate { 1637*7c478bd9Sstevel@tonic-gate FILE *ifp; 1638*7c478bd9Sstevel@tonic-gate int last_processed_index; 1639*7c478bd9Sstevel@tonic-gate int err; 1640*7c478bd9Sstevel@tonic-gate cmdbuf_t *cmds; 1641*7c478bd9Sstevel@tonic-gate 1642*7c478bd9Sstevel@tonic-gate /* set correct locale for use inside pluginutil */ 1643*7c478bd9Sstevel@tonic-gate setlocale(LC_ALL, "C"); 1644*7c478bd9Sstevel@tonic-gate 1645*7c478bd9Sstevel@tonic-gate /* 1646*7c478bd9Sstevel@tonic-gate * Initialize the command buffer 1647*7c478bd9Sstevel@tonic-gate */ 1648*7c478bd9Sstevel@tonic-gate 1649*7c478bd9Sstevel@tonic-gate cmds = malloc(sizeof (*cmds)); 1650*7c478bd9Sstevel@tonic-gate if (cmds == NULL) { 1651*7c478bd9Sstevel@tonic-gate setlocale(LC_ALL, ""); 1652*7c478bd9Sstevel@tonic-gate return (1); 1653*7c478bd9Sstevel@tonic-gate } 1654*7c478bd9Sstevel@tonic-gate 1655*7c478bd9Sstevel@tonic-gate memset(cmds, 0, sizeof (cmdbuf_t)); 1656*7c478bd9Sstevel@tonic-gate 1657*7c478bd9Sstevel@tonic-gate cmds->fname = filename; 1658*7c478bd9Sstevel@tonic-gate 1659*7c478bd9Sstevel@tonic-gate ifp = fopen(filename, "r"); 1660*7c478bd9Sstevel@tonic-gate if (ifp == NULL) { 1661*7c478bd9Sstevel@tonic-gate setlocale(LC_ALL, ""); 1662*7c478bd9Sstevel@tonic-gate return (1); 1663*7c478bd9Sstevel@tonic-gate } 1664*7c478bd9Sstevel@tonic-gate 1665*7c478bd9Sstevel@tonic-gate /* 1666*7c478bd9Sstevel@tonic-gate * check the syntax of the configuration file 1667*7c478bd9Sstevel@tonic-gate */ 1668*7c478bd9Sstevel@tonic-gate err = check_conffile_syntax(cmds, ifp); 1669*7c478bd9Sstevel@tonic-gate 1670*7c478bd9Sstevel@tonic-gate (void) fclose(ifp); 1671*7c478bd9Sstevel@tonic-gate 1672*7c478bd9Sstevel@tonic-gate if (err != EC_SYNTAX_OK) { 1673*7c478bd9Sstevel@tonic-gate clean_up(cmds); 1674*7c478bd9Sstevel@tonic-gate free(cmds); 1675*7c478bd9Sstevel@tonic-gate setlocale(LC_ALL, ""); 1676*7c478bd9Sstevel@tonic-gate return (1); 1677*7c478bd9Sstevel@tonic-gate } 1678*7c478bd9Sstevel@tonic-gate 1679*7c478bd9Sstevel@tonic-gate /* 1680*7c478bd9Sstevel@tonic-gate * Process the commands 1681*7c478bd9Sstevel@tonic-gate */ 1682*7c478bd9Sstevel@tonic-gate err = process_commands(cmds, STARTING_INDEX, nh, &last_processed_index); 1683*7c478bd9Sstevel@tonic-gate 1684*7c478bd9Sstevel@tonic-gate /* 1685*7c478bd9Sstevel@tonic-gate * If any PICL error, remove the newly created node/prop 1686*7c478bd9Sstevel@tonic-gate * handles from the PICL tree. 1687*7c478bd9Sstevel@tonic-gate */ 1688*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) { 1689*7c478bd9Sstevel@tonic-gate undo_commands(cmds, last_processed_index); 1690*7c478bd9Sstevel@tonic-gate if (cmds->verbose) 1691*7c478bd9Sstevel@tonic-gate verbose_log(LOG_ERR, err_msg[EC_PICL_ERR], filename, 1692*7c478bd9Sstevel@tonic-gate err); 1693*7c478bd9Sstevel@tonic-gate } 1694*7c478bd9Sstevel@tonic-gate 1695*7c478bd9Sstevel@tonic-gate clean_up(cmds); 1696*7c478bd9Sstevel@tonic-gate free(cmds); 1697*7c478bd9Sstevel@tonic-gate 1698*7c478bd9Sstevel@tonic-gate /* reset the locale */ 1699*7c478bd9Sstevel@tonic-gate setlocale(LC_ALL, ""); 1700*7c478bd9Sstevel@tonic-gate 1701*7c478bd9Sstevel@tonic-gate return ((err == PICL_SUCCESS) ? 0 : 1); 1702*7c478bd9Sstevel@tonic-gate } 1703