1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <unistd.h> 30*0Sstevel@tonic-gate #include <sys/types.h> 31*0Sstevel@tonic-gate #include <sys/socket.h> 32*0Sstevel@tonic-gate #include <sys/sockio.h> 33*0Sstevel@tonic-gate #include <netinet/in.h> 34*0Sstevel@tonic-gate #include <arpa/inet.h> 35*0Sstevel@tonic-gate #include <net/if.h> 36*0Sstevel@tonic-gate #include <stdio.h> 37*0Sstevel@tonic-gate #include <stdlib.h> 38*0Sstevel@tonic-gate #include <strings.h> 39*0Sstevel@tonic-gate #include <ctype.h> 40*0Sstevel@tonic-gate #include <errno.h> 41*0Sstevel@tonic-gate #include <libintl.h> 42*0Sstevel@tonic-gate #include <locale.h> 43*0Sstevel@tonic-gate #include <libdevinfo.h> 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gate #define DATADM_OP_VIEW 0x0000 46*0Sstevel@tonic-gate #define DATADM_OP_UPDATE 0x0001 47*0Sstevel@tonic-gate #define DATADM_OP_ADD 0x0002 48*0Sstevel@tonic-gate #define DATADM_OP_REMOVE 0x0003 49*0Sstevel@tonic-gate #define DATADM_NUM_OPS 0x0004 50*0Sstevel@tonic-gate #define DATADM_DAT_CONF "/etc/dat/dat.conf" 51*0Sstevel@tonic-gate #define DATADM_LINESZ 1024 52*0Sstevel@tonic-gate #define DATADM_NUM_SP_TOKENS 7 53*0Sstevel@tonic-gate #define DATADM_NUM_DAT_TOKENS 8 54*0Sstevel@tonic-gate #define DATADM_IA_NAME "ibd" 55*0Sstevel@tonic-gate #define DATADM_DRV_NAME "driver_name" 56*0Sstevel@tonic-gate #define DATADM_MAX_TOKENS 16 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate /* 59*0Sstevel@tonic-gate * generic entry 60*0Sstevel@tonic-gate * placed at the top of all entry types 61*0Sstevel@tonic-gate */ 62*0Sstevel@tonic-gate typedef struct datadm_entry { 63*0Sstevel@tonic-gate struct datadm_entry *de_next; 64*0Sstevel@tonic-gate } datadm_entry_t; 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate /* 67*0Sstevel@tonic-gate * list structure 68*0Sstevel@tonic-gate * can be manipulated using datadm_walk_list or 69*0Sstevel@tonic-gate * datadm_enqueue_entry 70*0Sstevel@tonic-gate */ 71*0Sstevel@tonic-gate typedef struct datadm_list { 72*0Sstevel@tonic-gate datadm_entry_t *dl_head; 73*0Sstevel@tonic-gate datadm_entry_t *dl_tail; 74*0Sstevel@tonic-gate uint_t dl_count; 75*0Sstevel@tonic-gate } datadm_list_t; 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate /* 78*0Sstevel@tonic-gate * internal representation of the version string in 79*0Sstevel@tonic-gate * dat.conf or service_provider.conf. the format is 80*0Sstevel@tonic-gate * <dv_name><dv_major>.<dv_minor> 81*0Sstevel@tonic-gate */ 82*0Sstevel@tonic-gate typedef struct datadm_version { 83*0Sstevel@tonic-gate char *dv_name; 84*0Sstevel@tonic-gate uint_t dv_major; 85*0Sstevel@tonic-gate uint_t dv_minor; 86*0Sstevel@tonic-gate } datadm_version_t; 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate /* 89*0Sstevel@tonic-gate * each sp_entry corresponds to an entry in dat.conf or 90*0Sstevel@tonic-gate * service_provider.conf. an sp_entry is processed by the 91*0Sstevel@tonic-gate * function datadm_process_sp_entry. 92*0Sstevel@tonic-gate */ 93*0Sstevel@tonic-gate typedef struct datadm_sp_entry { 94*0Sstevel@tonic-gate datadm_entry_t spe_header; 95*0Sstevel@tonic-gate char *spe_devname; 96*0Sstevel@tonic-gate datadm_version_t spe_api_version; 97*0Sstevel@tonic-gate int spe_threadsafe; 98*0Sstevel@tonic-gate int spe_default; 99*0Sstevel@tonic-gate char *spe_libpath; 100*0Sstevel@tonic-gate datadm_version_t spe_sp_version; 101*0Sstevel@tonic-gate char *spe_sp_data; 102*0Sstevel@tonic-gate int spe_invalid; 103*0Sstevel@tonic-gate } datadm_sp_entry_t; 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate /* 106*0Sstevel@tonic-gate * an hca_entry is created whenever a new hca device is 107*0Sstevel@tonic-gate * encountered during sp_entry processing. this structure 108*0Sstevel@tonic-gate * contains two lists. the sp_list holds sp entries that 109*0Sstevel@tonic-gate * are added when sp entry processing occurs. duplicate 110*0Sstevel@tonic-gate * sp entries are not added to this list. the ia_list may 111*0Sstevel@tonic-gate * be built statically using the information in dat.conf or 112*0Sstevel@tonic-gate * dynamically using libdevinfo. similar to the sp_list, 113*0Sstevel@tonic-gate * the ia_list contains only unique entries. 114*0Sstevel@tonic-gate */ 115*0Sstevel@tonic-gate typedef struct datadm_hca_entry { 116*0Sstevel@tonic-gate datadm_entry_t he_header; 117*0Sstevel@tonic-gate char *he_name; 118*0Sstevel@tonic-gate datadm_list_t he_sp_list; 119*0Sstevel@tonic-gate datadm_list_t he_ia_list; 120*0Sstevel@tonic-gate } datadm_hca_entry_t; 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate /* 123*0Sstevel@tonic-gate * an ia_entry is created when a new ia name is encountered 124*0Sstevel@tonic-gate * during sp_entry processing or when a new ia name is 125*0Sstevel@tonic-gate * discovered by datadm_fill_ia_list. ia_entry holds the ia 126*0Sstevel@tonic-gate * device's instance number. 127*0Sstevel@tonic-gate */ 128*0Sstevel@tonic-gate typedef struct datadm_ia_entry { 129*0Sstevel@tonic-gate datadm_entry_t iae_header; 130*0Sstevel@tonic-gate int iae_devnum; 131*0Sstevel@tonic-gate } datadm_ia_entry_t; 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate /* 134*0Sstevel@tonic-gate * a comment entry represents one of the comment lines at the 135*0Sstevel@tonic-gate * top of dat.conf. a list of these lines are saved during the 136*0Sstevel@tonic-gate * parsing of dat.conf. these lines are written back to dat.conf 137*0Sstevel@tonic-gate * when dat.conf gets regenerated. 138*0Sstevel@tonic-gate */ 139*0Sstevel@tonic-gate typedef struct datadm_cmnt_entry { 140*0Sstevel@tonic-gate datadm_entry_t cmnt_header; 141*0Sstevel@tonic-gate char *cmnt_line; 142*0Sstevel@tonic-gate } datadm_cmnt_entry_t; 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate /* 145*0Sstevel@tonic-gate * 2nd argument to datadm_hca_entry_find. 146*0Sstevel@tonic-gate * hf_hca_entry is filled in if an hca_entry with 147*0Sstevel@tonic-gate * a matching he_name is found. 148*0Sstevel@tonic-gate */ 149*0Sstevel@tonic-gate typedef struct datadm_hca_find { 150*0Sstevel@tonic-gate datadm_sp_entry_t *hf_sp_entry; 151*0Sstevel@tonic-gate datadm_hca_entry_t *hf_hca_entry; 152*0Sstevel@tonic-gate } datadm_hca_find_t; 153*0Sstevel@tonic-gate 154*0Sstevel@tonic-gate /* 155*0Sstevel@tonic-gate * 2nd argument to datadm_ia_entry_find. 156*0Sstevel@tonic-gate * if_ia_entry is filled in if an ia_entry with 157*0Sstevel@tonic-gate * a matching ia_devnum is found. 158*0Sstevel@tonic-gate */ 159*0Sstevel@tonic-gate typedef struct datadm_ia_find { 160*0Sstevel@tonic-gate int if_ia_devnum; 161*0Sstevel@tonic-gate datadm_ia_entry_t *if_ia_entry; 162*0Sstevel@tonic-gate } datadm_ia_find_t; 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate /* 165*0Sstevel@tonic-gate * this gets passed to datadm_fill_ia_list. 166*0Sstevel@tonic-gate * we do this to avoid regenerating the device 167*0Sstevel@tonic-gate * tree for each hca_entry we process. 168*0Sstevel@tonic-gate */ 169*0Sstevel@tonic-gate typedef struct datadm_fill_ia_list { 170*0Sstevel@tonic-gate di_node_t ia_root_node; 171*0Sstevel@tonic-gate int ia_sock_fd_v4; 172*0Sstevel@tonic-gate int ia_sock_fd_v6; 173*0Sstevel@tonic-gate } datadm_fill_ia_list_t; 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate /* 176*0Sstevel@tonic-gate * this defines the commandline parameters specified 177*0Sstevel@tonic-gate * by the user. 178*0Sstevel@tonic-gate */ 179*0Sstevel@tonic-gate typedef struct datadm_args { 180*0Sstevel@tonic-gate char *da_sp_conf; 181*0Sstevel@tonic-gate char *da_dat_conf; 182*0Sstevel@tonic-gate int da_op_type; 183*0Sstevel@tonic-gate } datadm_args_t; 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate static datadm_args_t datadm_args; 186*0Sstevel@tonic-gate static datadm_list_t datadm_conf_header; 187*0Sstevel@tonic-gate static char *datadm_conf_header_default = 188*0Sstevel@tonic-gate "#\n" 189*0Sstevel@tonic-gate "# Copyright 2004 Sun Microsystems, Inc. All rights reserved.\n" 190*0Sstevel@tonic-gate "# Use is subject to license terms.\n" 191*0Sstevel@tonic-gate "#\n" 192*0Sstevel@tonic-gate "# ident \"@(#)dat.conf 1.1 03/08/26 SMI\"\n" 193*0Sstevel@tonic-gate "#\n" 194*0Sstevel@tonic-gate "# DAT configuration file.\n" 195*0Sstevel@tonic-gate "#\n" 196*0Sstevel@tonic-gate "# This file is updated using the datadm(1) command.\n" 197*0Sstevel@tonic-gate "# Do not hand edit this file.\n" 198*0Sstevel@tonic-gate "# See datadm(1) man page for more details.\n" 199*0Sstevel@tonic-gate "#\n" 200*0Sstevel@tonic-gate "# The fields in this file are -\n" 201*0Sstevel@tonic-gate "#\n" 202*0Sstevel@tonic-gate "# IAname version threadsafe default library-path provider-version \\\n" 203*0Sstevel@tonic-gate "# instance-data platform-information\n" 204*0Sstevel@tonic-gate "#\n"; 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate /* 207*0Sstevel@tonic-gate * common parsing functions. 208*0Sstevel@tonic-gate */ 209*0Sstevel@tonic-gate typedef int (*datadm_parse_func_t)(char *, void *); 210*0Sstevel@tonic-gate static int datadm_parse_line(char *, char *[], int *); 211*0Sstevel@tonic-gate static int datadm_parse_generic_str(char *, char **); 212*0Sstevel@tonic-gate static int datadm_parse_nonnull_str(char *, char **); 213*0Sstevel@tonic-gate static int datadm_parse_version(char *, datadm_version_t *); 214*0Sstevel@tonic-gate static int datadm_parse_devname(char *, datadm_sp_entry_t *); 215*0Sstevel@tonic-gate static int datadm_parse_api_version(char *, datadm_sp_entry_t *); 216*0Sstevel@tonic-gate static int datadm_parse_threadsafe(char *, datadm_sp_entry_t *); 217*0Sstevel@tonic-gate static int datadm_parse_default(char *, datadm_sp_entry_t *); 218*0Sstevel@tonic-gate static int datadm_parse_libpath(char *, datadm_sp_entry_t *); 219*0Sstevel@tonic-gate static int datadm_parse_sp_version(char *, datadm_sp_entry_t *); 220*0Sstevel@tonic-gate static int datadm_parse_sp_data(char *, datadm_sp_entry_t *); 221*0Sstevel@tonic-gate static int datadm_parse_ia_name(char *, int *); 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate /* 224*0Sstevel@tonic-gate * utility functions 225*0Sstevel@tonic-gate */ 226*0Sstevel@tonic-gate static void datadm_enqueue_entry(datadm_list_t *, datadm_entry_t *); 227*0Sstevel@tonic-gate static int datadm_walk_list(datadm_list_t *, 228*0Sstevel@tonic-gate int (*)(datadm_entry_t *, void *), void *); 229*0Sstevel@tonic-gate static int datadm_str_match(char *, char *); 230*0Sstevel@tonic-gate static int datadm_version_match(datadm_version_t *, datadm_version_t *); 231*0Sstevel@tonic-gate static int datadm_sp_entry_match(datadm_sp_entry_t *, datadm_sp_entry_t *); 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate /* 234*0Sstevel@tonic-gate * entry allocation/deallocation 235*0Sstevel@tonic-gate */ 236*0Sstevel@tonic-gate static datadm_sp_entry_t *datadm_alloc_sp_entry(void); 237*0Sstevel@tonic-gate static datadm_ia_entry_t *datadm_alloc_ia_entry(void); 238*0Sstevel@tonic-gate static datadm_hca_entry_t *datadm_alloc_hca_entry(void); 239*0Sstevel@tonic-gate static datadm_cmnt_entry_t *datadm_alloc_cmnt_entry(void); 240*0Sstevel@tonic-gate static void datadm_free_sp_entry(datadm_sp_entry_t *); 241*0Sstevel@tonic-gate static void datadm_free_ia_entry(datadm_ia_entry_t *); 242*0Sstevel@tonic-gate static void datadm_free_hca_entry(datadm_hca_entry_t *); 243*0Sstevel@tonic-gate static void datadm_free_cmnt_entry(datadm_cmnt_entry_t *); 244*0Sstevel@tonic-gate 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gate /* 247*0Sstevel@tonic-gate * high level parsing functions 248*0Sstevel@tonic-gate */ 249*0Sstevel@tonic-gate static int datadm_parse_sp_conf(datadm_list_t *); 250*0Sstevel@tonic-gate static int datadm_parse_dat_conf(datadm_list_t *); 251*0Sstevel@tonic-gate static int datadm_process_sp_entry(datadm_list_t *, datadm_sp_entry_t *, int); 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate /* 254*0Sstevel@tonic-gate * ia devices discovery 255*0Sstevel@tonic-gate */ 256*0Sstevel@tonic-gate static int datadm_build_ia_lists(datadm_list_t *); 257*0Sstevel@tonic-gate static int datadm_fill_ia_list(datadm_hca_entry_t *, datadm_fill_ia_list_t *); 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate /* 260*0Sstevel@tonic-gate * helper function for OP_REMOVE 261*0Sstevel@tonic-gate */ 262*0Sstevel@tonic-gate static void datadm_invalidate_common_sp_entries(datadm_list_t *, 263*0Sstevel@tonic-gate datadm_list_t *); 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gate /* 266*0Sstevel@tonic-gate * output generation 267*0Sstevel@tonic-gate */ 268*0Sstevel@tonic-gate static int datadm_generate_dat_conf(datadm_list_t *); 269*0Sstevel@tonic-gate static int datadm_generate_conf_header(FILE *); 270*0Sstevel@tonic-gate static int datadm_generate_conf_entry(FILE *, datadm_ia_entry_t *, 271*0Sstevel@tonic-gate datadm_sp_entry_t *); 272*0Sstevel@tonic-gate 273*0Sstevel@tonic-gate /* 274*0Sstevel@tonic-gate * datadm operations 275*0Sstevel@tonic-gate */ 276*0Sstevel@tonic-gate static int datadm_view(void); 277*0Sstevel@tonic-gate static int datadm_update(void); 278*0Sstevel@tonic-gate static int datadm_add(void); 279*0Sstevel@tonic-gate static int datadm_remove(void); 280*0Sstevel@tonic-gate 281*0Sstevel@tonic-gate /* 282*0Sstevel@tonic-gate * usage 283*0Sstevel@tonic-gate */ 284*0Sstevel@tonic-gate static void datadm_usage(void); 285*0Sstevel@tonic-gate 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate /* 288*0Sstevel@tonic-gate * parse function tables 289*0Sstevel@tonic-gate */ 290*0Sstevel@tonic-gate static datadm_parse_func_t datadm_sp_parse_funcs[DATADM_NUM_SP_TOKENS] = { 291*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_devname, 292*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_api_version, 293*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_threadsafe, 294*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_default, 295*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_libpath, 296*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_sp_version, 297*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_sp_data 298*0Sstevel@tonic-gate }; 299*0Sstevel@tonic-gate 300*0Sstevel@tonic-gate static datadm_parse_func_t datadm_dat_parse_funcs[DATADM_NUM_DAT_TOKENS] = { 301*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_ia_name, 302*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_api_version, 303*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_threadsafe, 304*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_default, 305*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_libpath, 306*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_sp_version, 307*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_sp_data, 308*0Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_devname 309*0Sstevel@tonic-gate }; 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gate /* 312*0Sstevel@tonic-gate * operation table 313*0Sstevel@tonic-gate */ 314*0Sstevel@tonic-gate static int (*datadm_ops[DATADM_NUM_OPS])(void) = { 315*0Sstevel@tonic-gate datadm_view, 316*0Sstevel@tonic-gate datadm_update, 317*0Sstevel@tonic-gate datadm_add, 318*0Sstevel@tonic-gate datadm_remove 319*0Sstevel@tonic-gate }; 320*0Sstevel@tonic-gate 321*0Sstevel@tonic-gate static void 322*0Sstevel@tonic-gate datadm_usage(void) 323*0Sstevel@tonic-gate { 324*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 325*0Sstevel@tonic-gate "usage: datadm -v\n" 326*0Sstevel@tonic-gate " -u\n" 327*0Sstevel@tonic-gate " -a <service_provider.conf>\n" 328*0Sstevel@tonic-gate " -r <service_provider.conf>\n")); 329*0Sstevel@tonic-gate } 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gate static int 332*0Sstevel@tonic-gate datadm_parse_generic_str(char *str, char **strptr) 333*0Sstevel@tonic-gate { 334*0Sstevel@tonic-gate int len; 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate len = strlen(str); 337*0Sstevel@tonic-gate *strptr = (char *)malloc(len + 1); 338*0Sstevel@tonic-gate if (*strptr == NULL) { 339*0Sstevel@tonic-gate return (-1); 340*0Sstevel@tonic-gate } 341*0Sstevel@tonic-gate (void) strcpy(*strptr, str); 342*0Sstevel@tonic-gate return (0); 343*0Sstevel@tonic-gate } 344*0Sstevel@tonic-gate 345*0Sstevel@tonic-gate /* 346*0Sstevel@tonic-gate * this function strips off leading and trailing 347*0Sstevel@tonic-gate * whitespaces and returns an error for null or 348*0Sstevel@tonic-gate * empty strings. 349*0Sstevel@tonic-gate */ 350*0Sstevel@tonic-gate static int 351*0Sstevel@tonic-gate datadm_parse_nonnull_str(char *str, char **strptr) 352*0Sstevel@tonic-gate { 353*0Sstevel@tonic-gate int len, i; 354*0Sstevel@tonic-gate char *start; 355*0Sstevel@tonic-gate 356*0Sstevel@tonic-gate if (str[0] == '\0') { 357*0Sstevel@tonic-gate return (-1); 358*0Sstevel@tonic-gate } 359*0Sstevel@tonic-gate start = str; 360*0Sstevel@tonic-gate for (i = 0; str[i] != '\0'; i++) { 361*0Sstevel@tonic-gate if (!isspace(str[i])) { 362*0Sstevel@tonic-gate start = &str[i]; 363*0Sstevel@tonic-gate break; 364*0Sstevel@tonic-gate } 365*0Sstevel@tonic-gate } 366*0Sstevel@tonic-gate for (; str[i] != '\0'; i++) { 367*0Sstevel@tonic-gate if (isspace(str[i])) { 368*0Sstevel@tonic-gate str[i] = '\0'; 369*0Sstevel@tonic-gate } 370*0Sstevel@tonic-gate } 371*0Sstevel@tonic-gate len = strlen(start); 372*0Sstevel@tonic-gate *strptr = (char *)malloc(len + 1); 373*0Sstevel@tonic-gate if (*strptr == NULL) { 374*0Sstevel@tonic-gate return (-1); 375*0Sstevel@tonic-gate } 376*0Sstevel@tonic-gate (void) strcpy(*strptr, start); 377*0Sstevel@tonic-gate return (0); 378*0Sstevel@tonic-gate } 379*0Sstevel@tonic-gate 380*0Sstevel@tonic-gate /* 381*0Sstevel@tonic-gate * parses the api_version and sp_version fields in 382*0Sstevel@tonic-gate * dat.conf and service_provider.conf 383*0Sstevel@tonic-gate */ 384*0Sstevel@tonic-gate static int 385*0Sstevel@tonic-gate datadm_parse_version(char *str, datadm_version_t *version) 386*0Sstevel@tonic-gate { 387*0Sstevel@tonic-gate int i = 0, len; 388*0Sstevel@tonic-gate int major_idx, minor_idx; 389*0Sstevel@tonic-gate 390*0Sstevel@tonic-gate len = strlen(str); 391*0Sstevel@tonic-gate 392*0Sstevel@tonic-gate for (i = 0; i < len; i++) { 393*0Sstevel@tonic-gate if (isdigit(str[i])) break; 394*0Sstevel@tonic-gate } 395*0Sstevel@tonic-gate if (i == len) { 396*0Sstevel@tonic-gate return (-1); 397*0Sstevel@tonic-gate } 398*0Sstevel@tonic-gate if (i > 0) { 399*0Sstevel@tonic-gate version->dv_name = (char *)malloc(i + 1); 400*0Sstevel@tonic-gate bcopy(str, version->dv_name, i); 401*0Sstevel@tonic-gate version->dv_name[i] = '\0'; 402*0Sstevel@tonic-gate } else { 403*0Sstevel@tonic-gate version->dv_name = NULL; 404*0Sstevel@tonic-gate } 405*0Sstevel@tonic-gate major_idx = i; 406*0Sstevel@tonic-gate 407*0Sstevel@tonic-gate for (; i < len; i++) { 408*0Sstevel@tonic-gate if (!isdigit(str[i])) break; 409*0Sstevel@tonic-gate } 410*0Sstevel@tonic-gate if (i == len) { 411*0Sstevel@tonic-gate return (-1); 412*0Sstevel@tonic-gate } 413*0Sstevel@tonic-gate if (str[i] != '.') { 414*0Sstevel@tonic-gate return (-1); 415*0Sstevel@tonic-gate } 416*0Sstevel@tonic-gate minor_idx = ++i; 417*0Sstevel@tonic-gate if (i == len) { 418*0Sstevel@tonic-gate return (-1); 419*0Sstevel@tonic-gate } 420*0Sstevel@tonic-gate for (; i < len; i++) { 421*0Sstevel@tonic-gate if (!isdigit(str[i])) break; 422*0Sstevel@tonic-gate } 423*0Sstevel@tonic-gate if (i != len) { 424*0Sstevel@tonic-gate return (-1); 425*0Sstevel@tonic-gate } 426*0Sstevel@tonic-gate version->dv_major = atoi(str + major_idx); 427*0Sstevel@tonic-gate version->dv_minor = atoi(str + minor_idx); 428*0Sstevel@tonic-gate return (0); 429*0Sstevel@tonic-gate } 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate /* 432*0Sstevel@tonic-gate * parses the ia_name field in dat.conf 433*0Sstevel@tonic-gate */ 434*0Sstevel@tonic-gate static int 435*0Sstevel@tonic-gate datadm_parse_ia_name(char *str, int *ia_devnum) 436*0Sstevel@tonic-gate { 437*0Sstevel@tonic-gate int len; 438*0Sstevel@tonic-gate int i, start; 439*0Sstevel@tonic-gate 440*0Sstevel@tonic-gate len = strlen(DATADM_IA_NAME); 441*0Sstevel@tonic-gate if (strncmp(str, DATADM_IA_NAME, len) != 0) { 442*0Sstevel@tonic-gate return (-1); 443*0Sstevel@tonic-gate } 444*0Sstevel@tonic-gate start = i = len; 445*0Sstevel@tonic-gate len = strlen(str); 446*0Sstevel@tonic-gate if (str[i] == '\0') { 447*0Sstevel@tonic-gate return (-1); 448*0Sstevel@tonic-gate } 449*0Sstevel@tonic-gate for (; i < len; i++) { 450*0Sstevel@tonic-gate if (!isdigit(str[i])) break; 451*0Sstevel@tonic-gate } 452*0Sstevel@tonic-gate if (i != len) { 453*0Sstevel@tonic-gate return (-1); 454*0Sstevel@tonic-gate } 455*0Sstevel@tonic-gate *ia_devnum = atoi(str + start); 456*0Sstevel@tonic-gate return (0); 457*0Sstevel@tonic-gate } 458*0Sstevel@tonic-gate 459*0Sstevel@tonic-gate /* 460*0Sstevel@tonic-gate * parses the device name, strips leading and trailing spaces. 461*0Sstevel@tonic-gate * the format should be "driver_name=<dev_name>" 462*0Sstevel@tonic-gate */ 463*0Sstevel@tonic-gate static int 464*0Sstevel@tonic-gate datadm_parse_devname(char *str, datadm_sp_entry_t *sp_entry) 465*0Sstevel@tonic-gate { 466*0Sstevel@tonic-gate int len, dlen, i, j = 0; 467*0Sstevel@tonic-gate char *drv_name = DATADM_DRV_NAME; 468*0Sstevel@tonic-gate 469*0Sstevel@tonic-gate len = strlen(str); 470*0Sstevel@tonic-gate dlen = strlen(drv_name); 471*0Sstevel@tonic-gate 472*0Sstevel@tonic-gate /* 473*0Sstevel@tonic-gate * strip out leading spaces and try to match 474*0Sstevel@tonic-gate * the expected string 475*0Sstevel@tonic-gate */ 476*0Sstevel@tonic-gate for (i = 0; i < len; i++) { 477*0Sstevel@tonic-gate if (isspace(str[i]) && j == 0) { 478*0Sstevel@tonic-gate continue; 479*0Sstevel@tonic-gate } else { 480*0Sstevel@tonic-gate if (str[i] == drv_name[j]) { 481*0Sstevel@tonic-gate j++; 482*0Sstevel@tonic-gate if (j == dlen) { 483*0Sstevel@tonic-gate break; 484*0Sstevel@tonic-gate } else { 485*0Sstevel@tonic-gate continue; 486*0Sstevel@tonic-gate } 487*0Sstevel@tonic-gate } else { 488*0Sstevel@tonic-gate break; 489*0Sstevel@tonic-gate } 490*0Sstevel@tonic-gate } 491*0Sstevel@tonic-gate } 492*0Sstevel@tonic-gate 493*0Sstevel@tonic-gate /* 494*0Sstevel@tonic-gate * j must be dlen if the matching string is found 495*0Sstevel@tonic-gate */ 496*0Sstevel@tonic-gate if (j != dlen) { 497*0Sstevel@tonic-gate return (-1); 498*0Sstevel@tonic-gate } 499*0Sstevel@tonic-gate 500*0Sstevel@tonic-gate /* 501*0Sstevel@tonic-gate * skip past the last char of drv_name 502*0Sstevel@tonic-gate */ 503*0Sstevel@tonic-gate i++; 504*0Sstevel@tonic-gate 505*0Sstevel@tonic-gate /* 506*0Sstevel@tonic-gate * strip the spaces before the '=' 507*0Sstevel@tonic-gate */ 508*0Sstevel@tonic-gate for (; i < len; i++) { 509*0Sstevel@tonic-gate if (!isspace(str[i])) { 510*0Sstevel@tonic-gate break; 511*0Sstevel@tonic-gate } 512*0Sstevel@tonic-gate } 513*0Sstevel@tonic-gate 514*0Sstevel@tonic-gate /* 515*0Sstevel@tonic-gate * return if the string is too long or if 516*0Sstevel@tonic-gate * the '=' isn't found 517*0Sstevel@tonic-gate */ 518*0Sstevel@tonic-gate if (i >= len || str[i] != '=') { 519*0Sstevel@tonic-gate return (-1); 520*0Sstevel@tonic-gate } 521*0Sstevel@tonic-gate i++; 522*0Sstevel@tonic-gate if (i >= len) { 523*0Sstevel@tonic-gate /* 524*0Sstevel@tonic-gate * no string after the equal 525*0Sstevel@tonic-gate */ 526*0Sstevel@tonic-gate return (-1); 527*0Sstevel@tonic-gate } 528*0Sstevel@tonic-gate return (datadm_parse_nonnull_str(str + i, &sp_entry->spe_devname)); 529*0Sstevel@tonic-gate } 530*0Sstevel@tonic-gate 531*0Sstevel@tonic-gate static int 532*0Sstevel@tonic-gate datadm_parse_api_version(char *str, datadm_sp_entry_t *sp_entry) 533*0Sstevel@tonic-gate { 534*0Sstevel@tonic-gate return (datadm_parse_version(str, &sp_entry->spe_api_version)); 535*0Sstevel@tonic-gate } 536*0Sstevel@tonic-gate 537*0Sstevel@tonic-gate static int 538*0Sstevel@tonic-gate datadm_parse_threadsafe(char *str, datadm_sp_entry_t *sp_entry) 539*0Sstevel@tonic-gate { 540*0Sstevel@tonic-gate int retval = 0; 541*0Sstevel@tonic-gate 542*0Sstevel@tonic-gate if (strcmp(str, "threadsafe") == 0) { 543*0Sstevel@tonic-gate sp_entry->spe_threadsafe = 1; 544*0Sstevel@tonic-gate } else if (strcmp(str, "nonthreadsafe") == 0) { 545*0Sstevel@tonic-gate sp_entry->spe_threadsafe = 0; 546*0Sstevel@tonic-gate } else { 547*0Sstevel@tonic-gate retval = -1; 548*0Sstevel@tonic-gate } 549*0Sstevel@tonic-gate return (retval); 550*0Sstevel@tonic-gate } 551*0Sstevel@tonic-gate 552*0Sstevel@tonic-gate static int 553*0Sstevel@tonic-gate datadm_parse_default(char *str, datadm_sp_entry_t *sp_entry) 554*0Sstevel@tonic-gate { 555*0Sstevel@tonic-gate int retval = 0; 556*0Sstevel@tonic-gate 557*0Sstevel@tonic-gate if (strcmp(str, "default") == 0) { 558*0Sstevel@tonic-gate sp_entry->spe_default = 1; 559*0Sstevel@tonic-gate } else if (strcmp(str, "nondefault") == 0) { 560*0Sstevel@tonic-gate sp_entry->spe_default = 0; 561*0Sstevel@tonic-gate } else { 562*0Sstevel@tonic-gate retval = -1; 563*0Sstevel@tonic-gate } 564*0Sstevel@tonic-gate return (retval); 565*0Sstevel@tonic-gate } 566*0Sstevel@tonic-gate 567*0Sstevel@tonic-gate static int 568*0Sstevel@tonic-gate datadm_parse_libpath(char *str, datadm_sp_entry_t *sp_entry) 569*0Sstevel@tonic-gate { 570*0Sstevel@tonic-gate return (datadm_parse_nonnull_str(str, &sp_entry->spe_libpath)); 571*0Sstevel@tonic-gate } 572*0Sstevel@tonic-gate 573*0Sstevel@tonic-gate static int 574*0Sstevel@tonic-gate datadm_parse_sp_version(char *str, datadm_sp_entry_t *sp_entry) 575*0Sstevel@tonic-gate { 576*0Sstevel@tonic-gate return (datadm_parse_version(str, &sp_entry->spe_sp_version)); 577*0Sstevel@tonic-gate } 578*0Sstevel@tonic-gate 579*0Sstevel@tonic-gate static int 580*0Sstevel@tonic-gate datadm_parse_sp_data(char *str, datadm_sp_entry_t *sp_entry) 581*0Sstevel@tonic-gate { 582*0Sstevel@tonic-gate return (datadm_parse_generic_str(str, &sp_entry->spe_sp_data)); 583*0Sstevel@tonic-gate } 584*0Sstevel@tonic-gate 585*0Sstevel@tonic-gate static void 586*0Sstevel@tonic-gate datadm_enqueue_entry(datadm_list_t *list, datadm_entry_t *entry) 587*0Sstevel@tonic-gate { 588*0Sstevel@tonic-gate if (list->dl_head == NULL) { 589*0Sstevel@tonic-gate list->dl_head = entry; 590*0Sstevel@tonic-gate list->dl_tail = entry; 591*0Sstevel@tonic-gate list->dl_count = 1; 592*0Sstevel@tonic-gate } else { 593*0Sstevel@tonic-gate list->dl_tail->de_next = entry; 594*0Sstevel@tonic-gate list->dl_tail = entry; 595*0Sstevel@tonic-gate list->dl_count++; 596*0Sstevel@tonic-gate } 597*0Sstevel@tonic-gate } 598*0Sstevel@tonic-gate 599*0Sstevel@tonic-gate /* 600*0Sstevel@tonic-gate * iterates through the list applying func on each element. 601*0Sstevel@tonic-gate * break and return if func returns non-zero. 602*0Sstevel@tonic-gate */ 603*0Sstevel@tonic-gate static int 604*0Sstevel@tonic-gate datadm_walk_list(datadm_list_t *list, int (*func)(datadm_entry_t *, void *), 605*0Sstevel@tonic-gate void *arg) 606*0Sstevel@tonic-gate { 607*0Sstevel@tonic-gate datadm_entry_t *entry; 608*0Sstevel@tonic-gate int retval = 0; 609*0Sstevel@tonic-gate 610*0Sstevel@tonic-gate entry = list->dl_head; 611*0Sstevel@tonic-gate while (entry != NULL) { 612*0Sstevel@tonic-gate retval = (*func)(entry, arg); 613*0Sstevel@tonic-gate if (retval != 0) break; 614*0Sstevel@tonic-gate entry = entry->de_next; 615*0Sstevel@tonic-gate } 616*0Sstevel@tonic-gate return (retval); 617*0Sstevel@tonic-gate } 618*0Sstevel@tonic-gate 619*0Sstevel@tonic-gate /* 620*0Sstevel@tonic-gate * iterates through the list applying free_func to each element. 621*0Sstevel@tonic-gate * list becomes empty when the function returns. 622*0Sstevel@tonic-gate */ 623*0Sstevel@tonic-gate static void 624*0Sstevel@tonic-gate datadm_free_list(datadm_list_t *list, void (*free_func)(datadm_entry_t *)) 625*0Sstevel@tonic-gate { 626*0Sstevel@tonic-gate while (list->dl_head != NULL) { 627*0Sstevel@tonic-gate datadm_entry_t *entry; 628*0Sstevel@tonic-gate 629*0Sstevel@tonic-gate entry = list->dl_head; 630*0Sstevel@tonic-gate list->dl_head = entry->de_next; 631*0Sstevel@tonic-gate (*free_func)(entry); 632*0Sstevel@tonic-gate } 633*0Sstevel@tonic-gate list->dl_count = 0; 634*0Sstevel@tonic-gate list->dl_tail = NULL; 635*0Sstevel@tonic-gate } 636*0Sstevel@tonic-gate 637*0Sstevel@tonic-gate static datadm_sp_entry_t * 638*0Sstevel@tonic-gate datadm_alloc_sp_entry(void) 639*0Sstevel@tonic-gate { 640*0Sstevel@tonic-gate datadm_sp_entry_t *sp_entry; 641*0Sstevel@tonic-gate 642*0Sstevel@tonic-gate sp_entry = (datadm_sp_entry_t *)malloc(sizeof (*sp_entry)); 643*0Sstevel@tonic-gate if (sp_entry == NULL) { 644*0Sstevel@tonic-gate return (NULL); 645*0Sstevel@tonic-gate } 646*0Sstevel@tonic-gate bzero(sp_entry, sizeof (*sp_entry)); 647*0Sstevel@tonic-gate return (sp_entry); 648*0Sstevel@tonic-gate } 649*0Sstevel@tonic-gate 650*0Sstevel@tonic-gate static void 651*0Sstevel@tonic-gate datadm_free_sp_entry(datadm_sp_entry_t *sp_entry) 652*0Sstevel@tonic-gate { 653*0Sstevel@tonic-gate if (sp_entry->spe_devname != NULL) { 654*0Sstevel@tonic-gate free(sp_entry->spe_devname); 655*0Sstevel@tonic-gate sp_entry->spe_devname = NULL; 656*0Sstevel@tonic-gate } 657*0Sstevel@tonic-gate if (sp_entry->spe_api_version.dv_name != NULL) { 658*0Sstevel@tonic-gate free(sp_entry->spe_api_version.dv_name); 659*0Sstevel@tonic-gate sp_entry->spe_api_version.dv_name = NULL; 660*0Sstevel@tonic-gate } 661*0Sstevel@tonic-gate sp_entry->spe_api_version.dv_major = 0; 662*0Sstevel@tonic-gate sp_entry->spe_api_version.dv_minor = 0; 663*0Sstevel@tonic-gate sp_entry->spe_threadsafe = 0; 664*0Sstevel@tonic-gate sp_entry->spe_default = 0; 665*0Sstevel@tonic-gate if (sp_entry->spe_libpath != NULL) { 666*0Sstevel@tonic-gate free(sp_entry->spe_libpath); 667*0Sstevel@tonic-gate sp_entry->spe_libpath = NULL; 668*0Sstevel@tonic-gate } 669*0Sstevel@tonic-gate if (sp_entry->spe_sp_version.dv_name != NULL) { 670*0Sstevel@tonic-gate free(sp_entry->spe_sp_version.dv_name); 671*0Sstevel@tonic-gate sp_entry->spe_sp_version.dv_name = NULL; 672*0Sstevel@tonic-gate } 673*0Sstevel@tonic-gate sp_entry->spe_sp_version.dv_major = 0; 674*0Sstevel@tonic-gate sp_entry->spe_sp_version.dv_minor = 0; 675*0Sstevel@tonic-gate if (sp_entry->spe_sp_data != NULL) { 676*0Sstevel@tonic-gate free(sp_entry->spe_sp_data); 677*0Sstevel@tonic-gate sp_entry->spe_sp_data = NULL; 678*0Sstevel@tonic-gate } 679*0Sstevel@tonic-gate free(sp_entry); 680*0Sstevel@tonic-gate } 681*0Sstevel@tonic-gate 682*0Sstevel@tonic-gate static int 683*0Sstevel@tonic-gate datadm_str_match(char *s1, char *s2) 684*0Sstevel@tonic-gate { 685*0Sstevel@tonic-gate if (s1 == NULL || s2 == NULL) { 686*0Sstevel@tonic-gate if (s1 != s2) { 687*0Sstevel@tonic-gate return (0); 688*0Sstevel@tonic-gate } 689*0Sstevel@tonic-gate } else { 690*0Sstevel@tonic-gate if (strcmp(s1, s2) != 0) { 691*0Sstevel@tonic-gate return (0); 692*0Sstevel@tonic-gate } 693*0Sstevel@tonic-gate } 694*0Sstevel@tonic-gate return (1); 695*0Sstevel@tonic-gate } 696*0Sstevel@tonic-gate 697*0Sstevel@tonic-gate static int 698*0Sstevel@tonic-gate datadm_version_match(datadm_version_t *v1, datadm_version_t *v2) 699*0Sstevel@tonic-gate { 700*0Sstevel@tonic-gate if (!datadm_str_match(v1->dv_name, v2->dv_name)) { 701*0Sstevel@tonic-gate return (0); 702*0Sstevel@tonic-gate } 703*0Sstevel@tonic-gate if (v1->dv_major != v2->dv_major) { 704*0Sstevel@tonic-gate return (0); 705*0Sstevel@tonic-gate } 706*0Sstevel@tonic-gate if (v1->dv_minor != v2->dv_minor) { 707*0Sstevel@tonic-gate return (0); 708*0Sstevel@tonic-gate } 709*0Sstevel@tonic-gate return (1); 710*0Sstevel@tonic-gate } 711*0Sstevel@tonic-gate 712*0Sstevel@tonic-gate static int 713*0Sstevel@tonic-gate datadm_sp_entry_match(datadm_sp_entry_t *sp1, datadm_sp_entry_t *sp2) 714*0Sstevel@tonic-gate { 715*0Sstevel@tonic-gate if (!datadm_str_match(sp1->spe_devname, sp2->spe_devname)) { 716*0Sstevel@tonic-gate return (0); 717*0Sstevel@tonic-gate } 718*0Sstevel@tonic-gate if (!datadm_version_match(&sp1->spe_api_version, 719*0Sstevel@tonic-gate &sp2->spe_api_version)) { 720*0Sstevel@tonic-gate return (0); 721*0Sstevel@tonic-gate } 722*0Sstevel@tonic-gate if (sp1->spe_threadsafe != sp2->spe_threadsafe) { 723*0Sstevel@tonic-gate return (0); 724*0Sstevel@tonic-gate } 725*0Sstevel@tonic-gate if (sp2->spe_default != sp2->spe_default) { 726*0Sstevel@tonic-gate return (0); 727*0Sstevel@tonic-gate } 728*0Sstevel@tonic-gate if (!datadm_str_match(sp1->spe_libpath, sp2->spe_libpath)) { 729*0Sstevel@tonic-gate return (0); 730*0Sstevel@tonic-gate } 731*0Sstevel@tonic-gate if (!datadm_version_match(&sp1->spe_sp_version, 732*0Sstevel@tonic-gate &sp2->spe_sp_version)) { 733*0Sstevel@tonic-gate return (0); 734*0Sstevel@tonic-gate } 735*0Sstevel@tonic-gate if (!datadm_str_match(sp1->spe_sp_data, sp2->spe_sp_data)) { 736*0Sstevel@tonic-gate return (0); 737*0Sstevel@tonic-gate } 738*0Sstevel@tonic-gate return (1); 739*0Sstevel@tonic-gate } 740*0Sstevel@tonic-gate 741*0Sstevel@tonic-gate static datadm_ia_entry_t * 742*0Sstevel@tonic-gate datadm_alloc_ia_entry(void) 743*0Sstevel@tonic-gate { 744*0Sstevel@tonic-gate datadm_ia_entry_t *ia_entry; 745*0Sstevel@tonic-gate 746*0Sstevel@tonic-gate ia_entry = (datadm_ia_entry_t *)malloc(sizeof (*ia_entry)); 747*0Sstevel@tonic-gate if (ia_entry == NULL) { 748*0Sstevel@tonic-gate return (NULL); 749*0Sstevel@tonic-gate } 750*0Sstevel@tonic-gate bzero(ia_entry, sizeof (*ia_entry)); 751*0Sstevel@tonic-gate return (ia_entry); 752*0Sstevel@tonic-gate } 753*0Sstevel@tonic-gate 754*0Sstevel@tonic-gate static void 755*0Sstevel@tonic-gate datadm_free_ia_entry(datadm_ia_entry_t *ia_entry) 756*0Sstevel@tonic-gate { 757*0Sstevel@tonic-gate free(ia_entry); 758*0Sstevel@tonic-gate } 759*0Sstevel@tonic-gate 760*0Sstevel@tonic-gate static datadm_hca_entry_t * 761*0Sstevel@tonic-gate datadm_alloc_hca_entry(void) 762*0Sstevel@tonic-gate { 763*0Sstevel@tonic-gate datadm_hca_entry_t *hca_entry; 764*0Sstevel@tonic-gate 765*0Sstevel@tonic-gate hca_entry = (datadm_hca_entry_t *)malloc(sizeof (*hca_entry)); 766*0Sstevel@tonic-gate if (hca_entry == NULL) { 767*0Sstevel@tonic-gate return (NULL); 768*0Sstevel@tonic-gate } 769*0Sstevel@tonic-gate bzero(hca_entry, sizeof (*hca_entry)); 770*0Sstevel@tonic-gate return (hca_entry); 771*0Sstevel@tonic-gate } 772*0Sstevel@tonic-gate 773*0Sstevel@tonic-gate static void 774*0Sstevel@tonic-gate datadm_free_hca_entry(datadm_hca_entry_t *hca_entry) 775*0Sstevel@tonic-gate { 776*0Sstevel@tonic-gate if (hca_entry->he_name != NULL) { 777*0Sstevel@tonic-gate free(hca_entry->he_name); 778*0Sstevel@tonic-gate hca_entry->he_name = NULL; 779*0Sstevel@tonic-gate } 780*0Sstevel@tonic-gate datadm_free_list(&hca_entry->he_sp_list, 781*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_sp_entry); 782*0Sstevel@tonic-gate datadm_free_list(&hca_entry->he_ia_list, 783*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_ia_entry); 784*0Sstevel@tonic-gate free(hca_entry); 785*0Sstevel@tonic-gate } 786*0Sstevel@tonic-gate 787*0Sstevel@tonic-gate static int 788*0Sstevel@tonic-gate datadm_hca_entry_match(datadm_hca_entry_t *h1, datadm_hca_entry_t *h2) 789*0Sstevel@tonic-gate { 790*0Sstevel@tonic-gate if (!datadm_str_match(h1->he_name, h2->he_name)) { 791*0Sstevel@tonic-gate return (0); 792*0Sstevel@tonic-gate } 793*0Sstevel@tonic-gate return (1); 794*0Sstevel@tonic-gate } 795*0Sstevel@tonic-gate 796*0Sstevel@tonic-gate static int 797*0Sstevel@tonic-gate datadm_hca_entry_find(datadm_hca_entry_t *h1, datadm_hca_find_t *hf) 798*0Sstevel@tonic-gate { 799*0Sstevel@tonic-gate if (datadm_str_match(h1->he_name, hf->hf_sp_entry->spe_devname)) { 800*0Sstevel@tonic-gate hf->hf_hca_entry = h1; 801*0Sstevel@tonic-gate return (1); 802*0Sstevel@tonic-gate } 803*0Sstevel@tonic-gate return (0); 804*0Sstevel@tonic-gate } 805*0Sstevel@tonic-gate 806*0Sstevel@tonic-gate static int 807*0Sstevel@tonic-gate datadm_ia_entry_find(datadm_ia_entry_t *i1, datadm_ia_find_t *iaf) 808*0Sstevel@tonic-gate { 809*0Sstevel@tonic-gate if (i1->iae_devnum == iaf->if_ia_devnum) { 810*0Sstevel@tonic-gate iaf->if_ia_entry = i1; 811*0Sstevel@tonic-gate return (1); 812*0Sstevel@tonic-gate } 813*0Sstevel@tonic-gate return (0); 814*0Sstevel@tonic-gate } 815*0Sstevel@tonic-gate 816*0Sstevel@tonic-gate static datadm_cmnt_entry_t * 817*0Sstevel@tonic-gate datadm_alloc_cmnt_entry(void) 818*0Sstevel@tonic-gate { 819*0Sstevel@tonic-gate datadm_cmnt_entry_t *cmnt_entry; 820*0Sstevel@tonic-gate 821*0Sstevel@tonic-gate cmnt_entry = (datadm_cmnt_entry_t *)malloc(sizeof (*cmnt_entry)); 822*0Sstevel@tonic-gate if (cmnt_entry == NULL) { 823*0Sstevel@tonic-gate return (NULL); 824*0Sstevel@tonic-gate } 825*0Sstevel@tonic-gate bzero(cmnt_entry, sizeof (*cmnt_entry)); 826*0Sstevel@tonic-gate return (cmnt_entry); 827*0Sstevel@tonic-gate } 828*0Sstevel@tonic-gate 829*0Sstevel@tonic-gate static void 830*0Sstevel@tonic-gate datadm_free_cmnt_entry(datadm_cmnt_entry_t *cmnt_entry) 831*0Sstevel@tonic-gate { 832*0Sstevel@tonic-gate if (cmnt_entry->cmnt_line != NULL) { 833*0Sstevel@tonic-gate free(cmnt_entry->cmnt_line); 834*0Sstevel@tonic-gate cmnt_entry->cmnt_line = NULL; 835*0Sstevel@tonic-gate } 836*0Sstevel@tonic-gate free(cmnt_entry); 837*0Sstevel@tonic-gate } 838*0Sstevel@tonic-gate 839*0Sstevel@tonic-gate /* 840*0Sstevel@tonic-gate * tokenizes a line and strips off the quotes from quoted strings 841*0Sstevel@tonic-gate */ 842*0Sstevel@tonic-gate static int 843*0Sstevel@tonic-gate datadm_parse_line(char *line_buf, char *tokens[], int *token_count) 844*0Sstevel@tonic-gate { 845*0Sstevel@tonic-gate int len, i; 846*0Sstevel@tonic-gate int count = 0; 847*0Sstevel@tonic-gate char *start = NULL; 848*0Sstevel@tonic-gate 849*0Sstevel@tonic-gate /* the line must not be longer than DATADM_LINESZ */ 850*0Sstevel@tonic-gate len = strlen(line_buf); 851*0Sstevel@tonic-gate if (line_buf[len - 1] != '\n') { 852*0Sstevel@tonic-gate return (-1); 853*0Sstevel@tonic-gate } 854*0Sstevel@tonic-gate /* discard blank lines and comments */ 855*0Sstevel@tonic-gate if (len == 1) { 856*0Sstevel@tonic-gate *token_count = 0; 857*0Sstevel@tonic-gate return (0); 858*0Sstevel@tonic-gate } 859*0Sstevel@tonic-gate if (len >= 2 && line_buf[0] == '#') { 860*0Sstevel@tonic-gate *token_count = 0; 861*0Sstevel@tonic-gate return (0); 862*0Sstevel@tonic-gate } 863*0Sstevel@tonic-gate /* removes the new line */ 864*0Sstevel@tonic-gate line_buf[len - 1] = '\0'; 865*0Sstevel@tonic-gate len--; 866*0Sstevel@tonic-gate 867*0Sstevel@tonic-gate for (i = 0; i < len; i++) { 868*0Sstevel@tonic-gate if (start != NULL) { 869*0Sstevel@tonic-gate /* 870*0Sstevel@tonic-gate * start points to the start of 871*0Sstevel@tonic-gate * a new token. if start is '"', 872*0Sstevel@tonic-gate * we should expect a quoted 873*0Sstevel@tonic-gate * string. 874*0Sstevel@tonic-gate */ 875*0Sstevel@tonic-gate if (*start == '\"') { 876*0Sstevel@tonic-gate /* 877*0Sstevel@tonic-gate * keep scanning until we 878*0Sstevel@tonic-gate * hit the end quote. 879*0Sstevel@tonic-gate */ 880*0Sstevel@tonic-gate if (line_buf[i] != '\"') { 881*0Sstevel@tonic-gate continue; 882*0Sstevel@tonic-gate } 883*0Sstevel@tonic-gate /* 884*0Sstevel@tonic-gate * skip past the start quote 885*0Sstevel@tonic-gate */ 886*0Sstevel@tonic-gate start++; 887*0Sstevel@tonic-gate } else { 888*0Sstevel@tonic-gate /* 889*0Sstevel@tonic-gate * our token is not a quoted 890*0Sstevel@tonic-gate * string. our token ends only 891*0Sstevel@tonic-gate * when we hit a whitespace. 892*0Sstevel@tonic-gate */ 893*0Sstevel@tonic-gate if (!isspace(line_buf[i])) { 894*0Sstevel@tonic-gate continue; 895*0Sstevel@tonic-gate } 896*0Sstevel@tonic-gate } 897*0Sstevel@tonic-gate /* 898*0Sstevel@tonic-gate * nullify the end quote (if any) 899*0Sstevel@tonic-gate * and update the tokens array. 900*0Sstevel@tonic-gate */ 901*0Sstevel@tonic-gate line_buf[i] = '\0'; 902*0Sstevel@tonic-gate tokens[count] = start; 903*0Sstevel@tonic-gate start = NULL; 904*0Sstevel@tonic-gate count++; 905*0Sstevel@tonic-gate } else { 906*0Sstevel@tonic-gate /* 907*0Sstevel@tonic-gate * skip whitespaces 908*0Sstevel@tonic-gate */ 909*0Sstevel@tonic-gate if (isspace(line_buf[i])) { 910*0Sstevel@tonic-gate continue; 911*0Sstevel@tonic-gate } else { 912*0Sstevel@tonic-gate start = &line_buf[i]; 913*0Sstevel@tonic-gate } 914*0Sstevel@tonic-gate } 915*0Sstevel@tonic-gate if (count == DATADM_MAX_TOKENS) { 916*0Sstevel@tonic-gate start = NULL; 917*0Sstevel@tonic-gate break; 918*0Sstevel@tonic-gate } 919*0Sstevel@tonic-gate } 920*0Sstevel@tonic-gate if (start != NULL) { 921*0Sstevel@tonic-gate tokens[count] = start; 922*0Sstevel@tonic-gate start = NULL; 923*0Sstevel@tonic-gate count++; 924*0Sstevel@tonic-gate } 925*0Sstevel@tonic-gate *token_count = count; 926*0Sstevel@tonic-gate return (0); 927*0Sstevel@tonic-gate } 928*0Sstevel@tonic-gate 929*0Sstevel@tonic-gate /* 930*0Sstevel@tonic-gate * attempts to save sp_entry into hca_list. 931*0Sstevel@tonic-gate * becomes no-op if sp entry already exists. 932*0Sstevel@tonic-gate * new hca entries and ia entries are created as needed. 933*0Sstevel@tonic-gate */ 934*0Sstevel@tonic-gate static int 935*0Sstevel@tonic-gate datadm_process_sp_entry(datadm_list_t *hca_list, datadm_sp_entry_t *sp_entry, 936*0Sstevel@tonic-gate int ia_devnum) 937*0Sstevel@tonic-gate { 938*0Sstevel@tonic-gate datadm_hca_find_t hca_find; 939*0Sstevel@tonic-gate datadm_ia_find_t ia_find; 940*0Sstevel@tonic-gate datadm_hca_entry_t *hca_entry; 941*0Sstevel@tonic-gate 942*0Sstevel@tonic-gate hca_find.hf_sp_entry = sp_entry; 943*0Sstevel@tonic-gate hca_find.hf_hca_entry = NULL; 944*0Sstevel@tonic-gate (void) datadm_walk_list(hca_list, (int (*)(datadm_entry_t *, void *)) 945*0Sstevel@tonic-gate datadm_hca_entry_find, (void *)&hca_find); 946*0Sstevel@tonic-gate 947*0Sstevel@tonic-gate if (hca_find.hf_hca_entry == NULL) { 948*0Sstevel@tonic-gate int dlen; 949*0Sstevel@tonic-gate 950*0Sstevel@tonic-gate /* 951*0Sstevel@tonic-gate * hca_entry not found, need to create 952*0Sstevel@tonic-gate * and insert one. 953*0Sstevel@tonic-gate */ 954*0Sstevel@tonic-gate hca_entry = datadm_alloc_hca_entry(); 955*0Sstevel@tonic-gate if (hca_entry == NULL) { 956*0Sstevel@tonic-gate return (-1); 957*0Sstevel@tonic-gate } 958*0Sstevel@tonic-gate dlen = strlen(sp_entry->spe_devname); 959*0Sstevel@tonic-gate hca_entry->he_name = (char *)malloc(dlen + 1); 960*0Sstevel@tonic-gate if (hca_entry->he_name == NULL) { 961*0Sstevel@tonic-gate datadm_free_hca_entry(hca_entry); 962*0Sstevel@tonic-gate return (-1); 963*0Sstevel@tonic-gate } 964*0Sstevel@tonic-gate (void) strcpy(hca_entry->he_name, sp_entry->spe_devname); 965*0Sstevel@tonic-gate datadm_enqueue_entry(hca_list, (datadm_entry_t *)hca_entry); 966*0Sstevel@tonic-gate } else { 967*0Sstevel@tonic-gate hca_entry = hca_find.hf_hca_entry; 968*0Sstevel@tonic-gate } 969*0Sstevel@tonic-gate if (ia_devnum == -1) { 970*0Sstevel@tonic-gate goto put_sp_entry; 971*0Sstevel@tonic-gate } 972*0Sstevel@tonic-gate ia_find.if_ia_devnum = ia_devnum; 973*0Sstevel@tonic-gate ia_find.if_ia_entry = NULL; 974*0Sstevel@tonic-gate (void) datadm_walk_list(&hca_entry->he_ia_list, 975*0Sstevel@tonic-gate (int (*)(datadm_entry_t *, void *))datadm_ia_entry_find, &ia_find); 976*0Sstevel@tonic-gate 977*0Sstevel@tonic-gate if (ia_find.if_ia_entry == NULL) { 978*0Sstevel@tonic-gate datadm_ia_entry_t *ia_entry; 979*0Sstevel@tonic-gate 980*0Sstevel@tonic-gate /* 981*0Sstevel@tonic-gate * ia_entry not found, need to create 982*0Sstevel@tonic-gate * and insert one. 983*0Sstevel@tonic-gate */ 984*0Sstevel@tonic-gate ia_entry = datadm_alloc_ia_entry(); 985*0Sstevel@tonic-gate if (ia_entry == NULL) { 986*0Sstevel@tonic-gate return (-1); 987*0Sstevel@tonic-gate } 988*0Sstevel@tonic-gate ia_entry->iae_devnum = ia_devnum; 989*0Sstevel@tonic-gate datadm_enqueue_entry(&hca_entry->he_ia_list, 990*0Sstevel@tonic-gate (datadm_entry_t *)ia_entry); 991*0Sstevel@tonic-gate } 992*0Sstevel@tonic-gate 993*0Sstevel@tonic-gate put_sp_entry:; 994*0Sstevel@tonic-gate 995*0Sstevel@tonic-gate if (datadm_walk_list(&hca_entry->he_sp_list, 996*0Sstevel@tonic-gate (int (*)(datadm_entry_t *, void *))datadm_sp_entry_match, 997*0Sstevel@tonic-gate (void *)sp_entry)) { 998*0Sstevel@tonic-gate return (1); 999*0Sstevel@tonic-gate } else { 1000*0Sstevel@tonic-gate /* 1001*0Sstevel@tonic-gate * only insert sp_entry if it is not found. 1002*0Sstevel@tonic-gate */ 1003*0Sstevel@tonic-gate datadm_enqueue_entry(&hca_entry->he_sp_list, 1004*0Sstevel@tonic-gate (datadm_entry_t *)sp_entry); 1005*0Sstevel@tonic-gate } 1006*0Sstevel@tonic-gate return (0); 1007*0Sstevel@tonic-gate } 1008*0Sstevel@tonic-gate 1009*0Sstevel@tonic-gate /* 1010*0Sstevel@tonic-gate * parses service_provider.conf 1011*0Sstevel@tonic-gate */ 1012*0Sstevel@tonic-gate static int 1013*0Sstevel@tonic-gate datadm_parse_sp_conf(datadm_list_t *hca_list) 1014*0Sstevel@tonic-gate { 1015*0Sstevel@tonic-gate datadm_sp_entry_t *sp_entry; 1016*0Sstevel@tonic-gate FILE *sp_file; 1017*0Sstevel@tonic-gate char *sp_conf = datadm_args.da_sp_conf; 1018*0Sstevel@tonic-gate char *tokens[DATADM_MAX_TOKENS]; 1019*0Sstevel@tonic-gate char line_buf[DATADM_LINESZ]; 1020*0Sstevel@tonic-gate int retval = 0; 1021*0Sstevel@tonic-gate int token_count = 0; 1022*0Sstevel@tonic-gate int line_count = 0; 1023*0Sstevel@tonic-gate 1024*0Sstevel@tonic-gate sp_file = fopen(sp_conf, "r"); 1025*0Sstevel@tonic-gate if (sp_file == NULL) { 1026*0Sstevel@tonic-gate (void) fprintf(stderr, 1027*0Sstevel@tonic-gate gettext("datadm: cannot open %s\n"), sp_conf); 1028*0Sstevel@tonic-gate return (-1); 1029*0Sstevel@tonic-gate } 1030*0Sstevel@tonic-gate 1031*0Sstevel@tonic-gate for (;;) { 1032*0Sstevel@tonic-gate bzero(line_buf, DATADM_LINESZ); 1033*0Sstevel@tonic-gate if (fgets(line_buf, DATADM_LINESZ, sp_file) == NULL) { 1034*0Sstevel@tonic-gate break; 1035*0Sstevel@tonic-gate } 1036*0Sstevel@tonic-gate token_count = 0; 1037*0Sstevel@tonic-gate line_count++; 1038*0Sstevel@tonic-gate retval = datadm_parse_line(line_buf, tokens, &token_count); 1039*0Sstevel@tonic-gate if (retval != 0) { 1040*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1041*0Sstevel@tonic-gate "datadm: %s: line %d exceeded max length %d\n"), 1042*0Sstevel@tonic-gate sp_conf, line_count, DATADM_LINESZ); 1043*0Sstevel@tonic-gate break; 1044*0Sstevel@tonic-gate } 1045*0Sstevel@tonic-gate if (token_count == 0) continue; 1046*0Sstevel@tonic-gate if (token_count == DATADM_NUM_SP_TOKENS) { 1047*0Sstevel@tonic-gate int i = 0; 1048*0Sstevel@tonic-gate 1049*0Sstevel@tonic-gate sp_entry = datadm_alloc_sp_entry(); 1050*0Sstevel@tonic-gate if (sp_entry == NULL) { 1051*0Sstevel@tonic-gate retval = -1; 1052*0Sstevel@tonic-gate break; 1053*0Sstevel@tonic-gate } 1054*0Sstevel@tonic-gate 1055*0Sstevel@tonic-gate /* 1056*0Sstevel@tonic-gate * sp_entry gets filled incrementally by 1057*0Sstevel@tonic-gate * each parsing function 1058*0Sstevel@tonic-gate */ 1059*0Sstevel@tonic-gate for (i = 0; i < DATADM_NUM_SP_TOKENS && 1060*0Sstevel@tonic-gate retval == 0; i++) { 1061*0Sstevel@tonic-gate retval = (*datadm_sp_parse_funcs[i]) 1062*0Sstevel@tonic-gate (tokens[i], (void *)sp_entry); 1063*0Sstevel@tonic-gate } 1064*0Sstevel@tonic-gate if (retval != 0) { 1065*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1066*0Sstevel@tonic-gate "datadm: parse error: %s, " 1067*0Sstevel@tonic-gate "line %d, token: %s\n"), 1068*0Sstevel@tonic-gate sp_conf, line_count, tokens[i - 1]); 1069*0Sstevel@tonic-gate datadm_free_sp_entry(sp_entry); 1070*0Sstevel@tonic-gate sp_entry = NULL; 1071*0Sstevel@tonic-gate break; 1072*0Sstevel@tonic-gate } 1073*0Sstevel@tonic-gate 1074*0Sstevel@tonic-gate retval = datadm_process_sp_entry(hca_list, 1075*0Sstevel@tonic-gate sp_entry, -1); 1076*0Sstevel@tonic-gate if (retval != 0) { 1077*0Sstevel@tonic-gate datadm_free_sp_entry(sp_entry); 1078*0Sstevel@tonic-gate if (retval == 1) { 1079*0Sstevel@tonic-gate retval = 0; 1080*0Sstevel@tonic-gate } else { 1081*0Sstevel@tonic-gate break; 1082*0Sstevel@tonic-gate } 1083*0Sstevel@tonic-gate } 1084*0Sstevel@tonic-gate } else { 1085*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1086*0Sstevel@tonic-gate "datadm: parse error: %s, line %d, " 1087*0Sstevel@tonic-gate "# of tokens: %d, expected %d\n"), sp_conf, 1088*0Sstevel@tonic-gate line_count, token_count, DATADM_NUM_SP_TOKENS); 1089*0Sstevel@tonic-gate retval = -1; 1090*0Sstevel@tonic-gate break; 1091*0Sstevel@tonic-gate } 1092*0Sstevel@tonic-gate } 1093*0Sstevel@tonic-gate if (retval != 0) { 1094*0Sstevel@tonic-gate datadm_free_list(hca_list, 1095*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1096*0Sstevel@tonic-gate } 1097*0Sstevel@tonic-gate (void) fclose(sp_file); 1098*0Sstevel@tonic-gate return (retval); 1099*0Sstevel@tonic-gate } 1100*0Sstevel@tonic-gate 1101*0Sstevel@tonic-gate /* 1102*0Sstevel@tonic-gate * parses dat.conf 1103*0Sstevel@tonic-gate */ 1104*0Sstevel@tonic-gate static int 1105*0Sstevel@tonic-gate datadm_parse_dat_conf(datadm_list_t *hca_list) 1106*0Sstevel@tonic-gate { 1107*0Sstevel@tonic-gate boolean_t save_header = B_TRUE; 1108*0Sstevel@tonic-gate datadm_sp_entry_t *sp_entry; 1109*0Sstevel@tonic-gate FILE *dat_file; 1110*0Sstevel@tonic-gate char *dat_conf = datadm_args.da_dat_conf; 1111*0Sstevel@tonic-gate char *tokens[DATADM_MAX_TOKENS]; 1112*0Sstevel@tonic-gate char line_buf[DATADM_LINESZ]; 1113*0Sstevel@tonic-gate int retval = 0; 1114*0Sstevel@tonic-gate int token_count = 0; 1115*0Sstevel@tonic-gate int line_count = 0; 1116*0Sstevel@tonic-gate 1117*0Sstevel@tonic-gate dat_file = fopen(dat_conf, "r"); 1118*0Sstevel@tonic-gate if (dat_file == NULL) { 1119*0Sstevel@tonic-gate /* dat.conf not existing is not an error for OP_ADD */ 1120*0Sstevel@tonic-gate if (datadm_args.da_op_type == DATADM_OP_ADD) { 1121*0Sstevel@tonic-gate return (0); 1122*0Sstevel@tonic-gate } 1123*0Sstevel@tonic-gate (void) fprintf(stderr, gettext("datadm: cannot open %s\n"), 1124*0Sstevel@tonic-gate dat_conf); 1125*0Sstevel@tonic-gate return (-1); 1126*0Sstevel@tonic-gate } 1127*0Sstevel@tonic-gate 1128*0Sstevel@tonic-gate for (;;) { 1129*0Sstevel@tonic-gate bzero(line_buf, DATADM_LINESZ); 1130*0Sstevel@tonic-gate if (fgets(line_buf, DATADM_LINESZ, dat_file) == NULL) { 1131*0Sstevel@tonic-gate break; 1132*0Sstevel@tonic-gate } 1133*0Sstevel@tonic-gate token_count = 0; 1134*0Sstevel@tonic-gate line_count++; 1135*0Sstevel@tonic-gate retval = datadm_parse_line(line_buf, tokens, &token_count); 1136*0Sstevel@tonic-gate if (retval != 0) { 1137*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1138*0Sstevel@tonic-gate "datadm: %s: line %d exceeded max length %d\n"), 1139*0Sstevel@tonic-gate dat_conf, line_count, DATADM_LINESZ); 1140*0Sstevel@tonic-gate break; 1141*0Sstevel@tonic-gate } 1142*0Sstevel@tonic-gate if (token_count == 0) { 1143*0Sstevel@tonic-gate datadm_cmnt_entry_t *cmnt_entry; 1144*0Sstevel@tonic-gate int cmnt_len; 1145*0Sstevel@tonic-gate 1146*0Sstevel@tonic-gate /* 1147*0Sstevel@tonic-gate * comments are saved only if they are 1148*0Sstevel@tonic-gate * at the top of dat.conf. 1149*0Sstevel@tonic-gate */ 1150*0Sstevel@tonic-gate if (!save_header) continue; 1151*0Sstevel@tonic-gate cmnt_entry = datadm_alloc_cmnt_entry(); 1152*0Sstevel@tonic-gate if (cmnt_entry == NULL) { 1153*0Sstevel@tonic-gate perror("datadm: malloc"); 1154*0Sstevel@tonic-gate retval = -1; 1155*0Sstevel@tonic-gate break; 1156*0Sstevel@tonic-gate } 1157*0Sstevel@tonic-gate cmnt_len = strlen(line_buf); 1158*0Sstevel@tonic-gate cmnt_entry->cmnt_line = (char *)malloc(cmnt_len + 1); 1159*0Sstevel@tonic-gate if (cmnt_entry->cmnt_line == NULL) { 1160*0Sstevel@tonic-gate perror("datadm: malloc"); 1161*0Sstevel@tonic-gate datadm_free_cmnt_entry(cmnt_entry); 1162*0Sstevel@tonic-gate retval = -1; 1163*0Sstevel@tonic-gate break; 1164*0Sstevel@tonic-gate } 1165*0Sstevel@tonic-gate (void) strncpy(cmnt_entry->cmnt_line, 1166*0Sstevel@tonic-gate line_buf, cmnt_len); 1167*0Sstevel@tonic-gate cmnt_entry->cmnt_line[cmnt_len] = '\0'; 1168*0Sstevel@tonic-gate datadm_enqueue_entry(&datadm_conf_header, 1169*0Sstevel@tonic-gate (datadm_entry_t *)cmnt_entry); 1170*0Sstevel@tonic-gate continue; 1171*0Sstevel@tonic-gate } 1172*0Sstevel@tonic-gate if (token_count == DATADM_NUM_DAT_TOKENS) { 1173*0Sstevel@tonic-gate int i = 0; 1174*0Sstevel@tonic-gate int ia_devnum = -1; 1175*0Sstevel@tonic-gate 1176*0Sstevel@tonic-gate /* 1177*0Sstevel@tonic-gate * we stop saving comment lines once 1178*0Sstevel@tonic-gate * we see the first valid line. 1179*0Sstevel@tonic-gate */ 1180*0Sstevel@tonic-gate save_header = B_FALSE; 1181*0Sstevel@tonic-gate sp_entry = datadm_alloc_sp_entry(); 1182*0Sstevel@tonic-gate if (sp_entry == NULL) { 1183*0Sstevel@tonic-gate retval = -1; 1184*0Sstevel@tonic-gate break; 1185*0Sstevel@tonic-gate } 1186*0Sstevel@tonic-gate 1187*0Sstevel@tonic-gate /* 1188*0Sstevel@tonic-gate * sp_entry gets filled incrementally by 1189*0Sstevel@tonic-gate * each parsing function 1190*0Sstevel@tonic-gate */ 1191*0Sstevel@tonic-gate for (i = 0; i < DATADM_NUM_DAT_TOKENS && 1192*0Sstevel@tonic-gate retval == 0; i++) { 1193*0Sstevel@tonic-gate void *arg; 1194*0Sstevel@tonic-gate 1195*0Sstevel@tonic-gate if (i == 0) { 1196*0Sstevel@tonic-gate /* 1197*0Sstevel@tonic-gate * the first token (ia name) 1198*0Sstevel@tonic-gate * does not belong to an 1199*0Sstevel@tonic-gate * sp_entry 1200*0Sstevel@tonic-gate */ 1201*0Sstevel@tonic-gate arg = (void *)&ia_devnum; 1202*0Sstevel@tonic-gate } else { 1203*0Sstevel@tonic-gate arg = (void *)sp_entry; 1204*0Sstevel@tonic-gate } 1205*0Sstevel@tonic-gate retval = (*datadm_dat_parse_funcs[i]) 1206*0Sstevel@tonic-gate (tokens[i], arg); 1207*0Sstevel@tonic-gate } 1208*0Sstevel@tonic-gate if (retval != 0) { 1209*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1210*0Sstevel@tonic-gate "datadm: parse error: %s, " 1211*0Sstevel@tonic-gate "line %d, token: %s\n"), dat_conf, 1212*0Sstevel@tonic-gate line_count, tokens[i - 1]); 1213*0Sstevel@tonic-gate datadm_free_sp_entry(sp_entry); 1214*0Sstevel@tonic-gate sp_entry = NULL; 1215*0Sstevel@tonic-gate break; 1216*0Sstevel@tonic-gate } 1217*0Sstevel@tonic-gate 1218*0Sstevel@tonic-gate /* 1219*0Sstevel@tonic-gate * we ignore the ibds in dat.conf if we are 1220*0Sstevel@tonic-gate * doing update 1221*0Sstevel@tonic-gate */ 1222*0Sstevel@tonic-gate if (datadm_args.da_op_type == DATADM_OP_UPDATE) { 1223*0Sstevel@tonic-gate ia_devnum = -1; 1224*0Sstevel@tonic-gate } 1225*0Sstevel@tonic-gate retval = datadm_process_sp_entry(hca_list, sp_entry, 1226*0Sstevel@tonic-gate ia_devnum); 1227*0Sstevel@tonic-gate if (retval != 0) { 1228*0Sstevel@tonic-gate datadm_free_sp_entry(sp_entry); 1229*0Sstevel@tonic-gate if (retval == 1) { 1230*0Sstevel@tonic-gate retval = 0; 1231*0Sstevel@tonic-gate } else { 1232*0Sstevel@tonic-gate break; 1233*0Sstevel@tonic-gate } 1234*0Sstevel@tonic-gate } 1235*0Sstevel@tonic-gate } else { 1236*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1237*0Sstevel@tonic-gate "datadm: parse error: %s, line %d, " 1238*0Sstevel@tonic-gate "# of tokens: %d, expected %d\n"), dat_conf, 1239*0Sstevel@tonic-gate line_count, token_count, DATADM_NUM_DAT_TOKENS); 1240*0Sstevel@tonic-gate retval = -1; 1241*0Sstevel@tonic-gate break; 1242*0Sstevel@tonic-gate } 1243*0Sstevel@tonic-gate } 1244*0Sstevel@tonic-gate if (retval != 0) { 1245*0Sstevel@tonic-gate datadm_free_list(&datadm_conf_header, 1246*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry); 1247*0Sstevel@tonic-gate datadm_free_list(hca_list, 1248*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1249*0Sstevel@tonic-gate } 1250*0Sstevel@tonic-gate (void) fclose(dat_file); 1251*0Sstevel@tonic-gate return (retval); 1252*0Sstevel@tonic-gate } 1253*0Sstevel@tonic-gate 1254*0Sstevel@tonic-gate /* 1255*0Sstevel@tonic-gate * discovers all ibd devices under a particular hca 1256*0Sstevel@tonic-gate */ 1257*0Sstevel@tonic-gate static int 1258*0Sstevel@tonic-gate datadm_fill_ia_list(datadm_hca_entry_t *hca, datadm_fill_ia_list_t *args) 1259*0Sstevel@tonic-gate { 1260*0Sstevel@tonic-gate di_node_t root_node; 1261*0Sstevel@tonic-gate di_node_t hca_node; 1262*0Sstevel@tonic-gate int retval = 0; 1263*0Sstevel@tonic-gate int sv4, sv6; 1264*0Sstevel@tonic-gate 1265*0Sstevel@tonic-gate root_node = args->ia_root_node; 1266*0Sstevel@tonic-gate sv4 = args->ia_sock_fd_v4; 1267*0Sstevel@tonic-gate sv6 = args->ia_sock_fd_v6; 1268*0Sstevel@tonic-gate 1269*0Sstevel@tonic-gate hca_node = di_drv_first_node(hca->he_name, root_node); 1270*0Sstevel@tonic-gate if (hca_node == DI_NODE_NIL) { 1271*0Sstevel@tonic-gate return (0); 1272*0Sstevel@tonic-gate } 1273*0Sstevel@tonic-gate while (hca_node != DI_NODE_NIL) { 1274*0Sstevel@tonic-gate di_node_t ibd_node; 1275*0Sstevel@tonic-gate 1276*0Sstevel@tonic-gate ibd_node = di_drv_first_node(DATADM_IA_NAME, hca_node); 1277*0Sstevel@tonic-gate while (ibd_node != DI_NODE_NIL) { 1278*0Sstevel@tonic-gate datadm_ia_find_t ia_find; 1279*0Sstevel@tonic-gate datadm_ia_entry_t *ia_entry; 1280*0Sstevel@tonic-gate struct lifreq req; 1281*0Sstevel@tonic-gate int devnum, rval; 1282*0Sstevel@tonic-gate 1283*0Sstevel@tonic-gate devnum = di_instance(ibd_node); 1284*0Sstevel@tonic-gate if (devnum == -1) { 1285*0Sstevel@tonic-gate ibd_node = di_drv_next_node(ibd_node); 1286*0Sstevel@tonic-gate continue; 1287*0Sstevel@tonic-gate } 1288*0Sstevel@tonic-gate 1289*0Sstevel@tonic-gate (void) snprintf(req.lifr_name, sizeof (req.lifr_name), 1290*0Sstevel@tonic-gate "%s%d", DATADM_IA_NAME, devnum); 1291*0Sstevel@tonic-gate /* 1292*0Sstevel@tonic-gate * we don't really need to know the ip address. 1293*0Sstevel@tonic-gate * we just want to check if the device is plumbed 1294*0Sstevel@tonic-gate * or not. 1295*0Sstevel@tonic-gate */ 1296*0Sstevel@tonic-gate rval = ioctl(sv4, SIOCGLIFADDR, (caddr_t)&req); 1297*0Sstevel@tonic-gate if (rval != 0) { 1298*0Sstevel@tonic-gate /* 1299*0Sstevel@tonic-gate * we try v6 if the v4 address isn't found. 1300*0Sstevel@tonic-gate */ 1301*0Sstevel@tonic-gate rval = ioctl(sv6, SIOCGLIFADDR, (caddr_t)&req); 1302*0Sstevel@tonic-gate if (rval != 0) { 1303*0Sstevel@tonic-gate ibd_node = di_drv_next_node(ibd_node); 1304*0Sstevel@tonic-gate continue; 1305*0Sstevel@tonic-gate } 1306*0Sstevel@tonic-gate } 1307*0Sstevel@tonic-gate ia_find.if_ia_devnum = devnum; 1308*0Sstevel@tonic-gate ia_find.if_ia_entry = NULL; 1309*0Sstevel@tonic-gate (void) datadm_walk_list(&hca->he_ia_list, 1310*0Sstevel@tonic-gate (int (*)(datadm_entry_t *, void *)) 1311*0Sstevel@tonic-gate datadm_ia_entry_find, &ia_find); 1312*0Sstevel@tonic-gate 1313*0Sstevel@tonic-gate if (ia_find.if_ia_entry == NULL) { 1314*0Sstevel@tonic-gate /* 1315*0Sstevel@tonic-gate * we insert an ia entry only if 1316*0Sstevel@tonic-gate * it is unique. 1317*0Sstevel@tonic-gate */ 1318*0Sstevel@tonic-gate ia_entry = datadm_alloc_ia_entry(); 1319*0Sstevel@tonic-gate if (ia_entry == NULL) { 1320*0Sstevel@tonic-gate retval = -1; 1321*0Sstevel@tonic-gate break; 1322*0Sstevel@tonic-gate } 1323*0Sstevel@tonic-gate ia_entry->iae_devnum = devnum; 1324*0Sstevel@tonic-gate datadm_enqueue_entry(&hca->he_ia_list, 1325*0Sstevel@tonic-gate (datadm_entry_t *)ia_entry); 1326*0Sstevel@tonic-gate } else { 1327*0Sstevel@tonic-gate ia_entry = ia_find.if_ia_entry; 1328*0Sstevel@tonic-gate } 1329*0Sstevel@tonic-gate ibd_node = di_drv_next_node(ibd_node); 1330*0Sstevel@tonic-gate } 1331*0Sstevel@tonic-gate hca_node = di_drv_next_node(hca_node); 1332*0Sstevel@tonic-gate } 1333*0Sstevel@tonic-gate if (retval != 0) { 1334*0Sstevel@tonic-gate datadm_free_list(&hca->he_ia_list, 1335*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_ia_entry); 1336*0Sstevel@tonic-gate } 1337*0Sstevel@tonic-gate return (0); 1338*0Sstevel@tonic-gate } 1339*0Sstevel@tonic-gate 1340*0Sstevel@tonic-gate /* 1341*0Sstevel@tonic-gate * used by OP_REMOVE to invalidate common sp entries between hl1 and hl2. 1342*0Sstevel@tonic-gate * invalid sp entries will be ignored by datadm_generate_dat_conf. 1343*0Sstevel@tonic-gate */ 1344*0Sstevel@tonic-gate static void 1345*0Sstevel@tonic-gate datadm_invalidate_common_sp_entries(datadm_list_t *hl1, datadm_list_t *hl2) 1346*0Sstevel@tonic-gate { 1347*0Sstevel@tonic-gate datadm_entry_t *he1, *he2; 1348*0Sstevel@tonic-gate 1349*0Sstevel@tonic-gate he1 = hl1->dl_head; 1350*0Sstevel@tonic-gate while (he1 != NULL) { 1351*0Sstevel@tonic-gate he2 = hl2->dl_head; 1352*0Sstevel@tonic-gate while (he2 != NULL) { 1353*0Sstevel@tonic-gate datadm_entry_t *se1, *se2; 1354*0Sstevel@tonic-gate 1355*0Sstevel@tonic-gate if (!datadm_hca_entry_match( 1356*0Sstevel@tonic-gate (datadm_hca_entry_t *)he1, 1357*0Sstevel@tonic-gate (datadm_hca_entry_t *)he2)) { 1358*0Sstevel@tonic-gate he2 = he2->de_next; 1359*0Sstevel@tonic-gate continue; 1360*0Sstevel@tonic-gate } 1361*0Sstevel@tonic-gate se1 = ((datadm_hca_entry_t *)he1)->he_sp_list.dl_head; 1362*0Sstevel@tonic-gate while (se1 != NULL) { 1363*0Sstevel@tonic-gate se2 = ((datadm_hca_entry_t *)he2)-> 1364*0Sstevel@tonic-gate he_sp_list.dl_head; 1365*0Sstevel@tonic-gate while (se2 != NULL) { 1366*0Sstevel@tonic-gate if (!datadm_sp_entry_match( 1367*0Sstevel@tonic-gate (datadm_sp_entry_t *)se1, 1368*0Sstevel@tonic-gate (datadm_sp_entry_t *)se2)) { 1369*0Sstevel@tonic-gate se2 = se2->de_next; 1370*0Sstevel@tonic-gate continue; 1371*0Sstevel@tonic-gate } 1372*0Sstevel@tonic-gate ((datadm_sp_entry_t *)se1)-> 1373*0Sstevel@tonic-gate spe_invalid = 1; 1374*0Sstevel@tonic-gate break; 1375*0Sstevel@tonic-gate } 1376*0Sstevel@tonic-gate se1 = se1->de_next; 1377*0Sstevel@tonic-gate } 1378*0Sstevel@tonic-gate break; 1379*0Sstevel@tonic-gate } 1380*0Sstevel@tonic-gate he1 = he1->de_next; 1381*0Sstevel@tonic-gate } 1382*0Sstevel@tonic-gate } 1383*0Sstevel@tonic-gate 1384*0Sstevel@tonic-gate /* 1385*0Sstevel@tonic-gate * applies datadm_fill_ia_list on each hca_list element 1386*0Sstevel@tonic-gate */ 1387*0Sstevel@tonic-gate static int 1388*0Sstevel@tonic-gate datadm_build_ia_lists(datadm_list_t *hca_list) 1389*0Sstevel@tonic-gate { 1390*0Sstevel@tonic-gate datadm_fill_ia_list_t ia_args; 1391*0Sstevel@tonic-gate di_node_t root_node; 1392*0Sstevel@tonic-gate int retval = 0; 1393*0Sstevel@tonic-gate int sv4, sv6; 1394*0Sstevel@tonic-gate 1395*0Sstevel@tonic-gate root_node = di_init("/", DINFOCPYALL); 1396*0Sstevel@tonic-gate if (root_node == DI_NODE_NIL) { 1397*0Sstevel@tonic-gate perror("datadm: di_init"); 1398*0Sstevel@tonic-gate return (-1); 1399*0Sstevel@tonic-gate } 1400*0Sstevel@tonic-gate sv4 = socket(AF_INET, SOCK_DGRAM, 0); 1401*0Sstevel@tonic-gate if (sv4 < 0) { 1402*0Sstevel@tonic-gate perror("datadm: socket"); 1403*0Sstevel@tonic-gate di_fini(root_node); 1404*0Sstevel@tonic-gate return (-1); 1405*0Sstevel@tonic-gate } 1406*0Sstevel@tonic-gate sv6 = socket(AF_INET6, SOCK_DGRAM, 0); 1407*0Sstevel@tonic-gate if (sv6 < 0) { 1408*0Sstevel@tonic-gate perror("datadm: socket"); 1409*0Sstevel@tonic-gate di_fini(root_node); 1410*0Sstevel@tonic-gate return (-1); 1411*0Sstevel@tonic-gate } 1412*0Sstevel@tonic-gate ia_args.ia_root_node = root_node; 1413*0Sstevel@tonic-gate ia_args.ia_sock_fd_v4 = sv4; 1414*0Sstevel@tonic-gate ia_args.ia_sock_fd_v6 = sv6; 1415*0Sstevel@tonic-gate 1416*0Sstevel@tonic-gate retval = datadm_walk_list(hca_list, 1417*0Sstevel@tonic-gate (int (*)(datadm_entry_t *, void *))datadm_fill_ia_list, &ia_args); 1418*0Sstevel@tonic-gate 1419*0Sstevel@tonic-gate (void) close(sv4); 1420*0Sstevel@tonic-gate (void) close(sv6); 1421*0Sstevel@tonic-gate di_fini(root_node); 1422*0Sstevel@tonic-gate return (retval); 1423*0Sstevel@tonic-gate } 1424*0Sstevel@tonic-gate 1425*0Sstevel@tonic-gate static int 1426*0Sstevel@tonic-gate datadm_generate_conf_entry(FILE *outfile, datadm_ia_entry_t *ia_entry, 1427*0Sstevel@tonic-gate datadm_sp_entry_t *sp_entry) 1428*0Sstevel@tonic-gate { 1429*0Sstevel@tonic-gate int retval; 1430*0Sstevel@tonic-gate 1431*0Sstevel@tonic-gate retval = fprintf(outfile, 1432*0Sstevel@tonic-gate "%s%d %s%d.%d %s %s %s %s%d.%d \"%s\" \"%s%s%s\"\n", 1433*0Sstevel@tonic-gate DATADM_IA_NAME, ia_entry->iae_devnum, 1434*0Sstevel@tonic-gate (sp_entry->spe_api_version.dv_name ? 1435*0Sstevel@tonic-gate sp_entry->spe_api_version.dv_name : ""), 1436*0Sstevel@tonic-gate sp_entry->spe_api_version.dv_major, 1437*0Sstevel@tonic-gate sp_entry->spe_api_version.dv_minor, 1438*0Sstevel@tonic-gate (sp_entry->spe_threadsafe ? "threadsafe" : "nonthreadsafe"), 1439*0Sstevel@tonic-gate (sp_entry->spe_default ? "default" : "nondefault"), 1440*0Sstevel@tonic-gate sp_entry->spe_libpath, 1441*0Sstevel@tonic-gate (sp_entry->spe_sp_version.dv_name ? 1442*0Sstevel@tonic-gate sp_entry->spe_sp_version.dv_name : ""), 1443*0Sstevel@tonic-gate sp_entry->spe_sp_version.dv_major, 1444*0Sstevel@tonic-gate sp_entry->spe_sp_version.dv_minor, 1445*0Sstevel@tonic-gate sp_entry->spe_sp_data, 1446*0Sstevel@tonic-gate DATADM_DRV_NAME, "=", sp_entry->spe_devname); 1447*0Sstevel@tonic-gate 1448*0Sstevel@tonic-gate if (retval < 0) { 1449*0Sstevel@tonic-gate return (-1); 1450*0Sstevel@tonic-gate } 1451*0Sstevel@tonic-gate return (0); 1452*0Sstevel@tonic-gate } 1453*0Sstevel@tonic-gate 1454*0Sstevel@tonic-gate /* 1455*0Sstevel@tonic-gate * generate dat.conf header 1456*0Sstevel@tonic-gate */ 1457*0Sstevel@tonic-gate static int 1458*0Sstevel@tonic-gate datadm_generate_conf_header(FILE *outfile) 1459*0Sstevel@tonic-gate { 1460*0Sstevel@tonic-gate datadm_entry_t *cep; 1461*0Sstevel@tonic-gate datadm_cmnt_entry_t *cmnt; 1462*0Sstevel@tonic-gate int retval = 0; 1463*0Sstevel@tonic-gate 1464*0Sstevel@tonic-gate cep = datadm_conf_header.dl_head; 1465*0Sstevel@tonic-gate if (cep == NULL) { 1466*0Sstevel@tonic-gate /* 1467*0Sstevel@tonic-gate * if dat.conf doesn't have a header, we prepend a 1468*0Sstevel@tonic-gate * default one. 1469*0Sstevel@tonic-gate */ 1470*0Sstevel@tonic-gate retval = fprintf(outfile, "%s", datadm_conf_header_default); 1471*0Sstevel@tonic-gate goto done; 1472*0Sstevel@tonic-gate } 1473*0Sstevel@tonic-gate while (cep != NULL) { 1474*0Sstevel@tonic-gate cmnt = (datadm_cmnt_entry_t *)cep; 1475*0Sstevel@tonic-gate if (cmnt->cmnt_line != NULL) { 1476*0Sstevel@tonic-gate int len; 1477*0Sstevel@tonic-gate 1478*0Sstevel@tonic-gate retval = fprintf(outfile, "%s", cmnt->cmnt_line); 1479*0Sstevel@tonic-gate if (retval < 0) { 1480*0Sstevel@tonic-gate break; 1481*0Sstevel@tonic-gate } 1482*0Sstevel@tonic-gate 1483*0Sstevel@tonic-gate /* 1484*0Sstevel@tonic-gate * append a newline if the comment line doesn't 1485*0Sstevel@tonic-gate * have one. 1486*0Sstevel@tonic-gate */ 1487*0Sstevel@tonic-gate len = strlen(cmnt->cmnt_line); 1488*0Sstevel@tonic-gate if (cmnt->cmnt_line[len - 1] != '\n') { 1489*0Sstevel@tonic-gate retval = fprintf(outfile, "\n"); 1490*0Sstevel@tonic-gate if (retval < 0) { 1491*0Sstevel@tonic-gate break; 1492*0Sstevel@tonic-gate } 1493*0Sstevel@tonic-gate } 1494*0Sstevel@tonic-gate } 1495*0Sstevel@tonic-gate cep = cep->de_next; 1496*0Sstevel@tonic-gate } 1497*0Sstevel@tonic-gate done:; 1498*0Sstevel@tonic-gate if (retval < 0) { 1499*0Sstevel@tonic-gate return (-1); 1500*0Sstevel@tonic-gate } 1501*0Sstevel@tonic-gate return (0); 1502*0Sstevel@tonic-gate } 1503*0Sstevel@tonic-gate 1504*0Sstevel@tonic-gate /* 1505*0Sstevel@tonic-gate * outputs dat.conf to stdout or to basedir/etc/dat/dat.conf 1506*0Sstevel@tonic-gate */ 1507*0Sstevel@tonic-gate static int 1508*0Sstevel@tonic-gate datadm_generate_dat_conf(datadm_list_t *hca_list) 1509*0Sstevel@tonic-gate { 1510*0Sstevel@tonic-gate FILE *outfile = NULL; 1511*0Sstevel@tonic-gate char *dat_conf = datadm_args.da_dat_conf; 1512*0Sstevel@tonic-gate datadm_entry_t *hep; 1513*0Sstevel@tonic-gate int retval = 0; 1514*0Sstevel@tonic-gate 1515*0Sstevel@tonic-gate if (datadm_args.da_op_type == DATADM_OP_VIEW) { 1516*0Sstevel@tonic-gate outfile = stdout; 1517*0Sstevel@tonic-gate } else { 1518*0Sstevel@tonic-gate outfile = fopen(dat_conf, "w+"); 1519*0Sstevel@tonic-gate if (outfile == NULL) { 1520*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1521*0Sstevel@tonic-gate "datadm: cannot open %s: %s\n"), 1522*0Sstevel@tonic-gate dat_conf, strerror(errno)); 1523*0Sstevel@tonic-gate return (-1); 1524*0Sstevel@tonic-gate } 1525*0Sstevel@tonic-gate } 1526*0Sstevel@tonic-gate if (outfile != stdout) { 1527*0Sstevel@tonic-gate /* 1528*0Sstevel@tonic-gate * do not generate the header if we are 1529*0Sstevel@tonic-gate * printing to the screen 1530*0Sstevel@tonic-gate */ 1531*0Sstevel@tonic-gate retval = datadm_generate_conf_header(outfile); 1532*0Sstevel@tonic-gate if (retval != 0) { 1533*0Sstevel@tonic-gate goto done; 1534*0Sstevel@tonic-gate } 1535*0Sstevel@tonic-gate } 1536*0Sstevel@tonic-gate hep = hca_list->dl_head; 1537*0Sstevel@tonic-gate while (hep != NULL) { 1538*0Sstevel@tonic-gate datadm_entry_t *iep; 1539*0Sstevel@tonic-gate 1540*0Sstevel@tonic-gate iep = ((datadm_hca_entry_t *)hep)->he_ia_list.dl_head; 1541*0Sstevel@tonic-gate while (iep != NULL) { 1542*0Sstevel@tonic-gate datadm_entry_t *sep; 1543*0Sstevel@tonic-gate 1544*0Sstevel@tonic-gate sep = ((datadm_hca_entry_t *)hep)->he_sp_list.dl_head; 1545*0Sstevel@tonic-gate while (sep != NULL) { 1546*0Sstevel@tonic-gate if (((datadm_sp_entry_t *)sep)->spe_invalid) { 1547*0Sstevel@tonic-gate sep = sep->de_next; 1548*0Sstevel@tonic-gate continue; 1549*0Sstevel@tonic-gate } 1550*0Sstevel@tonic-gate retval = datadm_generate_conf_entry(outfile, 1551*0Sstevel@tonic-gate (datadm_ia_entry_t *)iep, 1552*0Sstevel@tonic-gate (datadm_sp_entry_t *)sep); 1553*0Sstevel@tonic-gate if (retval != 0) { 1554*0Sstevel@tonic-gate goto done; 1555*0Sstevel@tonic-gate } 1556*0Sstevel@tonic-gate sep = sep->de_next; 1557*0Sstevel@tonic-gate } 1558*0Sstevel@tonic-gate iep = iep->de_next; 1559*0Sstevel@tonic-gate } 1560*0Sstevel@tonic-gate hep = hep->de_next; 1561*0Sstevel@tonic-gate } 1562*0Sstevel@tonic-gate retval = fflush(outfile); 1563*0Sstevel@tonic-gate done:; 1564*0Sstevel@tonic-gate if (outfile != stdout) { 1565*0Sstevel@tonic-gate (void) fclose(outfile); 1566*0Sstevel@tonic-gate } 1567*0Sstevel@tonic-gate if (retval < 0) { 1568*0Sstevel@tonic-gate perror("datadm: fprintf"); 1569*0Sstevel@tonic-gate } 1570*0Sstevel@tonic-gate return (retval); 1571*0Sstevel@tonic-gate } 1572*0Sstevel@tonic-gate 1573*0Sstevel@tonic-gate static int 1574*0Sstevel@tonic-gate datadm_view(void) 1575*0Sstevel@tonic-gate { 1576*0Sstevel@tonic-gate int retval = 0; 1577*0Sstevel@tonic-gate datadm_list_t hca_list; 1578*0Sstevel@tonic-gate 1579*0Sstevel@tonic-gate bzero(&hca_list, sizeof (hca_list)); 1580*0Sstevel@tonic-gate 1581*0Sstevel@tonic-gate retval = datadm_parse_dat_conf(&hca_list); 1582*0Sstevel@tonic-gate if (retval != 0) { 1583*0Sstevel@tonic-gate goto cleanup; 1584*0Sstevel@tonic-gate } 1585*0Sstevel@tonic-gate retval = datadm_generate_dat_conf(&hca_list); 1586*0Sstevel@tonic-gate if (retval != 0) { 1587*0Sstevel@tonic-gate goto cleanup; 1588*0Sstevel@tonic-gate } 1589*0Sstevel@tonic-gate 1590*0Sstevel@tonic-gate cleanup:; 1591*0Sstevel@tonic-gate datadm_free_list(&datadm_conf_header, 1592*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry); 1593*0Sstevel@tonic-gate datadm_free_list(&hca_list, 1594*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1595*0Sstevel@tonic-gate return (retval); 1596*0Sstevel@tonic-gate } 1597*0Sstevel@tonic-gate 1598*0Sstevel@tonic-gate static int 1599*0Sstevel@tonic-gate datadm_update(void) 1600*0Sstevel@tonic-gate { 1601*0Sstevel@tonic-gate int retval = 0; 1602*0Sstevel@tonic-gate datadm_list_t hca_list; 1603*0Sstevel@tonic-gate 1604*0Sstevel@tonic-gate bzero(&hca_list, sizeof (hca_list)); 1605*0Sstevel@tonic-gate 1606*0Sstevel@tonic-gate retval = datadm_parse_dat_conf(&hca_list); 1607*0Sstevel@tonic-gate if (retval != 0) { 1608*0Sstevel@tonic-gate goto cleanup; 1609*0Sstevel@tonic-gate } 1610*0Sstevel@tonic-gate retval = datadm_build_ia_lists(&hca_list); 1611*0Sstevel@tonic-gate if (retval != 0) { 1612*0Sstevel@tonic-gate goto cleanup; 1613*0Sstevel@tonic-gate } 1614*0Sstevel@tonic-gate retval = datadm_generate_dat_conf(&hca_list); 1615*0Sstevel@tonic-gate if (retval != 0) { 1616*0Sstevel@tonic-gate goto cleanup; 1617*0Sstevel@tonic-gate } 1618*0Sstevel@tonic-gate 1619*0Sstevel@tonic-gate cleanup:; 1620*0Sstevel@tonic-gate datadm_free_list(&datadm_conf_header, 1621*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry); 1622*0Sstevel@tonic-gate datadm_free_list(&hca_list, 1623*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1624*0Sstevel@tonic-gate return (retval); 1625*0Sstevel@tonic-gate } 1626*0Sstevel@tonic-gate 1627*0Sstevel@tonic-gate static int 1628*0Sstevel@tonic-gate datadm_add(void) 1629*0Sstevel@tonic-gate { 1630*0Sstevel@tonic-gate int retval = 0; 1631*0Sstevel@tonic-gate datadm_list_t hca_list; 1632*0Sstevel@tonic-gate 1633*0Sstevel@tonic-gate bzero(&hca_list, sizeof (hca_list)); 1634*0Sstevel@tonic-gate 1635*0Sstevel@tonic-gate retval = datadm_parse_dat_conf(&hca_list); 1636*0Sstevel@tonic-gate if (retval != 0) { 1637*0Sstevel@tonic-gate goto cleanup; 1638*0Sstevel@tonic-gate } 1639*0Sstevel@tonic-gate retval = datadm_parse_sp_conf(&hca_list); 1640*0Sstevel@tonic-gate if (retval != 0) { 1641*0Sstevel@tonic-gate goto cleanup; 1642*0Sstevel@tonic-gate } 1643*0Sstevel@tonic-gate retval = datadm_build_ia_lists(&hca_list); 1644*0Sstevel@tonic-gate if (retval != 0) { 1645*0Sstevel@tonic-gate goto cleanup; 1646*0Sstevel@tonic-gate } 1647*0Sstevel@tonic-gate retval = datadm_generate_dat_conf(&hca_list); 1648*0Sstevel@tonic-gate if (retval != 0) { 1649*0Sstevel@tonic-gate goto cleanup; 1650*0Sstevel@tonic-gate } 1651*0Sstevel@tonic-gate 1652*0Sstevel@tonic-gate cleanup:; 1653*0Sstevel@tonic-gate datadm_free_list(&datadm_conf_header, 1654*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry); 1655*0Sstevel@tonic-gate datadm_free_list(&hca_list, 1656*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1657*0Sstevel@tonic-gate return (retval); 1658*0Sstevel@tonic-gate } 1659*0Sstevel@tonic-gate 1660*0Sstevel@tonic-gate static int 1661*0Sstevel@tonic-gate datadm_remove(void) 1662*0Sstevel@tonic-gate { 1663*0Sstevel@tonic-gate int retval = 0; 1664*0Sstevel@tonic-gate datadm_list_t hca_list; 1665*0Sstevel@tonic-gate datadm_list_t hca_list2; 1666*0Sstevel@tonic-gate 1667*0Sstevel@tonic-gate bzero(&hca_list, sizeof (hca_list)); 1668*0Sstevel@tonic-gate bzero(&hca_list2, sizeof (hca_list2)); 1669*0Sstevel@tonic-gate 1670*0Sstevel@tonic-gate retval = datadm_parse_dat_conf(&hca_list); 1671*0Sstevel@tonic-gate if (retval != 0) { 1672*0Sstevel@tonic-gate goto cleanup; 1673*0Sstevel@tonic-gate } 1674*0Sstevel@tonic-gate retval = datadm_parse_sp_conf(&hca_list2); 1675*0Sstevel@tonic-gate if (retval != 0) { 1676*0Sstevel@tonic-gate goto cleanup; 1677*0Sstevel@tonic-gate } 1678*0Sstevel@tonic-gate datadm_invalidate_common_sp_entries(&hca_list, &hca_list2); 1679*0Sstevel@tonic-gate 1680*0Sstevel@tonic-gate retval = datadm_generate_dat_conf(&hca_list); 1681*0Sstevel@tonic-gate if (retval != 0) { 1682*0Sstevel@tonic-gate goto cleanup; 1683*0Sstevel@tonic-gate } 1684*0Sstevel@tonic-gate 1685*0Sstevel@tonic-gate cleanup:; 1686*0Sstevel@tonic-gate datadm_free_list(&datadm_conf_header, 1687*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry); 1688*0Sstevel@tonic-gate datadm_free_list(&hca_list, 1689*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1690*0Sstevel@tonic-gate datadm_free_list(&hca_list2, 1691*0Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1692*0Sstevel@tonic-gate return (retval); 1693*0Sstevel@tonic-gate } 1694*0Sstevel@tonic-gate 1695*0Sstevel@tonic-gate static int 1696*0Sstevel@tonic-gate datadm_locate_dat_conf(char *basedir) 1697*0Sstevel@tonic-gate { 1698*0Sstevel@tonic-gate char *dat_conf; 1699*0Sstevel@tonic-gate 1700*0Sstevel@tonic-gate if (basedir == NULL) { 1701*0Sstevel@tonic-gate datadm_args.da_dat_conf = DATADM_DAT_CONF; 1702*0Sstevel@tonic-gate return (0); 1703*0Sstevel@tonic-gate } 1704*0Sstevel@tonic-gate dat_conf = (char *)malloc(strlen(basedir) + 1705*0Sstevel@tonic-gate strlen(DATADM_DAT_CONF) + 1); 1706*0Sstevel@tonic-gate if (dat_conf == NULL) { 1707*0Sstevel@tonic-gate return (-1); 1708*0Sstevel@tonic-gate } 1709*0Sstevel@tonic-gate dat_conf[0] = '\0'; 1710*0Sstevel@tonic-gate (void) strcat(dat_conf, basedir); 1711*0Sstevel@tonic-gate (void) strcat(dat_conf, DATADM_DAT_CONF); 1712*0Sstevel@tonic-gate datadm_args.da_dat_conf = dat_conf; 1713*0Sstevel@tonic-gate return (0); 1714*0Sstevel@tonic-gate } 1715*0Sstevel@tonic-gate 1716*0Sstevel@tonic-gate int 1717*0Sstevel@tonic-gate main(int argc, char **argv) 1718*0Sstevel@tonic-gate { 1719*0Sstevel@tonic-gate extern char *optarg; 1720*0Sstevel@tonic-gate extern int optind; 1721*0Sstevel@tonic-gate char *basedir = NULL; 1722*0Sstevel@tonic-gate int c, retval; 1723*0Sstevel@tonic-gate int op_type = -1, errflg = 0; 1724*0Sstevel@tonic-gate 1725*0Sstevel@tonic-gate bzero(&datadm_args, sizeof (datadm_args)); 1726*0Sstevel@tonic-gate bzero(&datadm_conf_header, sizeof (datadm_conf_header)); 1727*0Sstevel@tonic-gate 1728*0Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1729*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 1730*0Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 1731*0Sstevel@tonic-gate #endif 1732*0Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1733*0Sstevel@tonic-gate 1734*0Sstevel@tonic-gate while ((c = getopt(argc, argv, "vua:r:b:")) != EOF) { 1735*0Sstevel@tonic-gate switch (c) { 1736*0Sstevel@tonic-gate case 'v': 1737*0Sstevel@tonic-gate if (op_type != -1) errflg = 1; 1738*0Sstevel@tonic-gate op_type = DATADM_OP_VIEW; 1739*0Sstevel@tonic-gate break; 1740*0Sstevel@tonic-gate case 'u': 1741*0Sstevel@tonic-gate if (op_type != -1) errflg = 1; 1742*0Sstevel@tonic-gate op_type = DATADM_OP_UPDATE; 1743*0Sstevel@tonic-gate break; 1744*0Sstevel@tonic-gate case 'a': 1745*0Sstevel@tonic-gate if (op_type != -1) errflg = 1; 1746*0Sstevel@tonic-gate op_type = DATADM_OP_ADD; 1747*0Sstevel@tonic-gate datadm_args.da_sp_conf = optarg; 1748*0Sstevel@tonic-gate break; 1749*0Sstevel@tonic-gate case 'r': 1750*0Sstevel@tonic-gate if (op_type != -1) errflg = 1; 1751*0Sstevel@tonic-gate op_type = DATADM_OP_REMOVE; 1752*0Sstevel@tonic-gate datadm_args.da_sp_conf = optarg; 1753*0Sstevel@tonic-gate break; 1754*0Sstevel@tonic-gate case 'b': 1755*0Sstevel@tonic-gate basedir = optarg; 1756*0Sstevel@tonic-gate break; 1757*0Sstevel@tonic-gate default: 1758*0Sstevel@tonic-gate errflg = 1; 1759*0Sstevel@tonic-gate break; 1760*0Sstevel@tonic-gate } 1761*0Sstevel@tonic-gate if (errflg != 0) { 1762*0Sstevel@tonic-gate break; 1763*0Sstevel@tonic-gate } 1764*0Sstevel@tonic-gate } 1765*0Sstevel@tonic-gate if (errflg != 0 || op_type == -1 || optind < argc) { 1766*0Sstevel@tonic-gate datadm_usage(); 1767*0Sstevel@tonic-gate return (1); 1768*0Sstevel@tonic-gate } 1769*0Sstevel@tonic-gate datadm_args.da_op_type = op_type; 1770*0Sstevel@tonic-gate if (datadm_locate_dat_conf(basedir)) { 1771*0Sstevel@tonic-gate return (1); 1772*0Sstevel@tonic-gate } 1773*0Sstevel@tonic-gate 1774*0Sstevel@tonic-gate retval = (*datadm_ops[op_type])(); 1775*0Sstevel@tonic-gate return (retval); 1776*0Sstevel@tonic-gate } 1777