1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte /* 22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*fcf3ce44SJohn Forte * Use is subject to license terms. 24*fcf3ce44SJohn Forte */ 25*fcf3ce44SJohn Forte 26*fcf3ce44SJohn Forte #include <stdio.h> 27*fcf3ce44SJohn Forte 28*fcf3ce44SJohn Forte #include <sys/types.h> 29*fcf3ce44SJohn Forte #include <sys/wait.h> 30*fcf3ce44SJohn Forte #include <stdio.h> 31*fcf3ce44SJohn Forte #include <sys/mnttab.h> 32*fcf3ce44SJohn Forte #include <sys/vtoc.h> 33*fcf3ce44SJohn Forte #include <errno.h> 34*fcf3ce44SJohn Forte #include <limits.h> 35*fcf3ce44SJohn Forte #include <fcntl.h> 36*fcf3ce44SJohn Forte #include <string.h> 37*fcf3ce44SJohn Forte #include <stdarg.h> 38*fcf3ce44SJohn Forte #include <strings.h> 39*fcf3ce44SJohn Forte #include <stdlib.h> 40*fcf3ce44SJohn Forte #include <unistd.h> 41*fcf3ce44SJohn Forte #include <sys/mman.h> 42*fcf3ce44SJohn Forte #include <sys/stat.h> 43*fcf3ce44SJohn Forte 44*fcf3ce44SJohn Forte #include <locale.h> 45*fcf3ce44SJohn Forte #include <langinfo.h> 46*fcf3ce44SJohn Forte #include <libintl.h> 47*fcf3ce44SJohn Forte #include <stdarg.h> 48*fcf3ce44SJohn Forte #include <netdb.h> 49*fcf3ce44SJohn Forte #include <ctype.h> 50*fcf3ce44SJohn Forte #include <sys/stat.h> 51*fcf3ce44SJohn Forte #include <sys/utsname.h> 52*fcf3ce44SJohn Forte 53*fcf3ce44SJohn Forte #include "cfg_impl.h" 54*fcf3ce44SJohn Forte #include "cfg.h" 55*fcf3ce44SJohn Forte #include "cfg_lockd.h" 56*fcf3ce44SJohn Forte 57*fcf3ce44SJohn Forte #if 0 58*fcf3ce44SJohn Forte #define DEBUG_CFGLIST 59*fcf3ce44SJohn Forte #define DEBUG_EXTRA 60*fcf3ce44SJohn Forte #define DEBUG_LIB 61*fcf3ce44SJohn Forte #define DEBUG_NOISY 62*fcf3ce44SJohn Forte #define DEBUG_OUT 63*fcf3ce44SJohn Forte #endif 64*fcf3ce44SJohn Forte 65*fcf3ce44SJohn Forte #define MAX_CFG 16 /* Max. number of lines in /etc/dscfg_format */ 66*fcf3ce44SJohn Forte #define MAX_SET 12 /* number of chars in a set name */ 67*fcf3ce44SJohn Forte 68*fcf3ce44SJohn Forte 69*fcf3ce44SJohn Forte /* parser tree for config section */ 70*fcf3ce44SJohn Forte static struct parser chead[MAX_CFG] = { NULL }; 71*fcf3ce44SJohn Forte static int chead_loaded = 0; 72*fcf3ce44SJohn Forte static char config_file[CFG_MAX_BUF]; 73*fcf3ce44SJohn Forte static char dectohex[] = { '0', '1', '2', '3', '4', '5', '6', '7', 74*fcf3ce44SJohn Forte '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 75*fcf3ce44SJohn Forte #define CHARS_TO_ENCODE "=;\t " 76*fcf3ce44SJohn Forte #define min(a, b) ((a) > (b) ? (b) : (a)) 77*fcf3ce44SJohn Forte 78*fcf3ce44SJohn Forte /* field to be sorted on in sorting routines */ 79*fcf3ce44SJohn Forte static struct sortby_s { 80*fcf3ce44SJohn Forte char section[CFG_MAX_KEY]; 81*fcf3ce44SJohn Forte char field[CFG_MAX_KEY]; 82*fcf3ce44SJohn Forte int offset; 83*fcf3ce44SJohn Forte int comperror; 84*fcf3ce44SJohn Forte } sortby; 85*fcf3ce44SJohn Forte 86*fcf3ce44SJohn Forte int cfg_severity = 0; 87*fcf3ce44SJohn Forte char *cfg_perror_str; 88*fcf3ce44SJohn Forte static int cfg_read(cfp_t *); 89*fcf3ce44SJohn Forte static void cfg_read_parser_config(cfp_t *); 90*fcf3ce44SJohn Forte static int cfg_rdlock(CFGFILE *); 91*fcf3ce44SJohn Forte static int cfg_wrlock(CFGFILE *); 92*fcf3ce44SJohn Forte static int cfg_lockd; 93*fcf3ce44SJohn Forte void cfg_replace_lists(cfp_t *); 94*fcf3ce44SJohn Forte void cfg_free_parser_tree(); 95*fcf3ce44SJohn Forte void cfg_invalidate_hsizes(int, const char *); 96*fcf3ce44SJohn Forte int cfg_map_cfglists(cfp_t *); 97*fcf3ce44SJohn Forte int cfg_hdrcmp(cfp_t *); 98*fcf3ce44SJohn Forte void cfg_free_cfglist(cfp_t *); 99*fcf3ce44SJohn Forte 100*fcf3ce44SJohn Forte extern cfg_io_t *cfg_block_io_provider(void); 101*fcf3ce44SJohn Forte extern cfg_io_t *cfg_raw_io_provider(void); 102*fcf3ce44SJohn Forte extern int cl_initialized; 103*fcf3ce44SJohn Forte 104*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 105*fcf3ce44SJohn Forte static void 106*fcf3ce44SJohn Forte dump_status(cfp_t *cfp, char *str) 107*fcf3ce44SJohn Forte { 108*fcf3ce44SJohn Forte printf("called from %s\n", str); 109*fcf3ce44SJohn Forte printf(gettext("Header info:\n" 110*fcf3ce44SJohn Forte "\tmagic: %x\tstate: %x\n"), 111*fcf3ce44SJohn Forte cfp->cf_head->h_magic, cfp->cf_head->h_state); 112*fcf3ce44SJohn Forte printf(gettext("Parser section:\n" 113*fcf3ce44SJohn Forte "Start: %x\tsize: %d\toffset: %d\n"), 114*fcf3ce44SJohn Forte cfp->cf_mapped, cfp->cf_head->h_parsesize, 115*fcf3ce44SJohn Forte cfp->cf_head->h_parseoff); 116*fcf3ce44SJohn Forte printf(gettext("Config section:\n" 117*fcf3ce44SJohn Forte "Start: %x\tsize:%d\tacsize: %d\n"), 118*fcf3ce44SJohn Forte cfp->cf_head->h_cparse, cfp->cf_head->h_csize, 119*fcf3ce44SJohn Forte cfp->cf_head->h_acsize); 120*fcf3ce44SJohn Forte printf("\n\tccopy1: %x\tccopy2: %x\n", 121*fcf3ce44SJohn Forte cfp->cf_head->h_ccopy1, cfp->cf_head->h_ccopy2); 122*fcf3ce44SJohn Forte printf(gettext("Sequence:\n" 123*fcf3ce44SJohn Forte "\tseq1: %d\t\tseq2: %d\n"), 124*fcf3ce44SJohn Forte cfp->cf_head->h_seq1, cfp->cf_head->h_seq2); 125*fcf3ce44SJohn Forte } 126*fcf3ce44SJohn Forte #endif /* DEBUG */ 127*fcf3ce44SJohn Forte 128*fcf3ce44SJohn Forte /* 129*fcf3ce44SJohn Forte * cfg_get_item 130*fcf3ce44SJohn Forte * return position from parser config given tag and field 131*fcf3ce44SJohn Forte */ 132*fcf3ce44SJohn Forte static int 133*fcf3ce44SJohn Forte cfg_get_item(struct parser *tbl, const char *tag, const char *field) 134*fcf3ce44SJohn Forte { 135*fcf3ce44SJohn Forte int i; 136*fcf3ce44SJohn Forte struct lookup *p; 137*fcf3ce44SJohn Forte 138*fcf3ce44SJohn Forte for (i = 0; i < MAX_CFG; i++) { 139*fcf3ce44SJohn Forte /* only as many lists as defined */ 140*fcf3ce44SJohn Forte if (tbl[i].tag.l_word[0] == '\0') { 141*fcf3ce44SJohn Forte i = MAX_CFG; 142*fcf3ce44SJohn Forte break; 143*fcf3ce44SJohn Forte } 144*fcf3ce44SJohn Forte if (strcmp(tbl[i].tag.l_word, tag) == 0) 145*fcf3ce44SJohn Forte break; 146*fcf3ce44SJohn Forte } 147*fcf3ce44SJohn Forte 148*fcf3ce44SJohn Forte /* Handle table size */ 149*fcf3ce44SJohn Forte if (i < MAX_CFG) { 150*fcf3ce44SJohn Forte p = tbl[i].fld; 151*fcf3ce44SJohn Forte while (p) { 152*fcf3ce44SJohn Forte if (strcmp(p->l_word, field) == 0) 153*fcf3ce44SJohn Forte return (p->l_value); 154*fcf3ce44SJohn Forte p = p->l_next; 155*fcf3ce44SJohn Forte } 156*fcf3ce44SJohn Forte } 157*fcf3ce44SJohn Forte 158*fcf3ce44SJohn Forte /* Handle failure */ 159*fcf3ce44SJohn Forte return (-1); 160*fcf3ce44SJohn Forte } 161*fcf3ce44SJohn Forte 162*fcf3ce44SJohn Forte /* 163*fcf3ce44SJohn Forte * cfg_get_num_flds 164*fcf3ce44SJohn Forte * return number of fields for given parser tag 165*fcf3ce44SJohn Forte */ 166*fcf3ce44SJohn Forte static int 167*fcf3ce44SJohn Forte cfg_get_num_flds(struct parser *tbl, const char *tag, int *table_index) 168*fcf3ce44SJohn Forte { 169*fcf3ce44SJohn Forte int i; 170*fcf3ce44SJohn Forte int pos = 0; 171*fcf3ce44SJohn Forte struct lookup *p; 172*fcf3ce44SJohn Forte 173*fcf3ce44SJohn Forte for (i = 0; i < MAX_CFG; i++) { 174*fcf3ce44SJohn Forte /* only as many lists as defined */ 175*fcf3ce44SJohn Forte if (tbl[i].tag.l_word[0] == '\0') { 176*fcf3ce44SJohn Forte i = MAX_CFG; 177*fcf3ce44SJohn Forte break; 178*fcf3ce44SJohn Forte } 179*fcf3ce44SJohn Forte if (strcmp(tbl[i].tag.l_word, tag) == 0) { 180*fcf3ce44SJohn Forte *table_index = i; 181*fcf3ce44SJohn Forte break; 182*fcf3ce44SJohn Forte } 183*fcf3ce44SJohn Forte } 184*fcf3ce44SJohn Forte 185*fcf3ce44SJohn Forte /* Handle table size */ 186*fcf3ce44SJohn Forte if (i < MAX_CFG) { 187*fcf3ce44SJohn Forte p = tbl[i].fld; 188*fcf3ce44SJohn Forte while (p) { 189*fcf3ce44SJohn Forte pos++; 190*fcf3ce44SJohn Forte p = p->l_next; 191*fcf3ce44SJohn Forte } 192*fcf3ce44SJohn Forte return (pos); 193*fcf3ce44SJohn Forte } 194*fcf3ce44SJohn Forte 195*fcf3ce44SJohn Forte return (0); 196*fcf3ce44SJohn Forte } 197*fcf3ce44SJohn Forte 198*fcf3ce44SJohn Forte /* 199*fcf3ce44SJohn Forte * count white space fields 200*fcf3ce44SJohn Forte */ 201*fcf3ce44SJohn Forte static int 202*fcf3ce44SJohn Forte cfg_cnt_flds(char *value) 203*fcf3ce44SJohn Forte { 204*fcf3ce44SJohn Forte char *ptr; 205*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 206*fcf3ce44SJohn Forte int flds = 0; 207*fcf3ce44SJohn Forte 208*fcf3ce44SJohn Forte if ((value == NULL) || (strlen(value) >= CFG_MAX_BUF)) 209*fcf3ce44SJohn Forte return (0); 210*fcf3ce44SJohn Forte 211*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 212*fcf3ce44SJohn Forte strcpy(buf, value); 213*fcf3ce44SJohn Forte ptr = strtok(buf, " "); 214*fcf3ce44SJohn Forte while (ptr) { 215*fcf3ce44SJohn Forte flds++; 216*fcf3ce44SJohn Forte ptr = strtok(NULL, " "); 217*fcf3ce44SJohn Forte } 218*fcf3ce44SJohn Forte return (flds); 219*fcf3ce44SJohn Forte } 220*fcf3ce44SJohn Forte 221*fcf3ce44SJohn Forte /* 222*fcf3ce44SJohn Forte * cfg_get_parser_offset 223*fcf3ce44SJohn Forte * returns the index for each 224*fcf3ce44SJohn Forte * section of the parser.. 225*fcf3ce44SJohn Forte * ie. parser info for sndr is chead[3].tag.l_word 226*fcf3ce44SJohn Forte * this will help us find sndr quicker, as the 227*fcf3ce44SJohn Forte * the memory picture of the sets mimic this ordering 228*fcf3ce44SJohn Forte */ 229*fcf3ce44SJohn Forte static int 230*fcf3ce44SJohn Forte cfg_get_parser_offset(const char *section) 231*fcf3ce44SJohn Forte { 232*fcf3ce44SJohn Forte int i; 233*fcf3ce44SJohn Forte 234*fcf3ce44SJohn Forte for (i = 0; i < MAX_CFG; i++) { 235*fcf3ce44SJohn Forte /* only as many lists as defined */ 236*fcf3ce44SJohn Forte if (chead[i].tag.l_word[0] == '\0') { 237*fcf3ce44SJohn Forte i = MAX_CFG; 238*fcf3ce44SJohn Forte break; 239*fcf3ce44SJohn Forte } 240*fcf3ce44SJohn Forte if (strcmp(chead[i].tag.l_word, section) == 0) 241*fcf3ce44SJohn Forte break; 242*fcf3ce44SJohn Forte } 243*fcf3ce44SJohn Forte 244*fcf3ce44SJohn Forte /* Handle table size */ 245*fcf3ce44SJohn Forte if (i < MAX_CFG) 246*fcf3ce44SJohn Forte return (i); 247*fcf3ce44SJohn Forte 248*fcf3ce44SJohn Forte /* Handle failure */ 249*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 250*fcf3ce44SJohn Forte "cfg_get_parser_offset: section not found"); 251*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 252*fcf3ce44SJohn Forte errno = ESRCH; 253*fcf3ce44SJohn Forte return (-1); 254*fcf3ce44SJohn Forte } 255*fcf3ce44SJohn Forte 256*fcf3ce44SJohn Forte /* 257*fcf3ce44SJohn Forte * cfg_fld_mov 258*fcf3ce44SJohn Forte * move fields from old buffer to new 259*fcf3ce44SJohn Forte * moving only specified fields 260*fcf3ce44SJohn Forte * concates newbuf 261*fcf3ce44SJohn Forte * returns fields moved 262*fcf3ce44SJohn Forte */ 263*fcf3ce44SJohn Forte static int 264*fcf3ce44SJohn Forte cfg_fld_mov(char *newbuf, char *oldbuf, int start, int end) 265*fcf3ce44SJohn Forte { 266*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 267*fcf3ce44SJohn Forte char *ptr; 268*fcf3ce44SJohn Forte int flds = 0; 269*fcf3ce44SJohn Forte 270*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 271*fcf3ce44SJohn Forte if (oldbuf == NULL) 272*fcf3ce44SJohn Forte return (0); 273*fcf3ce44SJohn Forte 274*fcf3ce44SJohn Forte if ((start > end) || (strlen(oldbuf) >= CFG_MAX_BUF)) { 275*fcf3ce44SJohn Forte return (0); 276*fcf3ce44SJohn Forte } 277*fcf3ce44SJohn Forte if (!start || !end) 278*fcf3ce44SJohn Forte return (-1); 279*fcf3ce44SJohn Forte strcpy(buf, oldbuf); 280*fcf3ce44SJohn Forte ptr = strtok(buf, " "); 281*fcf3ce44SJohn Forte while (ptr) { 282*fcf3ce44SJohn Forte flds++; 283*fcf3ce44SJohn Forte if (flds >= start && flds <= end) { 284*fcf3ce44SJohn Forte strcat(newbuf, ptr); 285*fcf3ce44SJohn Forte strcat(newbuf, " "); 286*fcf3ce44SJohn Forte } 287*fcf3ce44SJohn Forte ptr = strtok(NULL, " "); 288*fcf3ce44SJohn Forte } 289*fcf3ce44SJohn Forte 290*fcf3ce44SJohn Forte return (flds); 291*fcf3ce44SJohn Forte } 292*fcf3ce44SJohn Forte 293*fcf3ce44SJohn Forte /* 294*fcf3ce44SJohn Forte * cfg_filter_node 295*fcf3ce44SJohn Forte * return indication if this raw buf should be returned 296*fcf3ce44SJohn Forte * checks cfg->cf_node for filtering 297*fcf3ce44SJohn Forte * We already know that this buf meets most of our criteria 298*fcf3ce44SJohn Forte * find the cnode field in the buf and see if it matches 299*fcf3ce44SJohn Forte * returns 300*fcf3ce44SJohn Forte * TRUE Good entry 301*fcf3ce44SJohn Forte * FALSE Don't use it 302*fcf3ce44SJohn Forte */ 303*fcf3ce44SJohn Forte static int 304*fcf3ce44SJohn Forte cfg_filter_node(CFGFILE *cfg, struct parser *tbl, char *buf, char *tag) 305*fcf3ce44SJohn Forte { 306*fcf3ce44SJohn Forte char tmpbuf[CFG_MAX_BUF]; 307*fcf3ce44SJohn Forte int i = 1; 308*fcf3ce44SJohn Forte int fld; 309*fcf3ce44SJohn Forte char *ptr; 310*fcf3ce44SJohn Forte 311*fcf3ce44SJohn Forte if (!cfg->cf_node) /* no filter always good */ 312*fcf3ce44SJohn Forte return (TRUE); 313*fcf3ce44SJohn Forte bzero(tmpbuf, CFG_MAX_BUF); 314*fcf3ce44SJohn Forte fld = cfg_get_item(tbl, tag, "cnode"); 315*fcf3ce44SJohn Forte if (fld < 0) /* no cnode field always good */ 316*fcf3ce44SJohn Forte return (TRUE); 317*fcf3ce44SJohn Forte strncpy(tmpbuf, buf, CFG_MAX_BUF); 318*fcf3ce44SJohn Forte if (tmpbuf[CFG_MAX_BUF - 1] != '\0') 319*fcf3ce44SJohn Forte return (FALSE); 320*fcf3ce44SJohn Forte ptr = strtok(tmpbuf, " "); 321*fcf3ce44SJohn Forte while (ptr && (i < fld)) { 322*fcf3ce44SJohn Forte ptr = strtok(NULL, " "); 323*fcf3ce44SJohn Forte i++; 324*fcf3ce44SJohn Forte } 325*fcf3ce44SJohn Forte if (!ptr) 326*fcf3ce44SJohn Forte return (FALSE); 327*fcf3ce44SJohn Forte #ifdef DEBUG_EXTRA 328*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg_filter_node: node=%s:%d cnode=%s:%d\n", 329*fcf3ce44SJohn Forte cfg->cf_node, strlen(cfg->cf_node), ptr, strlen(ptr)); 330*fcf3ce44SJohn Forte #endif 331*fcf3ce44SJohn Forte if (strcmp(ptr, cfg->cf_node) == 0) 332*fcf3ce44SJohn Forte return (TRUE); 333*fcf3ce44SJohn Forte return (FALSE); 334*fcf3ce44SJohn Forte } 335*fcf3ce44SJohn Forte /* 336*fcf3ce44SJohn Forte * cfg_insert_node 337*fcf3ce44SJohn Forte * insert resource in bufs which contain cnode parser field 338*fcf3ce44SJohn Forte */ 339*fcf3ce44SJohn Forte static void 340*fcf3ce44SJohn Forte cfg_insert_node(CFGFILE *cfg, struct parser *tbl, char *buf, char *tag) 341*fcf3ce44SJohn Forte { 342*fcf3ce44SJohn Forte char tmpbuf[CFG_MAX_BUF]; 343*fcf3ce44SJohn Forte int fld; 344*fcf3ce44SJohn Forte int nflds; 345*fcf3ce44SJohn Forte int table_index; 346*fcf3ce44SJohn Forte 347*fcf3ce44SJohn Forte bzero(tmpbuf, CFG_MAX_BUF); 348*fcf3ce44SJohn Forte strcpy(tmpbuf, " "); 349*fcf3ce44SJohn Forte fld = cfg_get_item(tbl, tag, "cnode"); 350*fcf3ce44SJohn Forte nflds = cfg_get_num_flds(tbl, tag, &table_index); 351*fcf3ce44SJohn Forte if ((fld < 0) && !(cfg->cf_node)) /* no cnode field always good */ 352*fcf3ce44SJohn Forte return; 353*fcf3ce44SJohn Forte 354*fcf3ce44SJohn Forte cfg_fld_mov(tmpbuf, buf, 1, (fld - 1)); 355*fcf3ce44SJohn Forte if (cfg->cf_node) 356*fcf3ce44SJohn Forte strcat(tmpbuf, cfg->cf_node); 357*fcf3ce44SJohn Forte else 358*fcf3ce44SJohn Forte strcat(tmpbuf, "-"); 359*fcf3ce44SJohn Forte strcat(tmpbuf, " "); 360*fcf3ce44SJohn Forte cfg_fld_mov(tmpbuf, buf, (fld + 1), nflds); 361*fcf3ce44SJohn Forte bcopy(tmpbuf, buf, strlen(tmpbuf) + 1); 362*fcf3ce44SJohn Forte } 363*fcf3ce44SJohn Forte 364*fcf3ce44SJohn Forte /* 365*fcf3ce44SJohn Forte * cfg_is_cnode 366*fcf3ce44SJohn Forte * Parser current buffer to see if a non-empty " - " cnode exists 367*fcf3ce44SJohn Forte */ 368*fcf3ce44SJohn Forte /*ARGSUSED*/ 369*fcf3ce44SJohn Forte static int 370*fcf3ce44SJohn Forte cfg_is_cnode(CFGFILE *cfg, struct parser *tbl, char *buf, char *tag) 371*fcf3ce44SJohn Forte { 372*fcf3ce44SJohn Forte char tmpbuf[CFG_MAX_BUF]; 373*fcf3ce44SJohn Forte int fld = cfg_get_item(tbl, tag, "cnode"); 374*fcf3ce44SJohn Forte 375*fcf3ce44SJohn Forte if (fld >= 0) { 376*fcf3ce44SJohn Forte tmpbuf[0] = '\0'; 377*fcf3ce44SJohn Forte cfg_fld_mov(tmpbuf, buf, fld, fld); 378*fcf3ce44SJohn Forte return (strcmp(tmpbuf, "- ") ? TRUE : FALSE); 379*fcf3ce44SJohn Forte } 380*fcf3ce44SJohn Forte return (FALSE); 381*fcf3ce44SJohn Forte } 382*fcf3ce44SJohn Forte /* 383*fcf3ce44SJohn Forte * cfg_get_cstring 384*fcf3ce44SJohn Forte * key determines section and value 385*fcf3ce44SJohn Forte * special considerations: 386*fcf3ce44SJohn Forte * AA.BB.CC... 387*fcf3ce44SJohn Forte * AA = data service tag 388*fcf3ce44SJohn Forte * BB = set number relative to first set (1..n) 389*fcf3ce44SJohn Forte * CC = field of set or if absent, all 390*fcf3ce44SJohn Forte */ 391*fcf3ce44SJohn Forte int 392*fcf3ce44SJohn Forte cfg_get_cstring(CFGFILE *cfg, const char *key, void *value, int value_len) 393*fcf3ce44SJohn Forte { 394*fcf3ce44SJohn Forte cfp_t *cfp; 395*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 396*fcf3ce44SJohn Forte char tmpkey[CFG_MAX_KEY]; 397*fcf3ce44SJohn Forte char *section; 398*fcf3ce44SJohn Forte char set[MAX_SET]; 399*fcf3ce44SJohn Forte char *setp; 400*fcf3ce44SJohn Forte char *itemp; 401*fcf3ce44SJohn Forte char *p; 402*fcf3ce44SJohn Forte int pos = 1; 403*fcf3ce44SJohn Forte int setnum; 404*fcf3ce44SJohn Forte int relnum; 405*fcf3ce44SJohn Forte int secnum; 406*fcf3ce44SJohn Forte int numfound; 407*fcf3ce44SJohn Forte int needed; 408*fcf3ce44SJohn Forte int table_offset; 409*fcf3ce44SJohn Forte 410*fcf3ce44SJohn Forte if (cfg == NULL) { 411*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 412*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 413*fcf3ce44SJohn Forte return (-1); 414*fcf3ce44SJohn Forte } 415*fcf3ce44SJohn Forte 416*fcf3ce44SJohn Forte if (!cfg_rdlock(cfg)) { 417*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_NOTLOCKED); 418*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 419*fcf3ce44SJohn Forte return (-1); 420*fcf3ce44SJohn Forte } 421*fcf3ce44SJohn Forte 422*fcf3ce44SJohn Forte bzero(buf, sizeof (buf)); 423*fcf3ce44SJohn Forte bzero(set, sizeof (set)); 424*fcf3ce44SJohn Forte bzero(tmpkey, sizeof (tmpkey)); 425*fcf3ce44SJohn Forte strcpy(tmpkey, key); 426*fcf3ce44SJohn Forte section = strtok(tmpkey, "."); 427*fcf3ce44SJohn Forte setp = strtok(NULL, "."); 428*fcf3ce44SJohn Forte itemp = strtok(NULL, "."); 429*fcf3ce44SJohn Forte 430*fcf3ce44SJohn Forte #ifdef DEBUG_EXTRA 431*fcf3ce44SJohn Forte if (!itemp) 432*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg_get_cstring:section:%s setp=%s\n", 433*fcf3ce44SJohn Forte section, setp); 434*fcf3ce44SJohn Forte else 435*fcf3ce44SJohn Forte (void) fprintf(stderr, 436*fcf3ce44SJohn Forte "cfg_get_cstring:section:%s setp=%s fld=%s\n", 437*fcf3ce44SJohn Forte section, setp, itemp); 438*fcf3ce44SJohn Forte #endif 439*fcf3ce44SJohn Forte 440*fcf3ce44SJohn Forte table_offset = cfg_get_parser_offset(section); 441*fcf3ce44SJohn Forte setnum = atoi(setp + 3); 442*fcf3ce44SJohn Forte if ((setnum < 1) || (setnum > 0x7ffd)) { 443*fcf3ce44SJohn Forte errno = EINVAL; 444*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 445*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 446*fcf3ce44SJohn Forte return (-1); 447*fcf3ce44SJohn Forte } 448*fcf3ce44SJohn Forte 449*fcf3ce44SJohn Forte /* 450*fcf3ce44SJohn Forte * we have to figure out where this set is 451*fcf3ce44SJohn Forte * in relation to other sets 452*fcf3ce44SJohn Forte */ 453*fcf3ce44SJohn Forte relnum = 1; 454*fcf3ce44SJohn Forte secnum = 0; 455*fcf3ce44SJohn Forte numfound = 0; 456*fcf3ce44SJohn Forte for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) { 457*fcf3ce44SJohn Forte if (!cfp->cf_fd) continue; 458*fcf3ce44SJohn Forte if (cfp->cf_head->h_state & CFG_HDR_INVALID) { 459*fcf3ce44SJohn Forte if (!cfg_read(cfp)) { 460*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_RDFAILED); 461*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 462*fcf3ce44SJohn Forte return (-1); 463*fcf3ce44SJohn Forte } 464*fcf3ce44SJohn Forte } 465*fcf3ce44SJohn Forte while (numfound < setnum) { 466*fcf3ce44SJohn Forte if ((*cfp->cf_pp->readcf) 467*fcf3ce44SJohn Forte (cfp, buf, table_offset, relnum - secnum) == NULL) { 468*fcf3ce44SJohn Forte secnum = relnum - 1; 469*fcf3ce44SJohn Forte break; 470*fcf3ce44SJohn Forte } 471*fcf3ce44SJohn Forte if (cfg_filter_node(cfg, &chead[0], buf, section)) 472*fcf3ce44SJohn Forte numfound++; 473*fcf3ce44SJohn Forte 474*fcf3ce44SJohn Forte if (numfound == setnum) 475*fcf3ce44SJohn Forte break; 476*fcf3ce44SJohn Forte 477*fcf3ce44SJohn Forte relnum++; 478*fcf3ce44SJohn Forte } 479*fcf3ce44SJohn Forte if (numfound == setnum) 480*fcf3ce44SJohn Forte break; 481*fcf3ce44SJohn Forte } 482*fcf3ce44SJohn Forte 483*fcf3ce44SJohn Forte /* Fail to find anything? */ 484*fcf3ce44SJohn Forte if (cfp >= &cfg->cf[2]) { 485*fcf3ce44SJohn Forte errno = ESRCH; 486*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", strerror(errno)); 487*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 488*fcf3ce44SJohn Forte return (-1); 489*fcf3ce44SJohn Forte } 490*fcf3ce44SJohn Forte 491*fcf3ce44SJohn Forte if (buf) { 492*fcf3ce44SJohn Forte if (!itemp) { 493*fcf3ce44SJohn Forte strncpy(value, buf, value_len); 494*fcf3ce44SJohn Forte return (0); 495*fcf3ce44SJohn Forte } 496*fcf3ce44SJohn Forte 497*fcf3ce44SJohn Forte if (itemp) { 498*fcf3ce44SJohn Forte needed = cfg_get_item(&chead[0], section, itemp); 499*fcf3ce44SJohn Forte p = strtok(buf, " "); 500*fcf3ce44SJohn Forte while (p) { 501*fcf3ce44SJohn Forte if (needed == pos) { 502*fcf3ce44SJohn Forte errno = 0; 503*fcf3ce44SJohn Forte if (*p == '-') { 504*fcf3ce44SJohn Forte strcpy(value, ""); 505*fcf3ce44SJohn Forte return (0); 506*fcf3ce44SJohn Forte } 507*fcf3ce44SJohn Forte else 508*fcf3ce44SJohn Forte if (strlen(p) > value_len) { 509*fcf3ce44SJohn Forte errno = E2BIG; 510*fcf3ce44SJohn Forte cfg_perror_str = 511*fcf3ce44SJohn Forte dgettext("cfg", 512*fcf3ce44SJohn Forte strerror(errno)); 513*fcf3ce44SJohn Forte cfg_severity = 514*fcf3ce44SJohn Forte CFG_ENONFATAL; 515*fcf3ce44SJohn Forte return (-1); 516*fcf3ce44SJohn Forte } 517*fcf3ce44SJohn Forte 518*fcf3ce44SJohn Forte strncpy(value, p, value_len); 519*fcf3ce44SJohn Forte 520*fcf3ce44SJohn Forte return (pos); 521*fcf3ce44SJohn Forte } 522*fcf3ce44SJohn Forte p = strtok(NULL, " "); 523*fcf3ce44SJohn Forte if (!p) 524*fcf3ce44SJohn Forte break; 525*fcf3ce44SJohn Forte pos++; 526*fcf3ce44SJohn Forte } 527*fcf3ce44SJohn Forte } 528*fcf3ce44SJohn Forte } 529*fcf3ce44SJohn Forte errno = ESRCH; 530*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", strerror(errno)); 531*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 532*fcf3ce44SJohn Forte return (-1); 533*fcf3ce44SJohn Forte } 534*fcf3ce44SJohn Forte 535*fcf3ce44SJohn Forte /* 536*fcf3ce44SJohn Forte * cfg_find_cstring() 537*fcf3ce44SJohn Forte * search for a string in the specified section 538*fcf3ce44SJohn Forte * in the specified field(s) 539*fcf3ce44SJohn Forte * if nfld is 0, then the string is searched for in 540*fcf3ce44SJohn Forte * every field of the entry 541*fcf3ce44SJohn Forte * the set number of the first occurence of target is returned 542*fcf3ce44SJohn Forte * ie. if /dev/vx/rdsk/vol10 is found in sndr.set9, 9 will be returned 543*fcf3ce44SJohn Forte * that is, of course, if the correct field was searched on. 544*fcf3ce44SJohn Forte * -1 on error 545*fcf3ce44SJohn Forte * 546*fcf3ce44SJohn Forte */ 547*fcf3ce44SJohn Forte int 548*fcf3ce44SJohn Forte cfg_find_cstring(CFGFILE *cfg, const char *target, 549*fcf3ce44SJohn Forte const char *section, int numflds, ...) { 550*fcf3ce44SJohn Forte 551*fcf3ce44SJohn Forte char **list = NULL; 552*fcf3ce44SJohn Forte va_list ap; 553*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 554*fcf3ce44SJohn Forte char *field, *p; 555*fcf3ce44SJohn Forte char **fldbuf = NULL; 556*fcf3ce44SJohn Forte int i, j, rc; 557*fcf3ce44SJohn Forte int pos = 1; 558*fcf3ce44SJohn Forte int fieldnum; 559*fcf3ce44SJohn Forte int nflds; 560*fcf3ce44SJohn Forte int tbl_off; 561*fcf3ce44SJohn Forte 562*fcf3ce44SJohn Forte if (cfg == NULL) { 563*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 564*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 565*fcf3ce44SJohn Forte return (-1); 566*fcf3ce44SJohn Forte } 567*fcf3ce44SJohn Forte 568*fcf3ce44SJohn Forte if (numflds == 0) { 569*fcf3ce44SJohn Forte nflds = cfg_get_num_flds(&chead[0], section, &tbl_off); 570*fcf3ce44SJohn Forte 571*fcf3ce44SJohn Forte } else { 572*fcf3ce44SJohn Forte nflds = numflds; 573*fcf3ce44SJohn Forte } 574*fcf3ce44SJohn Forte if ((fldbuf = calloc(nflds, CFG_MAX_KEY)) == NULL) { 575*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", strerror(errno)); 576*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 577*fcf3ce44SJohn Forte return (-1); 578*fcf3ce44SJohn Forte } 579*fcf3ce44SJohn Forte 580*fcf3ce44SJohn Forte if (numflds == 0) { /* search the whole string */ 581*fcf3ce44SJohn Forte if ((rc = cfg_get_section(cfg, &list, section)) <= 0) { 582*fcf3ce44SJohn Forte for (i = 0; i < nflds; i++) 583*fcf3ce44SJohn Forte free(fldbuf[i]); 584*fcf3ce44SJohn Forte free(fldbuf); 585*fcf3ce44SJohn Forte return (rc); 586*fcf3ce44SJohn Forte } 587*fcf3ce44SJohn Forte for (i = 0; i < rc; i++) { 588*fcf3ce44SJohn Forte bzero(buf, sizeof (buf)); 589*fcf3ce44SJohn Forte strcpy(buf, list[i]); 590*fcf3ce44SJohn Forte p = strtok(buf, " "); 591*fcf3ce44SJohn Forte while (p) { 592*fcf3ce44SJohn Forte if (strcmp(p, target) == 0) { /* we found it! */ 593*fcf3ce44SJohn Forte for (j = 0; j < rc; j++) 594*fcf3ce44SJohn Forte free(list[j]); 595*fcf3ce44SJohn Forte free(list); 596*fcf3ce44SJohn Forte for (j = 0; j < nflds; j++) 597*fcf3ce44SJohn Forte free(fldbuf[j]); 598*fcf3ce44SJohn Forte free(fldbuf); 599*fcf3ce44SJohn Forte return (i + 1); 600*fcf3ce44SJohn Forte } 601*fcf3ce44SJohn Forte p = strtok(NULL, " "); 602*fcf3ce44SJohn Forte } 603*fcf3ce44SJohn Forte } 604*fcf3ce44SJohn Forte for (i = 0; i < nflds; i++) 605*fcf3ce44SJohn Forte free(fldbuf[j]); 606*fcf3ce44SJohn Forte for (i = 0; i < rc; i++) 607*fcf3ce44SJohn Forte free(list[i]); 608*fcf3ce44SJohn Forte free(fldbuf); 609*fcf3ce44SJohn Forte free(list); 610*fcf3ce44SJohn Forte return (0); 611*fcf3ce44SJohn Forte } 612*fcf3ce44SJohn Forte 613*fcf3ce44SJohn Forte if ((rc = cfg_get_section(cfg, &list, section)) <= 0) { 614*fcf3ce44SJohn Forte for (i = 0; i < nflds; i++) 615*fcf3ce44SJohn Forte free(fldbuf[i]); 616*fcf3ce44SJohn Forte free(fldbuf); 617*fcf3ce44SJohn Forte return (rc); 618*fcf3ce44SJohn Forte } 619*fcf3ce44SJohn Forte 620*fcf3ce44SJohn Forte va_start(ap, numflds); 621*fcf3ce44SJohn Forte for (i = 0; i < numflds; i++) { 622*fcf3ce44SJohn Forte fldbuf[i] = strdup(va_arg(ap, char *)); 623*fcf3ce44SJohn Forte } 624*fcf3ce44SJohn Forte 625*fcf3ce44SJohn Forte fldbuf[i] = NULL; 626*fcf3ce44SJohn Forte 627*fcf3ce44SJohn Forte for (j = 0; j < numflds; j++) { 628*fcf3ce44SJohn Forte fieldnum = cfg_get_item(&chead[0], section, fldbuf[j]); 629*fcf3ce44SJohn Forte for (i = 0; i < rc; i++) { 630*fcf3ce44SJohn Forte bzero(buf, sizeof (buf)); 631*fcf3ce44SJohn Forte strcpy(buf, list[i]); 632*fcf3ce44SJohn Forte 633*fcf3ce44SJohn Forte field = strtok(buf, " "); 634*fcf3ce44SJohn Forte pos = 1; 635*fcf3ce44SJohn Forte while (pos < fieldnum) { 636*fcf3ce44SJohn Forte field = strtok(NULL, " "); 637*fcf3ce44SJohn Forte pos++; 638*fcf3ce44SJohn Forte } 639*fcf3ce44SJohn Forte if (field == NULL) { 640*fcf3ce44SJohn Forte for (j = 0; j < numflds; j++) 641*fcf3ce44SJohn Forte free(fldbuf[j]); 642*fcf3ce44SJohn Forte for (j = 0; j < rc; j++) 643*fcf3ce44SJohn Forte free(list[j]); 644*fcf3ce44SJohn Forte free(fldbuf); 645*fcf3ce44SJohn Forte free(list); 646*fcf3ce44SJohn Forte return (-1); 647*fcf3ce44SJohn Forte } 648*fcf3ce44SJohn Forte 649*fcf3ce44SJohn Forte if (strcmp(field, target) == 0) { 650*fcf3ce44SJohn Forte for (j = 0; j < numflds; j++) 651*fcf3ce44SJohn Forte free(fldbuf[j]); 652*fcf3ce44SJohn Forte for (j = 0; j < rc; j++) 653*fcf3ce44SJohn Forte free(list[j]); 654*fcf3ce44SJohn Forte free(fldbuf); 655*fcf3ce44SJohn Forte free(list); 656*fcf3ce44SJohn Forte 657*fcf3ce44SJohn Forte return (i + 1); 658*fcf3ce44SJohn Forte } 659*fcf3ce44SJohn Forte 660*fcf3ce44SJohn Forte } 661*fcf3ce44SJohn Forte 662*fcf3ce44SJohn Forte } 663*fcf3ce44SJohn Forte for (i = 0; i < nflds; i++) 664*fcf3ce44SJohn Forte free(fldbuf[i]); 665*fcf3ce44SJohn Forte for (i = 0; i < rc; i++) 666*fcf3ce44SJohn Forte free(list[i]); 667*fcf3ce44SJohn Forte free(fldbuf); 668*fcf3ce44SJohn Forte free(list); 669*fcf3ce44SJohn Forte return (0); 670*fcf3ce44SJohn Forte } 671*fcf3ce44SJohn Forte 672*fcf3ce44SJohn Forte /* 673*fcf3ce44SJohn Forte * cfg_put_cstring 674*fcf3ce44SJohn Forte * modify entry or add an entry to configuration section 675*fcf3ce44SJohn Forte * Key syntax supported 676*fcf3ce44SJohn Forte * tag Add entry (in entirely) to config 677*fcf3ce44SJohn Forte * tag.setn Add entry to setn If it exists overwrite old entry 678*fcf3ce44SJohn Forte * tag.setn.field Change field in setn 679*fcf3ce44SJohn Forte * value 680*fcf3ce44SJohn Forte * string to change 681*fcf3ce44SJohn Forte * NULL delete specified key 682*fcf3ce44SJohn Forte * 683*fcf3ce44SJohn Forte */ 684*fcf3ce44SJohn Forte 685*fcf3ce44SJohn Forte int 686*fcf3ce44SJohn Forte cfg_put_cstring(CFGFILE *cfg, const char *key, void *value, int val_len) 687*fcf3ce44SJohn Forte { 688*fcf3ce44SJohn Forte cfp_t *cfp; 689*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 690*fcf3ce44SJohn Forte char newbuf[CFG_MAX_BUF]; 691*fcf3ce44SJohn Forte char *bufp; 692*fcf3ce44SJohn Forte char tmpkey[CFG_MAX_KEY]; 693*fcf3ce44SJohn Forte char *section; 694*fcf3ce44SJohn Forte char *setp; 695*fcf3ce44SJohn Forte char *itemp; 696*fcf3ce44SJohn Forte int nofield = 0; 697*fcf3ce44SJohn Forte int noset = 0; 698*fcf3ce44SJohn Forte int fldnum; 699*fcf3ce44SJohn Forte int setnum = 0; 700*fcf3ce44SJohn Forte int relnum; 701*fcf3ce44SJohn Forte int secnum; 702*fcf3ce44SJohn Forte int numfound; 703*fcf3ce44SJohn Forte int addcnode = 1; 704*fcf3ce44SJohn Forte int table_index; 705*fcf3ce44SJohn Forte int table_offset; 706*fcf3ce44SJohn Forte 707*fcf3ce44SJohn Forte if (cfg == NULL) { 708*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 709*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 710*fcf3ce44SJohn Forte return (-1); 711*fcf3ce44SJohn Forte } 712*fcf3ce44SJohn Forte 713*fcf3ce44SJohn Forte bzero(buf, sizeof (buf)); 714*fcf3ce44SJohn Forte strcpy(tmpkey, key); 715*fcf3ce44SJohn Forte section = strtok(tmpkey, "."); 716*fcf3ce44SJohn Forte setp = strtok(NULL, "."); 717*fcf3ce44SJohn Forte itemp = strtok(NULL, "."); 718*fcf3ce44SJohn Forte 719*fcf3ce44SJohn Forte if (!cfg_wrlock(cfg)) { 720*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_RDFAILED); 721*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 722*fcf3ce44SJohn Forte return (-1); 723*fcf3ce44SJohn Forte } 724*fcf3ce44SJohn Forte 725*fcf3ce44SJohn Forte if (!key) { 726*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 727*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 728*fcf3ce44SJohn Forte return (-1); 729*fcf3ce44SJohn Forte } 730*fcf3ce44SJohn Forte if (value && val_len == 0) { 731*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 732*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 733*fcf3ce44SJohn Forte return (-1); 734*fcf3ce44SJohn Forte } 735*fcf3ce44SJohn Forte if (!itemp) 736*fcf3ce44SJohn Forte nofield++; 737*fcf3ce44SJohn Forte if (!setp) 738*fcf3ce44SJohn Forte noset++; 739*fcf3ce44SJohn Forte else if (setp) { 740*fcf3ce44SJohn Forte setnum = atoi(setp + 3); 741*fcf3ce44SJohn Forte if (setnum < 1 || setnum > 0x7ffd) { 742*fcf3ce44SJohn Forte errno = EINVAL; 743*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 744*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 745*fcf3ce44SJohn Forte return (-1); 746*fcf3ce44SJohn Forte } 747*fcf3ce44SJohn Forte } 748*fcf3ce44SJohn Forte 749*fcf3ce44SJohn Forte table_offset = cfg_get_parser_offset(section); 750*fcf3ce44SJohn Forte 751*fcf3ce44SJohn Forte /* 752*fcf3ce44SJohn Forte * we have to figure out where this set is 753*fcf3ce44SJohn Forte * in relation to other sets 754*fcf3ce44SJohn Forte */ 755*fcf3ce44SJohn Forte relnum = 1; 756*fcf3ce44SJohn Forte secnum = 0; 757*fcf3ce44SJohn Forte numfound = 0; 758*fcf3ce44SJohn Forte 759*fcf3ce44SJohn Forte if (setp && nofield) { 760*fcf3ce44SJohn Forte char tmpbuf[CFG_MAX_BUF]; 761*fcf3ce44SJohn Forte int rc; 762*fcf3ce44SJohn Forte int nflds; 763*fcf3ce44SJohn Forte int got; 764*fcf3ce44SJohn Forte 765*fcf3ce44SJohn Forte /* 766*fcf3ce44SJohn Forte * Set specified but no field 767*fcf3ce44SJohn Forte */ 768*fcf3ce44SJohn Forte for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) { 769*fcf3ce44SJohn Forte if (!cfp->cf_fd) continue; 770*fcf3ce44SJohn Forte if (cfp->cf_head->h_state & CFG_HDR_INVALID) { 771*fcf3ce44SJohn Forte if (!cfg_read(cfp)) { 772*fcf3ce44SJohn Forte cfg_perror_str = 773*fcf3ce44SJohn Forte dgettext("cfg", CFG_RDFAILED); 774*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 775*fcf3ce44SJohn Forte return (-1); 776*fcf3ce44SJohn Forte } 777*fcf3ce44SJohn Forte } 778*fcf3ce44SJohn Forte while (numfound < setnum) { 779*fcf3ce44SJohn Forte if ((*cfp->cf_pp->readcf) 780*fcf3ce44SJohn Forte (cfp, tmpbuf, table_offset, relnum - secnum) 781*fcf3ce44SJohn Forte == NULL) { 782*fcf3ce44SJohn Forte secnum = relnum - 1; 783*fcf3ce44SJohn Forte break; 784*fcf3ce44SJohn Forte } 785*fcf3ce44SJohn Forte if (cfg_filter_node(cfg, &chead[0], tmpbuf, 786*fcf3ce44SJohn Forte section)) 787*fcf3ce44SJohn Forte numfound++; 788*fcf3ce44SJohn Forte 789*fcf3ce44SJohn Forte if (numfound == setnum) 790*fcf3ce44SJohn Forte break; 791*fcf3ce44SJohn Forte 792*fcf3ce44SJohn Forte relnum++; 793*fcf3ce44SJohn Forte } 794*fcf3ce44SJohn Forte if (numfound == setnum) 795*fcf3ce44SJohn Forte break; 796*fcf3ce44SJohn Forte } 797*fcf3ce44SJohn Forte 798*fcf3ce44SJohn Forte /* Fail to find anything? */ 799*fcf3ce44SJohn Forte if (cfp >= &cfg->cf[2]) { 800*fcf3ce44SJohn Forte errno = ESRCH; 801*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", strerror(errno)); 802*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 803*fcf3ce44SJohn Forte return (-1); 804*fcf3ce44SJohn Forte } 805*fcf3ce44SJohn Forte 806*fcf3ce44SJohn Forte nflds = cfg_get_num_flds(&chead[0], section, &table_index); 807*fcf3ce44SJohn Forte 808*fcf3ce44SJohn Forte if (value == NULL) { 809*fcf3ce44SJohn Forte /* Remove entry completely */ 810*fcf3ce44SJohn Forte 811*fcf3ce44SJohn Forte if ((rc = ((*cfp->cf_pp->remcf) 812*fcf3ce44SJohn Forte (cfp, table_index, relnum - secnum))) < 0) 813*fcf3ce44SJohn Forte return (rc); 814*fcf3ce44SJohn Forte return (0); 815*fcf3ce44SJohn Forte } 816*fcf3ce44SJohn Forte 817*fcf3ce44SJohn Forte got = cfg_cnt_flds(value); 818*fcf3ce44SJohn Forte bzero(buf, sizeof (buf)); 819*fcf3ce44SJohn Forte 820*fcf3ce44SJohn Forte strncpy(buf, " ", 1); 821*fcf3ce44SJohn Forte if (strlen(value) > sizeof (buf) - 2) { 822*fcf3ce44SJohn Forte errno = E2BIG; 823*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", strerror(errno)); 824*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 825*fcf3ce44SJohn Forte return (-1); 826*fcf3ce44SJohn Forte } 827*fcf3ce44SJohn Forte strncat(buf, value, val_len); 828*fcf3ce44SJohn Forte if (got < nflds) { 829*fcf3ce44SJohn Forte for (/* CSTYLED */; got < nflds; got++) 830*fcf3ce44SJohn Forte strncat(buf, " - ", 3); 831*fcf3ce44SJohn Forte } else if (got > nflds) { 832*fcf3ce44SJohn Forte return (-1); 833*fcf3ce44SJohn Forte } else { 834*fcf3ce44SJohn Forte /* got == nflds, so cnode was included */ 835*fcf3ce44SJohn Forte addcnode = 0; 836*fcf3ce44SJohn Forte } 837*fcf3ce44SJohn Forte 838*fcf3ce44SJohn Forte bufp = buf; 839*fcf3ce44SJohn Forte if (addcnode) { 840*fcf3ce44SJohn Forte cfg_insert_node(cfg, &chead[0], buf, section); 841*fcf3ce44SJohn Forte } 842*fcf3ce44SJohn Forte 843*fcf3ce44SJohn Forte (*cfp->cf_pp->replacecf) 844*fcf3ce44SJohn Forte (cfp, bufp, table_index, relnum - secnum); 845*fcf3ce44SJohn Forte 846*fcf3ce44SJohn Forte return (TRUE); 847*fcf3ce44SJohn Forte } 848*fcf3ce44SJohn Forte 849*fcf3ce44SJohn Forte /* 850*fcf3ce44SJohn Forte * Both Set and field are specified 851*fcf3ce44SJohn Forte * needs to get current whole entry and old requested field 852*fcf3ce44SJohn Forte * copy good fields to buf, replace new field in buf 853*fcf3ce44SJohn Forte * move everything depending of new size 854*fcf3ce44SJohn Forte * replace entry so set# does not change 855*fcf3ce44SJohn Forte */ 856*fcf3ce44SJohn Forte if (setp && itemp) { 857*fcf3ce44SJohn Forte int rc; 858*fcf3ce44SJohn Forte int nflds; 859*fcf3ce44SJohn Forte int cnodepos; 860*fcf3ce44SJohn Forte 861*fcf3ce44SJohn Forte for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) { 862*fcf3ce44SJohn Forte if (!cfp->cf_fd) continue; 863*fcf3ce44SJohn Forte if (cfp->cf_head->h_state & CFG_HDR_INVALID) { 864*fcf3ce44SJohn Forte if (!cfg_read(cfp)) { 865*fcf3ce44SJohn Forte cfg_perror_str = 866*fcf3ce44SJohn Forte dgettext("cfg", CFG_RDFAILED); 867*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 868*fcf3ce44SJohn Forte return (-1); 869*fcf3ce44SJohn Forte } 870*fcf3ce44SJohn Forte } 871*fcf3ce44SJohn Forte while (numfound < setnum) { 872*fcf3ce44SJohn Forte if ((*cfp->cf_pp->readcf) 873*fcf3ce44SJohn Forte (cfp, buf, table_offset, relnum - secnum) 874*fcf3ce44SJohn Forte == NULL) { 875*fcf3ce44SJohn Forte secnum = relnum - 1; 876*fcf3ce44SJohn Forte break; 877*fcf3ce44SJohn Forte } 878*fcf3ce44SJohn Forte if (cfg_filter_node(cfg, &chead[0], buf, 879*fcf3ce44SJohn Forte section)) 880*fcf3ce44SJohn Forte numfound++; 881*fcf3ce44SJohn Forte 882*fcf3ce44SJohn Forte if (numfound == setnum) 883*fcf3ce44SJohn Forte break; 884*fcf3ce44SJohn Forte 885*fcf3ce44SJohn Forte relnum++; 886*fcf3ce44SJohn Forte } 887*fcf3ce44SJohn Forte if (numfound == setnum) 888*fcf3ce44SJohn Forte break; 889*fcf3ce44SJohn Forte } 890*fcf3ce44SJohn Forte 891*fcf3ce44SJohn Forte /* Fail to find anything? */ 892*fcf3ce44SJohn Forte if (cfp >= &cfg->cf[2]) { 893*fcf3ce44SJohn Forte errno = ESRCH; 894*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", strerror(errno)); 895*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 896*fcf3ce44SJohn Forte return (-1); 897*fcf3ce44SJohn Forte } 898*fcf3ce44SJohn Forte 899*fcf3ce44SJohn Forte nflds = cfg_get_num_flds(&chead[0], section, &table_index); 900*fcf3ce44SJohn Forte fldnum = cfg_get_item(&chead[0], section, itemp); 901*fcf3ce44SJohn Forte bzero(newbuf, sizeof (newbuf)); 902*fcf3ce44SJohn Forte strncpy(newbuf, " ", 1); 903*fcf3ce44SJohn Forte 904*fcf3ce44SJohn Forte /* move good flds in */ 905*fcf3ce44SJohn Forte rc = cfg_fld_mov(newbuf, buf, 1, fldnum - 1); 906*fcf3ce44SJohn Forte if (rc < 0) 907*fcf3ce44SJohn Forte return (rc); 908*fcf3ce44SJohn Forte 909*fcf3ce44SJohn Forte /* move new fld in */ 910*fcf3ce44SJohn Forte strncat(newbuf, value, strlen(value)); 911*fcf3ce44SJohn Forte strcat(newbuf, " "); 912*fcf3ce44SJohn Forte 913*fcf3ce44SJohn Forte /* move remaining flds in */ 914*fcf3ce44SJohn Forte rc = cfg_fld_mov(newbuf, buf, fldnum + 1, nflds); 915*fcf3ce44SJohn Forte if (rc < 0) 916*fcf3ce44SJohn Forte return (rc); 917*fcf3ce44SJohn Forte 918*fcf3ce44SJohn Forte cnodepos = cfg_get_item(&chead[0], section, "cnode"); 919*fcf3ce44SJohn Forte if ((cnodepos >= 0) && strcmp(itemp, "cnode") != 0) { 920*fcf3ce44SJohn Forte /* add cnode if user didn't specify it */ 921*fcf3ce44SJohn Forte cfg_insert_node(cfg, &chead[0], 922*fcf3ce44SJohn Forte newbuf, section); 923*fcf3ce44SJohn Forte } 924*fcf3ce44SJohn Forte 925*fcf3ce44SJohn Forte (*cfp->cf_pp->replacecf) 926*fcf3ce44SJohn Forte (cfp, newbuf, table_index, relnum - secnum); 927*fcf3ce44SJohn Forte 928*fcf3ce44SJohn Forte return (TRUE); 929*fcf3ce44SJohn Forte } 930*fcf3ce44SJohn Forte 931*fcf3ce44SJohn Forte if (noset) { /* blast entire thing in */ 932*fcf3ce44SJohn Forte int nflds; 933*fcf3ce44SJohn Forte int got; 934*fcf3ce44SJohn Forte int cnodepos; 935*fcf3ce44SJohn Forte 936*fcf3ce44SJohn Forte bufp = buf; 937*fcf3ce44SJohn Forte if (!value) { /* we shouldn't be here */ 938*fcf3ce44SJohn Forte errno = EINVAL; 939*fcf3ce44SJohn Forte return (-1); 940*fcf3ce44SJohn Forte } 941*fcf3ce44SJohn Forte strncat(buf, " ", 1); 942*fcf3ce44SJohn Forte if (strlen(value) > sizeof (buf) - 2) { 943*fcf3ce44SJohn Forte errno = E2BIG; 944*fcf3ce44SJohn Forte return (-1); 945*fcf3ce44SJohn Forte } 946*fcf3ce44SJohn Forte 947*fcf3ce44SJohn Forte strncat(buf, value, val_len); 948*fcf3ce44SJohn Forte nflds = cfg_get_num_flds(&chead[0], section, &table_index); 949*fcf3ce44SJohn Forte got = cfg_cnt_flds(value); 950*fcf3ce44SJohn Forte 951*fcf3ce44SJohn Forte cnodepos = cfg_get_item(&chead[0], section, "cnode"); 952*fcf3ce44SJohn Forte if (cnodepos < 0 || got >= cnodepos) { 953*fcf3ce44SJohn Forte /* no cnode, or cnode was specified by caller */ 954*fcf3ce44SJohn Forte addcnode = 0; 955*fcf3ce44SJohn Forte } 956*fcf3ce44SJohn Forte 957*fcf3ce44SJohn Forte if (got < nflds) { 958*fcf3ce44SJohn Forte for (/* CSTYLED */; got < nflds; got++) 959*fcf3ce44SJohn Forte strncat(buf, " - ", 3); 960*fcf3ce44SJohn Forte } else if (got > nflds) { 961*fcf3ce44SJohn Forte errno = EINVAL; /* specified too many fields */ 962*fcf3ce44SJohn Forte return (-1); 963*fcf3ce44SJohn Forte } else { 964*fcf3ce44SJohn Forte /* got == nflds, so cnode was included */ 965*fcf3ce44SJohn Forte addcnode = 0; 966*fcf3ce44SJohn Forte } 967*fcf3ce44SJohn Forte 968*fcf3ce44SJohn Forte if (addcnode) { 969*fcf3ce44SJohn Forte cfg_insert_node(cfg, &chead[0], buf, section); 970*fcf3ce44SJohn Forte } 971*fcf3ce44SJohn Forte 972*fcf3ce44SJohn Forte /* Make sure we put this entry in the right database */ 973*fcf3ce44SJohn Forte if (cfg_is_cnode(cfg, &chead[0], buf, section) && 974*fcf3ce44SJohn Forte cfg->cf[1].cf_fd) 975*fcf3ce44SJohn Forte cfp = &cfg->cf[1]; 976*fcf3ce44SJohn Forte else 977*fcf3ce44SJohn Forte cfp = &cfg->cf[0]; 978*fcf3ce44SJohn Forte 979*fcf3ce44SJohn Forte if (cfp->cf_head->h_state & CFG_HDR_INVALID) { 980*fcf3ce44SJohn Forte if (!cfg_read(cfp)) { 981*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_RDFAILED); 982*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 983*fcf3ce44SJohn Forte return (-1); 984*fcf3ce44SJohn Forte } 985*fcf3ce44SJohn Forte } 986*fcf3ce44SJohn Forte if (cfp->cf_head->h_csize + strlen(buf) > CFG_DEFAULT_SSIZE) { 987*fcf3ce44SJohn Forte errno = ENOSPC; 988*fcf3ce44SJohn Forte return (-1); 989*fcf3ce44SJohn Forte } 990*fcf3ce44SJohn Forte 991*fcf3ce44SJohn Forte (*cfp->cf_pp->addcf)(cfp, bufp, table_index); 992*fcf3ce44SJohn Forte 993*fcf3ce44SJohn Forte return (TRUE); 994*fcf3ce44SJohn Forte } 995*fcf3ce44SJohn Forte 996*fcf3ce44SJohn Forte errno = EINVAL; 997*fcf3ce44SJohn Forte cfg_perror_str = strerror(errno); 998*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 999*fcf3ce44SJohn Forte return (-1); 1000*fcf3ce44SJohn Forte } 1001*fcf3ce44SJohn Forte 1002*fcf3ce44SJohn Forte /* 1003*fcf3ce44SJohn Forte * cfg_encode_char 1004*fcf3ce44SJohn Forte * 1005*fcf3ce44SJohn Forte * Encode a single character into % + hex ascii value 1006*fcf3ce44SJohn Forte */ 1007*fcf3ce44SJohn Forte static void 1008*fcf3ce44SJohn Forte cfg_encode_char(char *result, char ch) 1009*fcf3ce44SJohn Forte { 1010*fcf3ce44SJohn Forte *result++ = '%'; 1011*fcf3ce44SJohn Forte *result++ = dectohex[ (ch >> 4) & 0xf ]; 1012*fcf3ce44SJohn Forte *result++ = dectohex[ ch & 0xf ]; 1013*fcf3ce44SJohn Forte } 1014*fcf3ce44SJohn Forte 1015*fcf3ce44SJohn Forte /* 1016*fcf3ce44SJohn Forte * cfg_decode_char 1017*fcf3ce44SJohn Forte * 1018*fcf3ce44SJohn Forte * Reverses cfg_encode_char 1019*fcf3ce44SJohn Forte */ 1020*fcf3ce44SJohn Forte static char 1021*fcf3ce44SJohn Forte cfg_decode_char(char *code) 1022*fcf3ce44SJohn Forte { 1023*fcf3ce44SJohn Forte char retval; 1024*fcf3ce44SJohn Forte if (*code != '%') { 1025*fcf3ce44SJohn Forte return ('\0'); 1026*fcf3ce44SJohn Forte } 1027*fcf3ce44SJohn Forte ++code; 1028*fcf3ce44SJohn Forte if (!isxdigit(*code)) 1029*fcf3ce44SJohn Forte return ('\0'); 1030*fcf3ce44SJohn Forte retval = (isdigit(*code)? *code - '0' : *code - 'a' + 10); 1031*fcf3ce44SJohn Forte retval <<= 4; 1032*fcf3ce44SJohn Forte ++code; 1033*fcf3ce44SJohn Forte if (!isxdigit(*code)) 1034*fcf3ce44SJohn Forte return ('\0'); 1035*fcf3ce44SJohn Forte retval |= (isdigit(*code)? *code - '0' : *code - 'a' + 10); 1036*fcf3ce44SJohn Forte 1037*fcf3ce44SJohn Forte return (retval); 1038*fcf3ce44SJohn Forte } 1039*fcf3ce44SJohn Forte 1040*fcf3ce44SJohn Forte /* 1041*fcf3ce44SJohn Forte * cfg_encode_option 1042*fcf3ce44SJohn Forte * 1043*fcf3ce44SJohn Forte * Transforms the key and value strings so that special characters 1044*fcf3ce44SJohn Forte * can be used within the options field. 1045*fcf3ce44SJohn Forte * 1046*fcf3ce44SJohn Forte * Returns: 1047*fcf3ce44SJohn Forte * Length of encoded string; -1 on failure 1048*fcf3ce44SJohn Forte */ 1049*fcf3ce44SJohn Forte static int 1050*fcf3ce44SJohn Forte cfg_encode_string(char *str, char *output, int outlen) 1051*fcf3ce44SJohn Forte { 1052*fcf3ce44SJohn Forte char *mem, *p, *q; 1053*fcf3ce44SJohn Forte int curlen; 1054*fcf3ce44SJohn Forte 1055*fcf3ce44SJohn Forte 1056*fcf3ce44SJohn Forte /* first, scan through the tag string converting %-signs */ 1057*fcf3ce44SJohn Forte p = str; 1058*fcf3ce44SJohn Forte q = output; 1059*fcf3ce44SJohn Forte curlen = 0; 1060*fcf3ce44SJohn Forte while (*p && curlen < outlen) { 1061*fcf3ce44SJohn Forte if (*p == '%') { 1062*fcf3ce44SJohn Forte if (curlen + 3 >= outlen) { 1063*fcf3ce44SJohn Forte return (-1); 1064*fcf3ce44SJohn Forte } 1065*fcf3ce44SJohn Forte cfg_encode_char(q, *p); 1066*fcf3ce44SJohn Forte curlen += 3; 1067*fcf3ce44SJohn Forte q += 3; 1068*fcf3ce44SJohn Forte } else { 1069*fcf3ce44SJohn Forte *q++ = *p; 1070*fcf3ce44SJohn Forte ++curlen; 1071*fcf3ce44SJohn Forte } 1072*fcf3ce44SJohn Forte ++p; 1073*fcf3ce44SJohn Forte } 1074*fcf3ce44SJohn Forte if (curlen < outlen) 1075*fcf3ce44SJohn Forte *q = '\0'; 1076*fcf3ce44SJohn Forte 1077*fcf3ce44SJohn Forte /* now encode special characters */ 1078*fcf3ce44SJohn Forte p = mem = strdup(output); 1079*fcf3ce44SJohn Forte q = output; 1080*fcf3ce44SJohn Forte curlen = 0; 1081*fcf3ce44SJohn Forte while (*p && curlen < outlen) { 1082*fcf3ce44SJohn Forte if (strchr(CHARS_TO_ENCODE, *p) != 0) { 1083*fcf3ce44SJohn Forte if (curlen + 3 >= outlen) { 1084*fcf3ce44SJohn Forte free(mem); 1085*fcf3ce44SJohn Forte return (-1); 1086*fcf3ce44SJohn Forte } 1087*fcf3ce44SJohn Forte cfg_encode_char(q, *p); 1088*fcf3ce44SJohn Forte curlen += 3; 1089*fcf3ce44SJohn Forte q += 3; 1090*fcf3ce44SJohn Forte } else { 1091*fcf3ce44SJohn Forte *q++ = *p; 1092*fcf3ce44SJohn Forte ++curlen; 1093*fcf3ce44SJohn Forte } 1094*fcf3ce44SJohn Forte ++p; 1095*fcf3ce44SJohn Forte } 1096*fcf3ce44SJohn Forte free(mem); 1097*fcf3ce44SJohn Forte 1098*fcf3ce44SJohn Forte if (curlen < outlen) 1099*fcf3ce44SJohn Forte *q = '\0'; 1100*fcf3ce44SJohn Forte /* LINTED possible ptrdiff_t overflow */ 1101*fcf3ce44SJohn Forte return (q - output); 1102*fcf3ce44SJohn Forte } 1103*fcf3ce44SJohn Forte 1104*fcf3ce44SJohn Forte /* 1105*fcf3ce44SJohn Forte * cfg_decode_option 1106*fcf3ce44SJohn Forte * 1107*fcf3ce44SJohn Forte * Given a string, decodes any %-encodes on it. 1108*fcf3ce44SJohn Forte */ 1109*fcf3ce44SJohn Forte static void 1110*fcf3ce44SJohn Forte cfg_decode_string(char *str, char *output, int outlen) 1111*fcf3ce44SJohn Forte { 1112*fcf3ce44SJohn Forte char *p, *q; 1113*fcf3ce44SJohn Forte int curlen; 1114*fcf3ce44SJohn Forte 1115*fcf3ce44SJohn Forte p = str; 1116*fcf3ce44SJohn Forte q = output; 1117*fcf3ce44SJohn Forte curlen = 0; 1118*fcf3ce44SJohn Forte while (*p && curlen < outlen) { 1119*fcf3ce44SJohn Forte if (*p == '%') { 1120*fcf3ce44SJohn Forte char ch = cfg_decode_char(p); 1121*fcf3ce44SJohn Forte if (!ch) { 1122*fcf3ce44SJohn Forte *q++ = *p++; 1123*fcf3ce44SJohn Forte ++curlen; 1124*fcf3ce44SJohn Forte } else { 1125*fcf3ce44SJohn Forte *q++ = ch; 1126*fcf3ce44SJohn Forte p += 3; 1127*fcf3ce44SJohn Forte ++curlen; 1128*fcf3ce44SJohn Forte } 1129*fcf3ce44SJohn Forte } else { 1130*fcf3ce44SJohn Forte *q++ = *p++; 1131*fcf3ce44SJohn Forte ++curlen; 1132*fcf3ce44SJohn Forte } 1133*fcf3ce44SJohn Forte } 1134*fcf3ce44SJohn Forte if (curlen < outlen) 1135*fcf3ce44SJohn Forte *q = '\0'; 1136*fcf3ce44SJohn Forte } 1137*fcf3ce44SJohn Forte 1138*fcf3ce44SJohn Forte /* 1139*fcf3ce44SJohn Forte * cfg_get_options 1140*fcf3ce44SJohn Forte * return first options set from basekey 1141*fcf3ce44SJohn Forte * Subsequent calls with basekey = NULL return next option if any 1142*fcf3ce44SJohn Forte * into tag and val 1143*fcf3ce44SJohn Forte * returns 1144*fcf3ce44SJohn Forte * true success and more options data 1145*fcf3ce44SJohn Forte * -1 no options data 1146*fcf3ce44SJohn Forte */ 1147*fcf3ce44SJohn Forte 1148*fcf3ce44SJohn Forte int 1149*fcf3ce44SJohn Forte cfg_get_options(CFGFILE *cfg, int section, const char *basekey, char *tag, 1150*fcf3ce44SJohn Forte int tag_len, char *val, int val_len) 1151*fcf3ce44SJohn Forte { 1152*fcf3ce44SJohn Forte static char buf[CFG_MAX_BUF]; 1153*fcf3ce44SJohn Forte char decode_buf[CFG_MAX_BUF]; 1154*fcf3ce44SJohn Forte int rc; 1155*fcf3ce44SJohn Forte char *ttag, *tval; 1156*fcf3ce44SJohn Forte 1157*fcf3ce44SJohn Forte if (cfg == NULL) { 1158*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 1159*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 1160*fcf3ce44SJohn Forte return (-1); 1161*fcf3ce44SJohn Forte } 1162*fcf3ce44SJohn Forte 1163*fcf3ce44SJohn Forte errno = ENOSYS; 1164*fcf3ce44SJohn Forte if (basekey == 0) { 1165*fcf3ce44SJohn Forte ttag = strtok(NULL, "="); 1166*fcf3ce44SJohn Forte } else { 1167*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 1168*fcf3ce44SJohn Forte if (section == CFG_SEC_CONF) { 1169*fcf3ce44SJohn Forte rc = cfg_get_cstring(cfg, basekey, buf, CFG_MAX_BUF); 1170*fcf3ce44SJohn Forte } else 1171*fcf3ce44SJohn Forte return (-1); 1172*fcf3ce44SJohn Forte if (rc < 0) 1173*fcf3ce44SJohn Forte return (rc); 1174*fcf3ce44SJohn Forte /* buf now contains raw options data */ 1175*fcf3ce44SJohn Forte ttag = strtok(buf, "="); 1176*fcf3ce44SJohn Forte } 1177*fcf3ce44SJohn Forte tval = strtok(NULL, ";"); 1178*fcf3ce44SJohn Forte if (!(tval) || !(ttag)) 1179*fcf3ce44SJohn Forte return (-1); 1180*fcf3ce44SJohn Forte if ((strlen(tval) > val_len) || (strlen(ttag) > tag_len)) { 1181*fcf3ce44SJohn Forte errno = E2BIG; 1182*fcf3ce44SJohn Forte return (-1); 1183*fcf3ce44SJohn Forte } 1184*fcf3ce44SJohn Forte cfg_decode_string(tval, decode_buf, CFG_MAX_BUF); 1185*fcf3ce44SJohn Forte strncpy(val, decode_buf, val_len); 1186*fcf3ce44SJohn Forte cfg_decode_string(ttag, decode_buf, CFG_MAX_BUF); 1187*fcf3ce44SJohn Forte strncpy(tag, decode_buf, tag_len); 1188*fcf3ce44SJohn Forte errno = 0; 1189*fcf3ce44SJohn Forte return (TRUE); 1190*fcf3ce44SJohn Forte } 1191*fcf3ce44SJohn Forte 1192*fcf3ce44SJohn Forte /* 1193*fcf3ce44SJohn Forte * cfg_put_options 1194*fcf3ce44SJohn Forte * 1195*fcf3ce44SJohn Forte * Replaces existing tag with new val. If tag doesn't exist, 1196*fcf3ce44SJohn Forte * then it adds a new tag with the specified val. 1197*fcf3ce44SJohn Forte * 1198*fcf3ce44SJohn Forte * Return: 1199*fcf3ce44SJohn Forte * true success 1200*fcf3ce44SJohn Forte * -1 incorrect section, or read error from cfg DB 1201*fcf3ce44SJohn Forte */ 1202*fcf3ce44SJohn Forte int 1203*fcf3ce44SJohn Forte cfg_put_options(CFGFILE *cfg, int section, const char *basekey, char *tag, 1204*fcf3ce44SJohn Forte char *val) 1205*fcf3ce44SJohn Forte { 1206*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 1207*fcf3ce44SJohn Forte char encode_buf[CFG_MAX_BUF]; 1208*fcf3ce44SJohn Forte char *p; 1209*fcf3ce44SJohn Forte int enclen; 1210*fcf3ce44SJohn Forte 1211*fcf3ce44SJohn Forte if (cfg == NULL) { 1212*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 1213*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 1214*fcf3ce44SJohn Forte return (-1); 1215*fcf3ce44SJohn Forte } 1216*fcf3ce44SJohn Forte 1217*fcf3ce44SJohn Forte errno = ENOSYS; 1218*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 1219*fcf3ce44SJohn Forte if (section != CFG_SEC_CONF) { 1220*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 1221*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 1222*fcf3ce44SJohn Forte return (-1); 1223*fcf3ce44SJohn Forte } 1224*fcf3ce44SJohn Forte if (!tag || !*tag || !val || !*val) 1225*fcf3ce44SJohn Forte return (-1); 1226*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, basekey, buf, CFG_MAX_BUF) < 0) { 1227*fcf3ce44SJohn Forte /* cfg severity & perror_str set up cfg_get_cstring() */ 1228*fcf3ce44SJohn Forte return (-1); 1229*fcf3ce44SJohn Forte } 1230*fcf3ce44SJohn Forte *encode_buf = ';'; 1231*fcf3ce44SJohn Forte enclen = cfg_encode_string(tag, &encode_buf[1], CFG_MAX_BUF - 1) + 1; 1232*fcf3ce44SJohn Forte if (enclen < 1 || (enclen + 1) >= CFG_MAX_BUF) { 1233*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 1234*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "Buffer too small"); 1235*fcf3ce44SJohn Forte return (-1); 1236*fcf3ce44SJohn Forte } 1237*fcf3ce44SJohn Forte encode_buf[enclen] = '='; 1238*fcf3ce44SJohn Forte encode_buf[enclen + 1] = '\0'; 1239*fcf3ce44SJohn Forte 1240*fcf3ce44SJohn Forte /* check the start of the string */ 1241*fcf3ce44SJohn Forte if (strncmp(buf, &encode_buf[1], enclen) == 0) { 1242*fcf3ce44SJohn Forte /* locate the end of this option */ 1243*fcf3ce44SJohn Forte p = strchr(buf, ';'); 1244*fcf3ce44SJohn Forte if (p && *(p + 1) != '\0') { 1245*fcf3ce44SJohn Forte /* add the new tag to the end */ 1246*fcf3ce44SJohn Forte ++p; 1247*fcf3ce44SJohn Forte strcat(p, &encode_buf[1]); 1248*fcf3ce44SJohn Forte } else { 1249*fcf3ce44SJohn Forte /* completely overwrite the existing tag */ 1250*fcf3ce44SJohn Forte p = buf; 1251*fcf3ce44SJohn Forte strcpy(p, &encode_buf[1]); 1252*fcf3ce44SJohn Forte } 1253*fcf3ce44SJohn Forte if (cfg_encode_string(val, encode_buf, CFG_MAX_BUF) < 0) { 1254*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 1255*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "Buffer too small"); 1256*fcf3ce44SJohn Forte return (-1); 1257*fcf3ce44SJohn Forte } 1258*fcf3ce44SJohn Forte strcat(p, encode_buf); 1259*fcf3ce44SJohn Forte strcat(p, ";"); 1260*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, basekey, p, strlen(p)) < 0) { 1261*fcf3ce44SJohn Forte /* severity & perror_str set by cfg_put_cstring */ 1262*fcf3ce44SJohn Forte return (-1); 1263*fcf3ce44SJohn Forte } 1264*fcf3ce44SJohn Forte errno = 0; 1265*fcf3ce44SJohn Forte return (TRUE); 1266*fcf3ce44SJohn Forte } 1267*fcf3ce44SJohn Forte 1268*fcf3ce44SJohn Forte /* it's hiding somewhere inside... */ 1269*fcf3ce44SJohn Forte p = strstr(buf, encode_buf); 1270*fcf3ce44SJohn Forte if (p) { 1271*fcf3ce44SJohn Forte /* delete the old value */ 1272*fcf3ce44SJohn Forte char *q = strchr(p + 1, ';'); 1273*fcf3ce44SJohn Forte if (q) { 1274*fcf3ce44SJohn Forte strcpy(p + 1, q + 1); 1275*fcf3ce44SJohn Forte } else { 1276*fcf3ce44SJohn Forte *p = '\0'; 1277*fcf3ce44SJohn Forte } 1278*fcf3ce44SJohn Forte strcat(buf, &encode_buf[1]); 1279*fcf3ce44SJohn Forte } else if (*buf) { 1280*fcf3ce44SJohn Forte strcat(buf, &encode_buf[1]); 1281*fcf3ce44SJohn Forte } else { 1282*fcf3ce44SJohn Forte strcpy(buf, &encode_buf[1]); 1283*fcf3ce44SJohn Forte } 1284*fcf3ce44SJohn Forte enclen = cfg_encode_string(val, encode_buf, CFG_MAX_BUF); 1285*fcf3ce44SJohn Forte if (enclen < 0 || (strlen(buf) + enclen) >= CFG_MAX_BUF) { 1286*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 1287*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "Buffer too small"); 1288*fcf3ce44SJohn Forte return (-1); 1289*fcf3ce44SJohn Forte } 1290*fcf3ce44SJohn Forte strcat(buf, encode_buf); 1291*fcf3ce44SJohn Forte strcat(buf, ";"); 1292*fcf3ce44SJohn Forte if (cfg_put_cstring(cfg, basekey, buf, CFG_MAX_BUF) < 0) { 1293*fcf3ce44SJohn Forte /* severity & perror_str set by cfg_put_cstring */ 1294*fcf3ce44SJohn Forte return (-1); 1295*fcf3ce44SJohn Forte } 1296*fcf3ce44SJohn Forte errno = 0; 1297*fcf3ce44SJohn Forte return (TRUE); 1298*fcf3ce44SJohn Forte } 1299*fcf3ce44SJohn Forte 1300*fcf3ce44SJohn Forte /* 1301*fcf3ce44SJohn Forte * cfg_get_single_option 1302*fcf3ce44SJohn Forte * 1303*fcf3ce44SJohn Forte * Scans the options string for the specified option and returns 1304*fcf3ce44SJohn Forte * the decoded value 1305*fcf3ce44SJohn Forte * 1306*fcf3ce44SJohn Forte * Return: 1307*fcf3ce44SJohn Forte * true success 1308*fcf3ce44SJohn Forte * -1 incorrect section, or read error from cfg DB 1309*fcf3ce44SJohn Forte */ 1310*fcf3ce44SJohn Forte int 1311*fcf3ce44SJohn Forte cfg_get_single_option(CFGFILE *cfg, int section, const char *basekey, char *tag, 1312*fcf3ce44SJohn Forte char *val, int val_len) 1313*fcf3ce44SJohn Forte { 1314*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 1315*fcf3ce44SJohn Forte char encode_buf[CFG_MAX_BUF]; 1316*fcf3ce44SJohn Forte char *p, *q; 1317*fcf3ce44SJohn Forte int enclen; 1318*fcf3ce44SJohn Forte 1319*fcf3ce44SJohn Forte if (cfg == NULL) { 1320*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 1321*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 1322*fcf3ce44SJohn Forte return (-1); 1323*fcf3ce44SJohn Forte } 1324*fcf3ce44SJohn Forte 1325*fcf3ce44SJohn Forte errno = ENOSYS; 1326*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 1327*fcf3ce44SJohn Forte if (section != CFG_SEC_CONF) { 1328*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 1329*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 1330*fcf3ce44SJohn Forte return (-1); 1331*fcf3ce44SJohn Forte } 1332*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, basekey, buf, CFG_MAX_BUF) < 0) { 1333*fcf3ce44SJohn Forte /* severity & perror_str set by cfg_get_cstring */ 1334*fcf3ce44SJohn Forte return (-1); 1335*fcf3ce44SJohn Forte } 1336*fcf3ce44SJohn Forte 1337*fcf3ce44SJohn Forte *encode_buf = ';'; 1338*fcf3ce44SJohn Forte enclen = cfg_encode_string(tag, &encode_buf[1], CFG_MAX_BUF - 1) + 1; 1339*fcf3ce44SJohn Forte if (enclen < 1 || (enclen + 1) >= CFG_MAX_BUF) { 1340*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 1341*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "Buffer too small"); 1342*fcf3ce44SJohn Forte return (-1); 1343*fcf3ce44SJohn Forte } 1344*fcf3ce44SJohn Forte encode_buf[enclen] = '='; 1345*fcf3ce44SJohn Forte encode_buf[enclen + 1] = '\0'; 1346*fcf3ce44SJohn Forte 1347*fcf3ce44SJohn Forte /* check the start of the string */ 1348*fcf3ce44SJohn Forte if (strncmp(buf, &encode_buf[1], enclen) == 0) { 1349*fcf3ce44SJohn Forte p = strchr(buf, '='); 1350*fcf3ce44SJohn Forte if (!p) { 1351*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 1352*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "Option not found"); 1353*fcf3ce44SJohn Forte return (-1); 1354*fcf3ce44SJohn Forte } 1355*fcf3ce44SJohn Forte ++p; 1356*fcf3ce44SJohn Forte q = strchr(p, ';'); 1357*fcf3ce44SJohn Forte if (q) { 1358*fcf3ce44SJohn Forte *q = '\0'; 1359*fcf3ce44SJohn Forte } 1360*fcf3ce44SJohn Forte cfg_decode_string(p, val, val_len); 1361*fcf3ce44SJohn Forte errno = 0; 1362*fcf3ce44SJohn Forte return (TRUE); 1363*fcf3ce44SJohn Forte } 1364*fcf3ce44SJohn Forte 1365*fcf3ce44SJohn Forte /* it's hiding somewhere inside... */ 1366*fcf3ce44SJohn Forte p = strstr(buf, encode_buf); 1367*fcf3ce44SJohn Forte if (p) { 1368*fcf3ce44SJohn Forte p += enclen + 1; 1369*fcf3ce44SJohn Forte q = strchr(p, ';'); 1370*fcf3ce44SJohn Forte if (q) { 1371*fcf3ce44SJohn Forte *q = '\0'; 1372*fcf3ce44SJohn Forte } 1373*fcf3ce44SJohn Forte cfg_decode_string(p, val, val_len); 1374*fcf3ce44SJohn Forte errno = 0; 1375*fcf3ce44SJohn Forte return (TRUE); 1376*fcf3ce44SJohn Forte } 1377*fcf3ce44SJohn Forte 1378*fcf3ce44SJohn Forte /* key not found */ 1379*fcf3ce44SJohn Forte return (-1); 1380*fcf3ce44SJohn Forte 1381*fcf3ce44SJohn Forte } 1382*fcf3ce44SJohn Forte 1383*fcf3ce44SJohn Forte /* 1384*fcf3ce44SJohn Forte * cfg_del_option 1385*fcf3ce44SJohn Forte * 1386*fcf3ce44SJohn Forte * Removes a single key=val pair from the specified option field 1387*fcf3ce44SJohn Forte * 1388*fcf3ce44SJohn Forte * Return: 1389*fcf3ce44SJohn Forte * true success 1390*fcf3ce44SJohn Forte * -1 unable to update config 1391*fcf3ce44SJohn Forte */ 1392*fcf3ce44SJohn Forte int 1393*fcf3ce44SJohn Forte cfg_del_option(CFGFILE *cfg, int section, const char *basekey, char *tag) 1394*fcf3ce44SJohn Forte { 1395*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 1396*fcf3ce44SJohn Forte char encode_buf[CFG_MAX_BUF]; 1397*fcf3ce44SJohn Forte char *p, *q; 1398*fcf3ce44SJohn Forte int enclen, rc; 1399*fcf3ce44SJohn Forte 1400*fcf3ce44SJohn Forte if (cfg == NULL) { 1401*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 1402*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 1403*fcf3ce44SJohn Forte return (-1); 1404*fcf3ce44SJohn Forte } 1405*fcf3ce44SJohn Forte 1406*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 1407*fcf3ce44SJohn Forte if (section != CFG_SEC_CONF) { 1408*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 1409*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 1410*fcf3ce44SJohn Forte return (-1); 1411*fcf3ce44SJohn Forte } 1412*fcf3ce44SJohn Forte if (cfg_get_cstring(cfg, basekey, buf, CFG_MAX_BUF) < 0) { 1413*fcf3ce44SJohn Forte /* severity & perror_str are set by cfg_get_cstring */ 1414*fcf3ce44SJohn Forte return (-1); 1415*fcf3ce44SJohn Forte } 1416*fcf3ce44SJohn Forte 1417*fcf3ce44SJohn Forte *encode_buf = ';'; 1418*fcf3ce44SJohn Forte enclen = cfg_encode_string(tag, &encode_buf[1], CFG_MAX_BUF - 1) + 1; 1419*fcf3ce44SJohn Forte if (enclen < 1 || (enclen + 1) >= CFG_MAX_BUF) { 1420*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 1421*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "Buffer too small"); 1422*fcf3ce44SJohn Forte return (-1); 1423*fcf3ce44SJohn Forte } 1424*fcf3ce44SJohn Forte encode_buf[enclen] = '='; 1425*fcf3ce44SJohn Forte encode_buf[enclen + 1] = '\0'; 1426*fcf3ce44SJohn Forte 1427*fcf3ce44SJohn Forte /* check the start of the string */ 1428*fcf3ce44SJohn Forte if (strncmp(buf, &encode_buf[1], enclen) == 0) { 1429*fcf3ce44SJohn Forte p = strchr(buf, ';'); 1430*fcf3ce44SJohn Forte if (p && (*(p + 1) != '\0')) { 1431*fcf3ce44SJohn Forte rc = cfg_put_cstring(cfg, basekey, p + 1, strlen(p + 1)); 1432*fcf3ce44SJohn Forte } else { 1433*fcf3ce44SJohn Forte rc = cfg_put_cstring(cfg, basekey, "-", 1); 1434*fcf3ce44SJohn Forte } 1435*fcf3ce44SJohn Forte /* severity & perror_str are set by cfg_put_cstring */ 1436*fcf3ce44SJohn Forte return (rc); 1437*fcf3ce44SJohn Forte } 1438*fcf3ce44SJohn Forte 1439*fcf3ce44SJohn Forte /* sigh */ 1440*fcf3ce44SJohn Forte p = strstr(buf, encode_buf); 1441*fcf3ce44SJohn Forte if (!p) { 1442*fcf3ce44SJohn Forte /* already removed */ 1443*fcf3ce44SJohn Forte return (TRUE); 1444*fcf3ce44SJohn Forte } 1445*fcf3ce44SJohn Forte q = strchr(p + 1, ';'); 1446*fcf3ce44SJohn Forte 1447*fcf3ce44SJohn Forte /* 1448*fcf3ce44SJohn Forte * Now the string looks like: 1449*fcf3ce44SJohn Forte * | first few options | *p | option to remove | *q | rest | '\0' 1450*fcf3ce44SJohn Forte */ 1451*fcf3ce44SJohn Forte 1452*fcf3ce44SJohn Forte if (!q) { 1453*fcf3ce44SJohn Forte /* hum... */ 1454*fcf3ce44SJohn Forte *p = '\0'; 1455*fcf3ce44SJohn Forte } else { 1456*fcf3ce44SJohn Forte strcpy(p, q); 1457*fcf3ce44SJohn Forte } 1458*fcf3ce44SJohn Forte 1459*fcf3ce44SJohn Forte return (cfg_put_cstring(cfg, basekey, buf, strlen(buf))); 1460*fcf3ce44SJohn Forte } 1461*fcf3ce44SJohn Forte 1462*fcf3ce44SJohn Forte static void 1463*fcf3ce44SJohn Forte cfg_set_memorymap(cfp_t *cfp) 1464*fcf3ce44SJohn Forte { 1465*fcf3ce44SJohn Forte cfgheader_t *hd = cfp->cf_head; 1466*fcf3ce44SJohn Forte 1467*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 1468*fcf3ce44SJohn Forte (void) fprintf(stderr, "callocing %d for initial reads\n", hd->h_csize); 1469*fcf3ce44SJohn Forte #endif 1470*fcf3ce44SJohn Forte 1471*fcf3ce44SJohn Forte hd->h_ccopy1 = (char *)calloc(hd->h_csize, sizeof (char)); 1472*fcf3ce44SJohn Forte hd->h_ccopy2 = (char *)calloc(hd->h_csize, sizeof (char)); 1473*fcf3ce44SJohn Forte hd->h_sizes1 = (int *)calloc(CFG_DEFAULT_PSIZE, sizeof (int)); 1474*fcf3ce44SJohn Forte hd->h_sizes2 = (int *)calloc(CFG_DEFAULT_PSIZE, sizeof (int)); 1475*fcf3ce44SJohn Forte } 1476*fcf3ce44SJohn Forte 1477*fcf3ce44SJohn Forte /* 1478*fcf3ce44SJohn Forte * cfg_init_header 1479*fcf3ce44SJohn Forte * fill in default header info 1480*fcf3ce44SJohn Forte */ 1481*fcf3ce44SJohn Forte static void 1482*fcf3ce44SJohn Forte cfg_init_header(cfp_t *cfp) 1483*fcf3ce44SJohn Forte { 1484*fcf3ce44SJohn Forte time_t tloc; 1485*fcf3ce44SJohn Forte cfgheader_t *hd = cfp->cf_head; 1486*fcf3ce44SJohn Forte 1487*fcf3ce44SJohn Forte hd->h_magic = (int32_t)CFG_NEW_MAGIC; 1488*fcf3ce44SJohn Forte hd->h_stamp = time(&tloc); 1489*fcf3ce44SJohn Forte hd->h_lock = 0; 1490*fcf3ce44SJohn Forte /* parser config */ 1491*fcf3ce44SJohn Forte hd->h_parsesize = 0; 1492*fcf3ce44SJohn Forte hd->h_parseoff = 0; 1493*fcf3ce44SJohn Forte hd->h_csize = 0; 1494*fcf3ce44SJohn Forte hd->h_psize = 0; 1495*fcf3ce44SJohn Forte hd->h_cfgs = NULL; 1496*fcf3ce44SJohn Forte hd->h_ncfgs = 0; 1497*fcf3ce44SJohn Forte hd->h_seq1 = hd->h_seq2 = 1; 1498*fcf3ce44SJohn Forte bzero(hd->h_cfgsizes, MAX_CFG * sizeof (int)); 1499*fcf3ce44SJohn Forte } 1500*fcf3ce44SJohn Forte /* 1501*fcf3ce44SJohn Forte * cfg_read 1502*fcf3ce44SJohn Forte * read header and all sections of configuration file 1503*fcf3ce44SJohn Forte * gets new data for incore copy 1504*fcf3ce44SJohn Forte * removes invalid header state 1505*fcf3ce44SJohn Forte * works even if config and persistent sections are empty 1506*fcf3ce44SJohn Forte * 1507*fcf3ce44SJohn Forte */ 1508*fcf3ce44SJohn Forte static int 1509*fcf3ce44SJohn Forte cfg_read(cfp_t *cfp) 1510*fcf3ce44SJohn Forte { 1511*fcf3ce44SJohn Forte int rc; 1512*fcf3ce44SJohn Forte cfgheader_t *hd; 1513*fcf3ce44SJohn Forte int readsize = 0; 1514*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 1515*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg_read\n"); 1516*fcf3ce44SJohn Forte #endif 1517*fcf3ce44SJohn Forte 1518*fcf3ce44SJohn Forte if (!cfp->cf_head) { 1519*fcf3ce44SJohn Forte if ((hd = calloc(1, sizeof (*hd))) == NULL) 1520*fcf3ce44SJohn Forte return (FALSE); 1521*fcf3ce44SJohn Forte #ifdef DEBUG_HDR 1522*fcf3ce44SJohn Forte (void) fprintf(stderr, "initial cfg header read\n"); 1523*fcf3ce44SJohn Forte #endif 1524*fcf3ce44SJohn Forte cfp->cf_head = hd; 1525*fcf3ce44SJohn Forte } 1526*fcf3ce44SJohn Forte 1527*fcf3ce44SJohn Forte if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) { 1528*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1529*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: seek header failed\n"); 1530*fcf3ce44SJohn Forte #endif 1531*fcf3ce44SJohn Forte return (FALSE); 1532*fcf3ce44SJohn Forte } 1533*fcf3ce44SJohn Forte 1534*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->read)(cfp, (char *)cfp->cf_head, 4); 1535*fcf3ce44SJohn Forte if (rc < 4) { 1536*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1537*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: read magic number failed\n"); 1538*fcf3ce44SJohn Forte #endif 1539*fcf3ce44SJohn Forte return (FALSE); 1540*fcf3ce44SJohn Forte } 1541*fcf3ce44SJohn Forte 1542*fcf3ce44SJohn Forte if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) { 1543*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1544*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: seek header failed\n"); 1545*fcf3ce44SJohn Forte #endif 1546*fcf3ce44SJohn Forte return (FALSE); 1547*fcf3ce44SJohn Forte } 1548*fcf3ce44SJohn Forte 1549*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->read)(cfp, (char *)cfp->cf_head, sizeof (*hd)); 1550*fcf3ce44SJohn Forte if (rc < sizeof (*hd)) { 1551*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1552*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: read header failed\n"); 1553*fcf3ce44SJohn Forte #endif 1554*fcf3ce44SJohn Forte return (FALSE); 1555*fcf3ce44SJohn Forte } 1556*fcf3ce44SJohn Forte 1557*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs = NULL; 1558*fcf3ce44SJohn Forte cfg_set_memorymap(cfp); 1559*fcf3ce44SJohn Forte if (cfp->cf_head->h_magic != CFG_NEW_MAGIC) { 1560*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1561*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg_read: wrong MAGIC number %x\n", 1562*fcf3ce44SJohn Forte cfp->cf_head->h_magic); 1563*fcf3ce44SJohn Forte #endif 1564*fcf3ce44SJohn Forte return (FALSE); 1565*fcf3ce44SJohn Forte } 1566*fcf3ce44SJohn Forte 1567*fcf3ce44SJohn Forte cfp->cf_head->h_state &= ~(CFG_HDR_INVALID); 1568*fcf3ce44SJohn Forte 1569*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 1570*fcf3ce44SJohn Forte (void) fprintf(stderr, "reading parser\n"); 1571*fcf3ce44SJohn Forte #endif 1572*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->read) 1573*fcf3ce44SJohn Forte (cfp, (char *)cfp->cf_mapped, CFG_DEFAULT_PARSE_SIZE); 1574*fcf3ce44SJohn Forte if (rc < sizeof (*hd)) { 1575*fcf3ce44SJohn Forte #ifdef DEBUG 1576*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: read parse config failed\n"); 1577*fcf3ce44SJohn Forte #endif 1578*fcf3ce44SJohn Forte return (FALSE); 1579*fcf3ce44SJohn Forte } 1580*fcf3ce44SJohn Forte 1581*fcf3ce44SJohn Forte readsize = cfp->cf_head->h_csize; 1582*fcf3ce44SJohn Forte 1583*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 1584*fcf3ce44SJohn Forte (void) fprintf(stderr, "reading copy1 readsize = %d\n", readsize); 1585*fcf3ce44SJohn Forte #endif 1586*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->read) 1587*fcf3ce44SJohn Forte (cfp, (char *)cfp->cf_head->h_ccopy1, readsize); 1588*fcf3ce44SJohn Forte if (rc < 0) { 1589*fcf3ce44SJohn Forte /* don't fail just return */ 1590*fcf3ce44SJohn Forte #ifdef DEBUG 1591*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: read ccopy1 section failed\n"); 1592*fcf3ce44SJohn Forte #endif 1593*fcf3ce44SJohn Forte return (FALSE); 1594*fcf3ce44SJohn Forte } 1595*fcf3ce44SJohn Forte 1596*fcf3ce44SJohn Forte if ((*cfp->cf_pp->seek) 1597*fcf3ce44SJohn Forte (cfp, CFG_DEFAULT_SSIZE - rc, SEEK_CUR) < 0) { 1598*fcf3ce44SJohn Forte #ifdef DEBUG 1599*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: seek (SEEK_CUR) failed\n"); 1600*fcf3ce44SJohn Forte #endif 1601*fcf3ce44SJohn Forte return (FALSE); 1602*fcf3ce44SJohn Forte } 1603*fcf3ce44SJohn Forte 1604*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 1605*fcf3ce44SJohn Forte (void) fprintf(stderr, "reading copy2 readsize = %d\n", readsize); 1606*fcf3ce44SJohn Forte #endif 1607*fcf3ce44SJohn Forte 1608*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->read) 1609*fcf3ce44SJohn Forte (cfp, (char *)cfp->cf_head->h_ccopy2, readsize); 1610*fcf3ce44SJohn Forte if (rc < 0) { 1611*fcf3ce44SJohn Forte /* don't fail just return */ 1612*fcf3ce44SJohn Forte #ifdef DEBUG 1613*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: read ccopy2 section failed\n"); 1614*fcf3ce44SJohn Forte #endif 1615*fcf3ce44SJohn Forte return (FALSE); 1616*fcf3ce44SJohn Forte } 1617*fcf3ce44SJohn Forte 1618*fcf3ce44SJohn Forte /* read the sizes of the lists from disk */ 1619*fcf3ce44SJohn Forte if ((*cfp->cf_pp->seek) 1620*fcf3ce44SJohn Forte (cfp, CFG_DEFAULT_SSIZE - rc, SEEK_CUR) < 0) { 1621*fcf3ce44SJohn Forte #ifdef DEBUG 1622*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: seek (SEEK_CUR) failed\n"); 1623*fcf3ce44SJohn Forte #endif 1624*fcf3ce44SJohn Forte return (FALSE); 1625*fcf3ce44SJohn Forte } 1626*fcf3ce44SJohn Forte 1627*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 1628*fcf3ce44SJohn Forte (void) fprintf(stderr, "reading sizes\n"); 1629*fcf3ce44SJohn Forte #endif 1630*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->read) 1631*fcf3ce44SJohn Forte (cfp, (int *)cfp->cf_head->h_sizes1, CFG_DEFAULT_PSIZE); 1632*fcf3ce44SJohn Forte if (rc < 0) { 1633*fcf3ce44SJohn Forte #ifdef DEBUG 1634*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: read h_sizes1 failed\n"); 1635*fcf3ce44SJohn Forte #endif 1636*fcf3ce44SJohn Forte return (FALSE); 1637*fcf3ce44SJohn Forte } 1638*fcf3ce44SJohn Forte 1639*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->read) 1640*fcf3ce44SJohn Forte (cfp, (int *)cfp->cf_head->h_sizes2, CFG_DEFAULT_PSIZE); 1641*fcf3ce44SJohn Forte if (rc < 0) { 1642*fcf3ce44SJohn Forte #ifdef DEBUG 1643*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: read h_sizes2 failed\n"); 1644*fcf3ce44SJohn Forte #endif 1645*fcf3ce44SJohn Forte return (FALSE); 1646*fcf3ce44SJohn Forte } 1647*fcf3ce44SJohn Forte 1648*fcf3ce44SJohn Forte /* 1649*fcf3ce44SJohn Forte * If initial or invalid sequence, use first section 1650*fcf3ce44SJohn Forte */ 1651*fcf3ce44SJohn Forte if ((cfp->cf_head->h_seq1 <= 0) && (cfp->cf_head->h_seq2 <= 0)) { 1652*fcf3ce44SJohn Forte cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy1; 1653*fcf3ce44SJohn Forte cfp->cf_head->h_sizes = cfp->cf_head->h_sizes1; 1654*fcf3ce44SJohn Forte } 1655*fcf3ce44SJohn Forte 1656*fcf3ce44SJohn Forte if (cfp->cf_head->h_seq1 >= cfp->cf_head->h_seq2) { 1657*fcf3ce44SJohn Forte cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy1; 1658*fcf3ce44SJohn Forte cfp->cf_head->h_sizes = cfp->cf_head->h_sizes1; 1659*fcf3ce44SJohn Forte } else { 1660*fcf3ce44SJohn Forte cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy2; 1661*fcf3ce44SJohn Forte cfp->cf_head->h_sizes = cfp->cf_head->h_sizes2; 1662*fcf3ce44SJohn Forte } 1663*fcf3ce44SJohn Forte 1664*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1665*fcf3ce44SJohn Forte dump_status(cfp, "cfg_read"); 1666*fcf3ce44SJohn Forte #endif 1667*fcf3ce44SJohn Forte 1668*fcf3ce44SJohn Forte return (TRUE); 1669*fcf3ce44SJohn Forte } 1670*fcf3ce44SJohn Forte 1671*fcf3ce44SJohn Forte /* 1672*fcf3ce44SJohn Forte * cfg_lock 1673*fcf3ce44SJohn Forte * Read-write locking of the configuration 1674*fcf3ce44SJohn Forte * reads into core all sections 1675*fcf3ce44SJohn Forte * builds parser trees for each section 1676*fcf3ce44SJohn Forte * Returns: TRUE if the lock was acquired, FALSE otherwise. 1677*fcf3ce44SJohn Forte */ 1678*fcf3ce44SJohn Forte int 1679*fcf3ce44SJohn Forte cfg_lock(CFGFILE *cfg, CFGLOCK mode) 1680*fcf3ce44SJohn Forte { 1681*fcf3ce44SJohn Forte cfp_t *cfp; 1682*fcf3ce44SJohn Forte int is_locked = 0; 1683*fcf3ce44SJohn Forte int rc; 1684*fcf3ce44SJohn Forte 1685*fcf3ce44SJohn Forte if (cfg == NULL) { 1686*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 1687*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 1688*fcf3ce44SJohn Forte return (FALSE); 1689*fcf3ce44SJohn Forte } 1690*fcf3ce44SJohn Forte 1691*fcf3ce44SJohn Forte if (mode == CFG_UPGRADE) { 1692*fcf3ce44SJohn Forte mode = CFG_WRLOCK; 1693*fcf3ce44SJohn Forte } 1694*fcf3ce44SJohn Forte 1695*fcf3ce44SJohn Forte if (mode == CFG_WRLOCK && (cfg->cf[0].cf_flag & CFG_RDONLY)) { 1696*fcf3ce44SJohn Forte goto fail; 1697*fcf3ce44SJohn Forte } 1698*fcf3ce44SJohn Forte 1699*fcf3ce44SJohn Forte /* 1700*fcf3ce44SJohn Forte * if you don't even give me the right lock request, 1701*fcf3ce44SJohn Forte * why should I give you one? 1702*fcf3ce44SJohn Forte */ 1703*fcf3ce44SJohn Forte if (mode != CFG_RDLOCK && mode != CFG_WRLOCK) 1704*fcf3ce44SJohn Forte goto fail; 1705*fcf3ce44SJohn Forte 1706*fcf3ce44SJohn Forte if (cfg_lockd) { 1707*fcf3ce44SJohn Forte if (mode == CFG_WRLOCK) 1708*fcf3ce44SJohn Forte cfg_lockd_wrlock(); 1709*fcf3ce44SJohn Forte else 1710*fcf3ce44SJohn Forte cfg_lockd_rdlock(); 1711*fcf3ce44SJohn Forte is_locked = 1; 1712*fcf3ce44SJohn Forte } else { 1713*fcf3ce44SJohn Forte 1714*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 1715*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg_lock\n"); 1716*fcf3ce44SJohn Forte #endif 1717*fcf3ce44SJohn Forte /* Lock is always based on local file pointer */ 1718*fcf3ce44SJohn Forte cfg->cf[1].cf_lock = cfg->cf[0].cf_lock = cfg->cf[0].cf_fd; 1719*fcf3ce44SJohn Forte 1720*fcf3ce44SJohn Forte if (!((cfg->cf[0].cf_flag & CFG_RDONLY) && 1721*fcf3ce44SJohn Forte (mode == CFG_RDLOCK))) { 1722*fcf3ce44SJohn Forte 1723*fcf3ce44SJohn Forte struct flock lk = {0}; 1724*fcf3ce44SJohn Forte lk.l_type = (mode == CFG_RDLOCK ? F_RDLCK : F_WRLCK); 1725*fcf3ce44SJohn Forte lk.l_whence = SEEK_SET; 1726*fcf3ce44SJohn Forte lk.l_start = (off_t)0; 1727*fcf3ce44SJohn Forte lk.l_len = (off_t)0; 1728*fcf3ce44SJohn Forte 1729*fcf3ce44SJohn Forte if (fcntl(cfg->cf[0].cf_lock, F_SETLKW, &lk) < 0) 1730*fcf3ce44SJohn Forte goto fail; 1731*fcf3ce44SJohn Forte } 1732*fcf3ce44SJohn Forte } 1733*fcf3ce44SJohn Forte 1734*fcf3ce44SJohn Forte /* Determine number of files open */ 1735*fcf3ce44SJohn Forte for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) { 1736*fcf3ce44SJohn Forte if (!cfp->cf_fd) continue; 1737*fcf3ce44SJohn Forte if ((cfp->cf_head) && 1738*fcf3ce44SJohn Forte (cfp->cf_head->h_state & CFG_HDR_INVALID)) { 1739*fcf3ce44SJohn Forte if ((rc = cfg_hdrcmp(cfp)) == 0) { 1740*fcf3ce44SJohn Forte #ifdef DEBUG_HDR 1741*fcf3ce44SJohn Forte (void) fprintf(stderr, 1742*fcf3ce44SJohn Forte "cfg header match, skipping re-read\n"); 1743*fcf3ce44SJohn Forte #endif 1744*fcf3ce44SJohn Forte cfp->cf_head->h_state |= CFG_HDR_RDLOCK; 1745*fcf3ce44SJohn Forte if (mode == CFG_WRLOCK) 1746*fcf3ce44SJohn Forte cfp->cf_head->h_state |= CFG_HDR_WRLOCK; 1747*fcf3ce44SJohn Forte 1748*fcf3ce44SJohn Forte cfp->cf_head->h_state &= ~(CFG_HDR_INVALID); 1749*fcf3ce44SJohn Forte continue; 1750*fcf3ce44SJohn Forte } 1751*fcf3ce44SJohn Forte #ifdef DEBUG_HDR 1752*fcf3ce44SJohn Forte (void) fprintf(stderr, "re-reading cfg, header mismatch\n"); 1753*fcf3ce44SJohn Forte #endif 1754*fcf3ce44SJohn Forte /* 1755*fcf3ce44SJohn Forte * dump what we have, info is stale 1756*fcf3ce44SJohn Forte */ 1757*fcf3ce44SJohn Forte cfg_free_cfglist(cfp); 1758*fcf3ce44SJohn Forte cfg_free_parser_tree(); 1759*fcf3ce44SJohn Forte 1760*fcf3ce44SJohn Forte if (cfp->cf_head->h_ccopy1) { 1761*fcf3ce44SJohn Forte free(cfp->cf_head->h_ccopy1); 1762*fcf3ce44SJohn Forte cfp->cf_head->h_ccopy1 = NULL; 1763*fcf3ce44SJohn Forte } 1764*fcf3ce44SJohn Forte if (cfp->cf_head->h_ccopy2) { 1765*fcf3ce44SJohn Forte free(cfp->cf_head->h_ccopy2); 1766*fcf3ce44SJohn Forte cfp->cf_head->h_ccopy2 = NULL; 1767*fcf3ce44SJohn Forte } 1768*fcf3ce44SJohn Forte if (cfp->cf_head->h_sizes1) { 1769*fcf3ce44SJohn Forte free(cfp->cf_head->h_sizes1); 1770*fcf3ce44SJohn Forte cfp->cf_head->h_sizes1 = NULL; 1771*fcf3ce44SJohn Forte } 1772*fcf3ce44SJohn Forte if (cfp->cf_head->h_sizes2) { 1773*fcf3ce44SJohn Forte free(cfp->cf_head->h_sizes2); 1774*fcf3ce44SJohn Forte cfp->cf_head->h_sizes2 = NULL; 1775*fcf3ce44SJohn Forte } 1776*fcf3ce44SJohn Forte 1777*fcf3ce44SJohn Forte if (cfp->cf_head) 1778*fcf3ce44SJohn Forte free(cfp->cf_head); 1779*fcf3ce44SJohn Forte cfp->cf_head = NULL; 1780*fcf3ce44SJohn Forte } 1781*fcf3ce44SJohn Forte 1782*fcf3ce44SJohn Forte if (cfp->cf_head == NULL) { 1783*fcf3ce44SJohn Forte if (!cfg_read(cfp)) { 1784*fcf3ce44SJohn Forte if (cfp->cf_head != NULL) 1785*fcf3ce44SJohn Forte cfg_init_header(cfp); 1786*fcf3ce44SJohn Forte else 1787*fcf3ce44SJohn Forte goto fail; 1788*fcf3ce44SJohn Forte } else { 1789*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 1790*fcf3ce44SJohn Forte (void) fprintf(stderr, 1791*fcf3ce44SJohn Forte "reading parser config\n"); 1792*fcf3ce44SJohn Forte #endif 1793*fcf3ce44SJohn Forte /* build parser trees */ 1794*fcf3ce44SJohn Forte cfg_read_parser_config(cfp); 1795*fcf3ce44SJohn Forte } 1796*fcf3ce44SJohn Forte 1797*fcf3ce44SJohn Forte } 1798*fcf3ce44SJohn Forte cfp->cf_head->h_state |= CFG_HDR_RDLOCK; 1799*fcf3ce44SJohn Forte if (mode == CFG_WRLOCK) { 1800*fcf3ce44SJohn Forte if (cfp->cf_head->h_seq1 >= cfp->cf_head->h_seq2) { 1801*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1802*fcf3ce44SJohn Forte (void) fprintf(stderr, 1803*fcf3ce44SJohn Forte "cfg_lock: WRLOCK copying 1 to 2\n"); 1804*fcf3ce44SJohn Forte #endif 1805*fcf3ce44SJohn Forte memcpy(cfp->cf_head->h_ccopy2, 1806*fcf3ce44SJohn Forte cfp->cf_head->h_ccopy1, 1807*fcf3ce44SJohn Forte cfp->cf_head->h_csize); 1808*fcf3ce44SJohn Forte memcpy(cfp->cf_head->h_sizes2, 1809*fcf3ce44SJohn Forte cfp->cf_head->h_sizes1, 1810*fcf3ce44SJohn Forte CFG_DEFAULT_PSIZE); 1811*fcf3ce44SJohn Forte 1812*fcf3ce44SJohn Forte cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy2; 1813*fcf3ce44SJohn Forte cfp->cf_head->h_sizes = cfp->cf_head->h_sizes2; 1814*fcf3ce44SJohn Forte } else { 1815*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1816*fcf3ce44SJohn Forte (void) fprintf(stderr, 1817*fcf3ce44SJohn Forte "cfg_lock: WRLOCK copying 2 to 1\n"); 1818*fcf3ce44SJohn Forte #endif 1819*fcf3ce44SJohn Forte memcpy(cfp->cf_head->h_ccopy1, 1820*fcf3ce44SJohn Forte cfp->cf_head->h_ccopy2, 1821*fcf3ce44SJohn Forte cfp->cf_head->h_csize); 1822*fcf3ce44SJohn Forte memcpy(cfp->cf_head->h_sizes1, 1823*fcf3ce44SJohn Forte cfp->cf_head->h_sizes2, 1824*fcf3ce44SJohn Forte CFG_DEFAULT_PSIZE); 1825*fcf3ce44SJohn Forte 1826*fcf3ce44SJohn Forte cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy1; 1827*fcf3ce44SJohn Forte cfp->cf_head->h_sizes = cfp->cf_head->h_sizes1; 1828*fcf3ce44SJohn Forte } 1829*fcf3ce44SJohn Forte 1830*fcf3ce44SJohn Forte cfp->cf_head->h_state |= CFG_HDR_WRLOCK; 1831*fcf3ce44SJohn Forte } 1832*fcf3ce44SJohn Forte 1833*fcf3ce44SJohn Forte if (cfg_map_cfglists(cfp) < 0) { 1834*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1835*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: map_cfglists failed\n"); 1836*fcf3ce44SJohn Forte #endif 1837*fcf3ce44SJohn Forte goto fail; 1838*fcf3ce44SJohn Forte } 1839*fcf3ce44SJohn Forte 1840*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1841*fcf3ce44SJohn Forte dump_status(cfp, "cfg_lock"); 1842*fcf3ce44SJohn Forte #endif 1843*fcf3ce44SJohn Forte } 1844*fcf3ce44SJohn Forte 1845*fcf3ce44SJohn Forte return (TRUE); 1846*fcf3ce44SJohn Forte 1847*fcf3ce44SJohn Forte fail: 1848*fcf3ce44SJohn Forte if (is_locked) { 1849*fcf3ce44SJohn Forte cfg_lockd_unlock(); 1850*fcf3ce44SJohn Forte } 1851*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EGENERIC); 1852*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 1853*fcf3ce44SJohn Forte return (FALSE); 1854*fcf3ce44SJohn Forte } 1855*fcf3ce44SJohn Forte 1856*fcf3ce44SJohn Forte /* 1857*fcf3ce44SJohn Forte * Unlock the database 1858*fcf3ce44SJohn Forte */ 1859*fcf3ce44SJohn Forte void 1860*fcf3ce44SJohn Forte cfp_unlock(cfp_t *cfp) 1861*fcf3ce44SJohn Forte { 1862*fcf3ce44SJohn Forte 1863*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 1864*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg_unlock\n"); 1865*fcf3ce44SJohn Forte #endif 1866*fcf3ce44SJohn Forte if (cfg_lockd) { 1867*fcf3ce44SJohn Forte cfg_lockd_unlock(); 1868*fcf3ce44SJohn Forte } else { 1869*fcf3ce44SJohn Forte struct flock lk = {0}; 1870*fcf3ce44SJohn Forte lk.l_type = F_UNLCK; 1871*fcf3ce44SJohn Forte lk.l_whence = SEEK_SET; 1872*fcf3ce44SJohn Forte lk.l_start = (off_t)0; 1873*fcf3ce44SJohn Forte lk.l_len = (off_t)0; 1874*fcf3ce44SJohn Forte (void) fcntl(cfp->cf_lock, F_SETLKW, &lk); 1875*fcf3ce44SJohn Forte } 1876*fcf3ce44SJohn Forte 1877*fcf3ce44SJohn Forte if (cfp->cf_head != NULL) { 1878*fcf3ce44SJohn Forte cfp->cf_head->h_state &= ~(CFG_HDR_RDLOCK|CFG_HDR_WRLOCK); 1879*fcf3ce44SJohn Forte cfp->cf_head->h_state |= CFG_HDR_INVALID; 1880*fcf3ce44SJohn Forte } 1881*fcf3ce44SJohn Forte } 1882*fcf3ce44SJohn Forte void 1883*fcf3ce44SJohn Forte cfg_unlock(CFGFILE *cfg) 1884*fcf3ce44SJohn Forte { 1885*fcf3ce44SJohn Forte if (cfg == NULL) { 1886*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 1887*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 1888*fcf3ce44SJohn Forte return; 1889*fcf3ce44SJohn Forte } 1890*fcf3ce44SJohn Forte 1891*fcf3ce44SJohn Forte cfp_unlock(&cfg->cf[0]); 1892*fcf3ce44SJohn Forte cfp_unlock(&cfg->cf[1]); 1893*fcf3ce44SJohn Forte } 1894*fcf3ce44SJohn Forte 1895*fcf3ce44SJohn Forte /* 1896*fcf3ce44SJohn Forte * Test for a read lock, set errno if failed. 1897*fcf3ce44SJohn Forte */ 1898*fcf3ce44SJohn Forte static int 1899*fcf3ce44SJohn Forte cfg_rdlock(CFGFILE *cfg) 1900*fcf3ce44SJohn Forte { 1901*fcf3ce44SJohn Forte int rc; 1902*fcf3ce44SJohn Forte cfp_t *cfp; 1903*fcf3ce44SJohn Forte 1904*fcf3ce44SJohn Forte if (cfg == NULL) { 1905*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 1906*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 1907*fcf3ce44SJohn Forte return (FALSE); 1908*fcf3ce44SJohn Forte } 1909*fcf3ce44SJohn Forte 1910*fcf3ce44SJohn Forte /* Determine number of files open */ 1911*fcf3ce44SJohn Forte for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) { 1912*fcf3ce44SJohn Forte if (!cfp->cf_fd) continue; 1913*fcf3ce44SJohn Forte if (cfp->cf_head == NULL) { 1914*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1915*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg_rdlock: cf_head == NULL\n"); 1916*fcf3ce44SJohn Forte #endif 1917*fcf3ce44SJohn Forte /* 1918*fcf3ce44SJohn Forte * 6335583, if header == NULL, 1919*fcf3ce44SJohn Forte * we can't call cfg_read to fill the header again 1920*fcf3ce44SJohn Forte * since it will change the lock state to 1921*fcf3ce44SJohn Forte * CFG_HDR_WRLOCK and dscfg will be the processer 1922*fcf3ce44SJohn Forte * that hold the lock, 1923*fcf3ce44SJohn Forte * just returning a FALSE if the case, 1924*fcf3ce44SJohn Forte * then retrieve the lock state from flock structure. 1925*fcf3ce44SJohn Forte */ 1926*fcf3ce44SJohn Forte rc = FALSE; 1927*fcf3ce44SJohn Forte break; 1928*fcf3ce44SJohn Forte } else { 1929*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1930*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg_rdlock: cf_head != NULL\n"); 1931*fcf3ce44SJohn Forte #endif 1932*fcf3ce44SJohn Forte if ((cfp->cf_head->h_state & CFG_HDR_RDLOCK) 1933*fcf3ce44SJohn Forte == CFG_HDR_RDLOCK) 1934*fcf3ce44SJohn Forte rc = TRUE; 1935*fcf3ce44SJohn Forte else { 1936*fcf3ce44SJohn Forte rc = FALSE; 1937*fcf3ce44SJohn Forte break; 1938*fcf3ce44SJohn Forte } 1939*fcf3ce44SJohn Forte } 1940*fcf3ce44SJohn Forte } 1941*fcf3ce44SJohn Forte 1942*fcf3ce44SJohn Forte if (!rc) 1943*fcf3ce44SJohn Forte errno = EPERM; 1944*fcf3ce44SJohn Forte 1945*fcf3ce44SJohn Forte return (rc); 1946*fcf3ce44SJohn Forte } 1947*fcf3ce44SJohn Forte 1948*fcf3ce44SJohn Forte /* 1949*fcf3ce44SJohn Forte * Test for a write lock, set errno if failed. 1950*fcf3ce44SJohn Forte */ 1951*fcf3ce44SJohn Forte static int 1952*fcf3ce44SJohn Forte cfg_wrlock(CFGFILE *cfg) 1953*fcf3ce44SJohn Forte { 1954*fcf3ce44SJohn Forte int rc; 1955*fcf3ce44SJohn Forte cfp_t *cfp; 1956*fcf3ce44SJohn Forte 1957*fcf3ce44SJohn Forte if (cfg == NULL) { 1958*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 1959*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 1960*fcf3ce44SJohn Forte return (FALSE); 1961*fcf3ce44SJohn Forte } 1962*fcf3ce44SJohn Forte 1963*fcf3ce44SJohn Forte /* Determine number of files open */ 1964*fcf3ce44SJohn Forte for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) { 1965*fcf3ce44SJohn Forte if (!cfp->cf_fd) continue; 1966*fcf3ce44SJohn Forte if (cfp->cf_head == NULL) { 1967*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1968*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg wrlock: cf_head == NULL\n"); 1969*fcf3ce44SJohn Forte #endif 1970*fcf3ce44SJohn Forte /* 1971*fcf3ce44SJohn Forte * 6335583, see comments on cfg_rdlock 1972*fcf3ce44SJohn Forte */ 1973*fcf3ce44SJohn Forte rc = FALSE; 1974*fcf3ce44SJohn Forte break; 1975*fcf3ce44SJohn Forte } else { 1976*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 1977*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg wrlock: cf_head != NULL\n"); 1978*fcf3ce44SJohn Forte #endif 1979*fcf3ce44SJohn Forte if ((cfp->cf_head->h_state & CFG_HDR_WRLOCK) 1980*fcf3ce44SJohn Forte == CFG_HDR_WRLOCK) 1981*fcf3ce44SJohn Forte rc = TRUE; 1982*fcf3ce44SJohn Forte else { 1983*fcf3ce44SJohn Forte rc = FALSE; 1984*fcf3ce44SJohn Forte break; 1985*fcf3ce44SJohn Forte } 1986*fcf3ce44SJohn Forte } 1987*fcf3ce44SJohn Forte } 1988*fcf3ce44SJohn Forte 1989*fcf3ce44SJohn Forte if (!rc) 1990*fcf3ce44SJohn Forte errno = EPERM; 1991*fcf3ce44SJohn Forte 1992*fcf3ce44SJohn Forte return (rc); 1993*fcf3ce44SJohn Forte } 1994*fcf3ce44SJohn Forte 1995*fcf3ce44SJohn Forte /* 1996*fcf3ce44SJohn Forte * cfg_get_lock 1997*fcf3ce44SJohn Forte * Find lock status of CFG database. 1998*fcf3ce44SJohn Forte * Returns: TRUE and sets lock and pid if the lock is held, FALSE otherwise. 1999*fcf3ce44SJohn Forte */ 2000*fcf3ce44SJohn Forte int 2001*fcf3ce44SJohn Forte cfg_get_lock(CFGFILE *cfg, CFGLOCK *lock, pid_t *pid) 2002*fcf3ce44SJohn Forte { 2003*fcf3ce44SJohn Forte struct flock lk; 2004*fcf3ce44SJohn Forte int rc; 2005*fcf3ce44SJohn Forte 2006*fcf3ce44SJohn Forte if (cfg == NULL) { 2007*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 2008*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2009*fcf3ce44SJohn Forte return (FALSE); 2010*fcf3ce44SJohn Forte } 2011*fcf3ce44SJohn Forte 2012*fcf3ce44SJohn Forte if (cfg_lockd) { 2013*fcf3ce44SJohn Forte switch (cfg_lockedby(pid)) { 2014*fcf3ce44SJohn Forte case LOCK_READ: 2015*fcf3ce44SJohn Forte *lock = CFG_RDLOCK; 2016*fcf3ce44SJohn Forte return (TRUE); 2017*fcf3ce44SJohn Forte case LOCK_WRITE: 2018*fcf3ce44SJohn Forte *lock = CFG_WRLOCK; 2019*fcf3ce44SJohn Forte return (TRUE); 2020*fcf3ce44SJohn Forte case LOCK_NOTLOCKED: 2021*fcf3ce44SJohn Forte default: 2022*fcf3ce44SJohn Forte return (FALSE); 2023*fcf3ce44SJohn Forte } 2024*fcf3ce44SJohn Forte } else { 2025*fcf3ce44SJohn Forte if (cfg_wrlock(cfg)) { 2026*fcf3ce44SJohn Forte *lock = CFG_WRLOCK; 2027*fcf3ce44SJohn Forte *pid = getpid(); 2028*fcf3ce44SJohn Forte return (TRUE); 2029*fcf3ce44SJohn Forte } 2030*fcf3ce44SJohn Forte 2031*fcf3ce44SJohn Forte if (cfg_rdlock(cfg)) { 2032*fcf3ce44SJohn Forte *lock = CFG_RDLOCK; 2033*fcf3ce44SJohn Forte *pid = getpid(); 2034*fcf3ce44SJohn Forte return (TRUE); 2035*fcf3ce44SJohn Forte } 2036*fcf3ce44SJohn Forte } 2037*fcf3ce44SJohn Forte /* Lock is always based on local file pointer */ 2038*fcf3ce44SJohn Forte cfg->cf[1].cf_lock = cfg->cf[0].cf_lock = cfg->cf[0].cf_fd; 2039*fcf3ce44SJohn Forte 2040*fcf3ce44SJohn Forte bzero(&lk, sizeof (lk)); 2041*fcf3ce44SJohn Forte lk.l_type = F_WRLCK; 2042*fcf3ce44SJohn Forte lk.l_whence = SEEK_SET; 2043*fcf3ce44SJohn Forte lk.l_start = (off_t)0; 2044*fcf3ce44SJohn Forte lk.l_len = (off_t)0; 2045*fcf3ce44SJohn Forte 2046*fcf3ce44SJohn Forte if (fcntl(cfg->cf[0].cf_lock, F_GETLK, &lk) < 0) 2047*fcf3ce44SJohn Forte rc = FALSE; 2048*fcf3ce44SJohn Forte else { 2049*fcf3ce44SJohn Forte if (lk.l_type == F_UNLCK) 2050*fcf3ce44SJohn Forte rc = FALSE; 2051*fcf3ce44SJohn Forte else { 2052*fcf3ce44SJohn Forte rc = TRUE; 2053*fcf3ce44SJohn Forte *pid = lk.l_pid; 2054*fcf3ce44SJohn Forte *lock = lk.l_type == F_WRLCK ? CFG_WRLOCK : CFG_RDLOCK; 2055*fcf3ce44SJohn Forte } 2056*fcf3ce44SJohn Forte } 2057*fcf3ce44SJohn Forte 2058*fcf3ce44SJohn Forte return (rc); 2059*fcf3ce44SJohn Forte } 2060*fcf3ce44SJohn Forte 2061*fcf3ce44SJohn Forte /* 2062*fcf3ce44SJohn Forte * cfg_commit 2063*fcf3ce44SJohn Forte * Write modified version of header, configuration and persistent 2064*fcf3ce44SJohn Forte * data using 2 stage commit. 2065*fcf3ce44SJohn Forte * If no valid data is found in header, it is assumed to be an initial 2066*fcf3ce44SJohn Forte * write and we will create the default header (could be dangerous) 2067*fcf3ce44SJohn Forte * another tricky part, if we are doing an upgrade we may be dealing 2068*fcf3ce44SJohn Forte * with an old database. we need to take care seeking and writing 2069*fcf3ce44SJohn Forte * until such time that it is upgraded. 2070*fcf3ce44SJohn Forte * 2071*fcf3ce44SJohn Forte * Mutual exclusion is checked using cfg_lock 2072*fcf3ce44SJohn Forte */ 2073*fcf3ce44SJohn Forte 2074*fcf3ce44SJohn Forte int 2075*fcf3ce44SJohn Forte cfg_commit(CFGFILE *cfg) 2076*fcf3ce44SJohn Forte { 2077*fcf3ce44SJohn Forte cfp_t *cfp; 2078*fcf3ce44SJohn Forte int rc; 2079*fcf3ce44SJohn Forte time_t tloc; 2080*fcf3ce44SJohn Forte int section; 2081*fcf3ce44SJohn Forte int wrsize, *ip; 2082*fcf3ce44SJohn Forte 2083*fcf3ce44SJohn Forte if (cfg == NULL) { 2084*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 2085*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2086*fcf3ce44SJohn Forte return (FALSE); 2087*fcf3ce44SJohn Forte } 2088*fcf3ce44SJohn Forte 2089*fcf3ce44SJohn Forte if (!cfg_wrlock(cfg)) 2090*fcf3ce44SJohn Forte return (FALSE); 2091*fcf3ce44SJohn Forte 2092*fcf3ce44SJohn Forte /* Determine number of files open */ 2093*fcf3ce44SJohn Forte for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) { 2094*fcf3ce44SJohn Forte if (!cfp->cf_fd) continue; 2095*fcf3ce44SJohn Forte 2096*fcf3ce44SJohn Forte /* 2097*fcf3ce44SJohn Forte * lets put everything back into one char * 2098*fcf3ce44SJohn Forte */ 2099*fcf3ce44SJohn Forte cfg_replace_lists(cfp); 2100*fcf3ce44SJohn Forte 2101*fcf3ce44SJohn Forte if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) { 2102*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 2103*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: seek header failed\n"); 2104*fcf3ce44SJohn Forte #endif 2105*fcf3ce44SJohn Forte return (FALSE); 2106*fcf3ce44SJohn Forte } 2107*fcf3ce44SJohn Forte 2108*fcf3ce44SJohn Forte cfp->cf_head->h_size = cfp->cf_head->h_parsesize 2109*fcf3ce44SJohn Forte + cfp->cf_head->h_csize + cfp->cf_head->h_psize; 2110*fcf3ce44SJohn Forte cfp->cf_head->h_stamp = time(&tloc); 2111*fcf3ce44SJohn Forte 2112*fcf3ce44SJohn Forte /* seeking into database */ 2113*fcf3ce44SJohn Forte if ((*cfp->cf_pp->seek) 2114*fcf3ce44SJohn Forte (cfp, sizeof (cfgheader_t), SEEK_CUR) < 0) 2115*fcf3ce44SJohn Forte return (FALSE); 2116*fcf3ce44SJohn Forte 2117*fcf3ce44SJohn Forte if (cfp->cf_head->h_ccopy1 == cfp->cf_head->h_cparse) { 2118*fcf3ce44SJohn Forte if (cfp->cf_head->h_seq1 < 0) 2119*fcf3ce44SJohn Forte cfp->cf_head->h_seq1 = 1; 2120*fcf3ce44SJohn Forte else 2121*fcf3ce44SJohn Forte cfp->cf_head->h_seq1 = cfp->cf_head->h_seq2 + 1; 2122*fcf3ce44SJohn Forte section = 1; 2123*fcf3ce44SJohn Forte } else { 2124*fcf3ce44SJohn Forte if (cfp->cf_head->h_seq2 < 0) 2125*fcf3ce44SJohn Forte cfp->cf_head->h_seq2 = 1; 2126*fcf3ce44SJohn Forte else 2127*fcf3ce44SJohn Forte cfp->cf_head->h_seq2 = cfp->cf_head->h_seq1 + 1; 2128*fcf3ce44SJohn Forte section = 2; 2129*fcf3ce44SJohn Forte } 2130*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 2131*fcf3ce44SJohn Forte dump_status(cfp, "cfg_commit"); 2132*fcf3ce44SJohn Forte #endif 2133*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->write) 2134*fcf3ce44SJohn Forte (cfp, cfp->cf_mapped, CFG_DEFAULT_PARSE_SIZE); 2135*fcf3ce44SJohn Forte #ifdef DEBUG 2136*fcf3ce44SJohn Forte if (rc < 0) { 2137*fcf3ce44SJohn Forte (void) fprintf(stderr, 2138*fcf3ce44SJohn Forte "parse commit: rc %d h_parsesize %d\n", 2139*fcf3ce44SJohn Forte rc, cfp->cf_head->h_parsesize); 2140*fcf3ce44SJohn Forte } 2141*fcf3ce44SJohn Forte #endif 2142*fcf3ce44SJohn Forte if (section == 1) { 2143*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->write) 2144*fcf3ce44SJohn Forte (cfp, cfp->cf_head->h_ccopy1, 2145*fcf3ce44SJohn Forte cfp->cf_head->h_csize); 2146*fcf3ce44SJohn Forte #ifdef DEBUG 2147*fcf3ce44SJohn Forte if (rc < 0) { 2148*fcf3ce44SJohn Forte (void) fprintf(stderr, 2149*fcf3ce44SJohn Forte "csection commit 1: rc %d h_csize %d\n", 2150*fcf3ce44SJohn Forte rc, cfp->cf_head->h_csize); 2151*fcf3ce44SJohn Forte } 2152*fcf3ce44SJohn Forte #endif 2153*fcf3ce44SJohn Forte if ((*cfp->cf_pp->seek) 2154*fcf3ce44SJohn Forte (cfp, (2 * CFG_DEFAULT_SSIZE) - rc, SEEK_CUR) < 0) 2155*fcf3ce44SJohn Forte return (FALSE); 2156*fcf3ce44SJohn Forte 2157*fcf3ce44SJohn Forte /* 2158*fcf3ce44SJohn Forte * limit the write to only what we need 2159*fcf3ce44SJohn Forte */ 2160*fcf3ce44SJohn Forte ip = cfp->cf_head->h_sizes1; 2161*fcf3ce44SJohn Forte for (wrsize = 0; *ip; ip += *ip + 1) 2162*fcf3ce44SJohn Forte wrsize += *ip + 1; 2163*fcf3ce44SJohn Forte 2164*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->write)(cfp, 2165*fcf3ce44SJohn Forte cfp->cf_head->h_sizes1, wrsize * sizeof (int)); 2166*fcf3ce44SJohn Forte #ifdef DEBUG 2167*fcf3ce44SJohn Forte if (rc < 0) { 2168*fcf3ce44SJohn Forte (void) fprintf(stderr, 2169*fcf3ce44SJohn Forte "cfg: write list sizes1 failed rc\n"); 2170*fcf3ce44SJohn Forte } 2171*fcf3ce44SJohn Forte #endif 2172*fcf3ce44SJohn Forte } else { 2173*fcf3ce44SJohn Forte if ((*cfp->cf_pp->seek)(cfp, 2174*fcf3ce44SJohn Forte CFG_DEFAULT_SSIZE, SEEK_CUR) < 0) 2175*fcf3ce44SJohn Forte return (FALSE); 2176*fcf3ce44SJohn Forte 2177*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->write)(cfp, 2178*fcf3ce44SJohn Forte cfp->cf_head->h_ccopy2, cfp->cf_head->h_csize); 2179*fcf3ce44SJohn Forte #ifdef DEBUG 2180*fcf3ce44SJohn Forte if (rc < 0) { 2181*fcf3ce44SJohn Forte (void) fprintf(stderr, 2182*fcf3ce44SJohn Forte "csection commit 2: rc %d h_csize %d\n", 2183*fcf3ce44SJohn Forte rc, cfp->cf_head->h_csize); 2184*fcf3ce44SJohn Forte } 2185*fcf3ce44SJohn Forte #endif 2186*fcf3ce44SJohn Forte if ((*cfp->cf_pp->seek) 2187*fcf3ce44SJohn Forte (cfp, (CFG_DEFAULT_SSIZE + CFG_DEFAULT_PSIZE) - rc, 2188*fcf3ce44SJohn Forte SEEK_CUR) < 0) 2189*fcf3ce44SJohn Forte return (FALSE); 2190*fcf3ce44SJohn Forte 2191*fcf3ce44SJohn Forte /* 2192*fcf3ce44SJohn Forte * limit the write to only what we need 2193*fcf3ce44SJohn Forte */ 2194*fcf3ce44SJohn Forte ip = cfp->cf_head->h_sizes2; 2195*fcf3ce44SJohn Forte for (wrsize = 0; *ip; ip += *ip + 1) 2196*fcf3ce44SJohn Forte wrsize += *ip + 1; 2197*fcf3ce44SJohn Forte 2198*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->write)(cfp, cfp->cf_head->h_sizes2, 2199*fcf3ce44SJohn Forte wrsize * sizeof (int)); 2200*fcf3ce44SJohn Forte #ifdef DEBUG 2201*fcf3ce44SJohn Forte if (rc < 0) { 2202*fcf3ce44SJohn Forte (void) fprintf(stderr, 2203*fcf3ce44SJohn Forte "cfg: write list sizes2 failed\n"); 2204*fcf3ce44SJohn Forte } 2205*fcf3ce44SJohn Forte #endif 2206*fcf3ce44SJohn Forte 2207*fcf3ce44SJohn Forte } 2208*fcf3ce44SJohn Forte 2209*fcf3ce44SJohn Forte 2210*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 2211*fcf3ce44SJohn Forte (void) fprintf(stderr, 2212*fcf3ce44SJohn Forte "writing h_csize %d\n", cfp->cf_head->h_csize); 2213*fcf3ce44SJohn Forte #endif 2214*fcf3ce44SJohn Forte if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) 2215*fcf3ce44SJohn Forte return (FALSE); 2216*fcf3ce44SJohn Forte 2217*fcf3ce44SJohn Forte cfp->cf_head->h_size = cfp->cf_head->h_parsesize + 2218*fcf3ce44SJohn Forte cfp->cf_head->h_csize + cfp->cf_head->h_psize; 2219*fcf3ce44SJohn Forte 2220*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->write) 2221*fcf3ce44SJohn Forte (cfp, cfp->cf_head, sizeof (cfgheader_t)); 2222*fcf3ce44SJohn Forte if (rc < 0) { 2223*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 2224*fcf3ce44SJohn Forte "cfg_commit: header write failed"); 2225*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2226*fcf3ce44SJohn Forte return (FALSE); 2227*fcf3ce44SJohn Forte } 2228*fcf3ce44SJohn Forte } 2229*fcf3ce44SJohn Forte 2230*fcf3ce44SJohn Forte return (TRUE); 2231*fcf3ce44SJohn Forte } 2232*fcf3ce44SJohn Forte 2233*fcf3ce44SJohn Forte /* 2234*fcf3ce44SJohn Forte * cfg_rewind 2235*fcf3ce44SJohn Forte * rewind internal file pointer for specified section 2236*fcf3ce44SJohn Forte * empty now, rewind not necessary. But don't break 2237*fcf3ce44SJohn Forte * old code. 2238*fcf3ce44SJohn Forte */ 2239*fcf3ce44SJohn Forte /*ARGSUSED*/ 2240*fcf3ce44SJohn Forte void 2241*fcf3ce44SJohn Forte cfg_rewind(CFGFILE *cfg, int section) 2242*fcf3ce44SJohn Forte { 2243*fcf3ce44SJohn Forte switch (section) { 2244*fcf3ce44SJohn Forte case CFG_SEC_CONF: 2245*fcf3ce44SJohn Forte break; 2246*fcf3ce44SJohn Forte case CFG_SEC_ALL: 2247*fcf3ce44SJohn Forte break; 2248*fcf3ce44SJohn Forte }; 2249*fcf3ce44SJohn Forte } 2250*fcf3ce44SJohn Forte 2251*fcf3ce44SJohn Forte /* 2252*fcf3ce44SJohn Forte * cfg_location 2253*fcf3ce44SJohn Forte * set or return the default location file to 2254*fcf3ce44SJohn Forte * determine the partition name of the configuration partition 2255*fcf3ce44SJohn Forte * location is stored in well known file location 2256*fcf3ce44SJohn Forte */ 2257*fcf3ce44SJohn Forte char * 2258*fcf3ce44SJohn Forte cfg_location(char *location, int mode, char *altroot) 2259*fcf3ce44SJohn Forte { 2260*fcf3ce44SJohn Forte int fd; 2261*fcf3ce44SJohn Forte int fmode; 2262*fcf3ce44SJohn Forte int rc; 2263*fcf3ce44SJohn Forte char wellknown[NSC_MAXPATH]; 2264*fcf3ce44SJohn Forte char loc[NSC_MAXPATH]; 2265*fcf3ce44SJohn Forte 2266*fcf3ce44SJohn Forte if (mode == CFG_LOC_GET_LOCAL) { 2267*fcf3ce44SJohn Forte return (CFG_LOCAL_LOCATION); 2268*fcf3ce44SJohn Forte } else if (mode == CFG_LOC_GET_CLUSTER) { 2269*fcf3ce44SJohn Forte fmode = O_RDONLY; 2270*fcf3ce44SJohn Forte } else { 2271*fcf3ce44SJohn Forte fmode = O_RDWR | O_CREAT; 2272*fcf3ce44SJohn Forte } 2273*fcf3ce44SJohn Forte 2274*fcf3ce44SJohn Forte if (altroot) { 2275*fcf3ce44SJohn Forte strcpy(wellknown, altroot); 2276*fcf3ce44SJohn Forte strcat(wellknown, CFG_CLUSTER_LOCATION); 2277*fcf3ce44SJohn Forte } else 2278*fcf3ce44SJohn Forte strcpy(wellknown, CFG_CLUSTER_LOCATION); 2279*fcf3ce44SJohn Forte 2280*fcf3ce44SJohn Forte fd = open(wellknown, fmode, 0644); 2281*fcf3ce44SJohn Forte if (fd < 0) { 2282*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", strerror(errno)); 2283*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 2284*fcf3ce44SJohn Forte return (NULL); 2285*fcf3ce44SJohn Forte } 2286*fcf3ce44SJohn Forte 2287*fcf3ce44SJohn Forte if (mode == CFG_LOC_SET_CLUSTER) { 2288*fcf3ce44SJohn Forte if (location == NULL || (strlen(location) > NSC_MAXPATH)) { 2289*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 2290*fcf3ce44SJohn Forte "cfg_location: filename too big or missing"); 2291*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2292*fcf3ce44SJohn Forte return (NULL); 2293*fcf3ce44SJohn Forte } 2294*fcf3ce44SJohn Forte 2295*fcf3ce44SJohn Forte /* 2296*fcf3ce44SJohn Forte * 5082142 2297*fcf3ce44SJohn Forte * If we're in a cluster, make sure that the config location 2298*fcf3ce44SJohn Forte * is a raw device. Using non-raw did devices in a cluster 2299*fcf3ce44SJohn Forte * can result in data corruption, since inconsistent data 2300*fcf3ce44SJohn Forte * may reside in the block cache on one node, but has not 2301*fcf3ce44SJohn Forte * been flushed to disk. 2302*fcf3ce44SJohn Forte */ 2303*fcf3ce44SJohn Forte if (cfg_iscluster() > 0) { 2304*fcf3ce44SJohn Forte struct stat dscfg_stat; 2305*fcf3ce44SJohn Forte if (stat(location, &dscfg_stat) != 0) { 2306*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 2307*fcf3ce44SJohn Forte "Unable to access dscfg location"); 2308*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2309*fcf3ce44SJohn Forte return (NULL); 2310*fcf3ce44SJohn Forte } 2311*fcf3ce44SJohn Forte if (!S_ISCHR(dscfg_stat.st_mode)) { 2312*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 2313*fcf3ce44SJohn Forte "dscfg location must be a raw device"); 2314*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2315*fcf3ce44SJohn Forte return (NULL); 2316*fcf3ce44SJohn Forte } 2317*fcf3ce44SJohn Forte } 2318*fcf3ce44SJohn Forte 2319*fcf3ce44SJohn Forte if (ftruncate(fd, 0) < 0) 2320*fcf3ce44SJohn Forte return (NULL); 2321*fcf3ce44SJohn Forte 2322*fcf3ce44SJohn Forte rc = write(fd, location, strlen(location)); 2323*fcf3ce44SJohn Forte if (rc < 0) { 2324*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 2325*fcf3ce44SJohn Forte "cfg_location: write to well known failed"); 2326*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2327*fcf3ce44SJohn Forte return (NULL); 2328*fcf3ce44SJohn Forte } 2329*fcf3ce44SJohn Forte bzero(config_file, sizeof (config_file)); 2330*fcf3ce44SJohn Forte } 2331*fcf3ce44SJohn Forte if (lseek(fd, 0, SEEK_SET) < 0) 2332*fcf3ce44SJohn Forte return (NULL); 2333*fcf3ce44SJohn Forte 2334*fcf3ce44SJohn Forte bzero(config_file, sizeof (config_file)); 2335*fcf3ce44SJohn Forte rc = read(fd, config_file, sizeof (config_file)); 2336*fcf3ce44SJohn Forte if (rc < 0) { 2337*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 2338*fcf3ce44SJohn Forte "cfg_location: read from well known failed"); 2339*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2340*fcf3ce44SJohn Forte return (NULL); 2341*fcf3ce44SJohn Forte } 2342*fcf3ce44SJohn Forte close(fd); 2343*fcf3ce44SJohn Forte if (altroot) { 2344*fcf3ce44SJohn Forte strcpy(loc, altroot); 2345*fcf3ce44SJohn Forte strcat(loc, config_file); 2346*fcf3ce44SJohn Forte bzero(config_file, sizeof (config_file)); 2347*fcf3ce44SJohn Forte strcpy(config_file, loc); 2348*fcf3ce44SJohn Forte } 2349*fcf3ce44SJohn Forte 2350*fcf3ce44SJohn Forte /* 2351*fcf3ce44SJohn Forte * scan string out of config_file, to strip whitespace 2352*fcf3ce44SJohn Forte */ 2353*fcf3ce44SJohn Forte sscanf(config_file, "%s", loc); 2354*fcf3ce44SJohn Forte strcpy(config_file, loc); 2355*fcf3ce44SJohn Forte 2356*fcf3ce44SJohn Forte return (config_file); 2357*fcf3ce44SJohn Forte } 2358*fcf3ce44SJohn Forte 2359*fcf3ce44SJohn Forte /* 2360*fcf3ce44SJohn Forte * cfg_update_parser_config 2361*fcf3ce44SJohn Forte * If tag and key exist return -1 2362*fcf3ce44SJohn Forte * 2363*fcf3ce44SJohn Forte * XXX Currently does not append new field to existing parser rule 2364*fcf3ce44SJohn Forte */ 2365*fcf3ce44SJohn Forte 2366*fcf3ce44SJohn Forte int 2367*fcf3ce44SJohn Forte cfg_update_parser_config(CFGFILE *cfg, const char *key, int section) 2368*fcf3ce44SJohn Forte { 2369*fcf3ce44SJohn Forte cfp_t *cfp; 2370*fcf3ce44SJohn Forte int size; 2371*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 2372*fcf3ce44SJohn Forte struct parser *tbl; 2373*fcf3ce44SJohn Forte char tmpkey[CFG_MAX_KEY]; 2374*fcf3ce44SJohn Forte char *ky, *fld; 2375*fcf3ce44SJohn Forte errno = 0; 2376*fcf3ce44SJohn Forte 2377*fcf3ce44SJohn Forte if (cfg == NULL) { 2378*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 2379*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2380*fcf3ce44SJohn Forte return (-1); 2381*fcf3ce44SJohn Forte } 2382*fcf3ce44SJohn Forte 2383*fcf3ce44SJohn Forte cfp = FP_SUN_CLUSTER(cfg); 2384*fcf3ce44SJohn Forte if (!cfg_wrlock(cfg)) 2385*fcf3ce44SJohn Forte return (-1); 2386*fcf3ce44SJohn Forte 2387*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 2388*fcf3ce44SJohn Forte bzero(tmpkey, sizeof (tmpkey)); 2389*fcf3ce44SJohn Forte strcpy(tmpkey, key); 2390*fcf3ce44SJohn Forte if (section == CFG_PARSE_CONF) { 2391*fcf3ce44SJohn Forte strcat(buf, "C:"); 2392*fcf3ce44SJohn Forte tbl = chead; 2393*fcf3ce44SJohn Forte } else { 2394*fcf3ce44SJohn Forte errno = EINVAL; 2395*fcf3ce44SJohn Forte return (-1); 2396*fcf3ce44SJohn Forte } 2397*fcf3ce44SJohn Forte ky = strtok(tmpkey, "."); 2398*fcf3ce44SJohn Forte fld = strtok(NULL, "."); 2399*fcf3ce44SJohn Forte while (fld) { 2400*fcf3ce44SJohn Forte size = cfg_get_item(tbl, ky, fld); 2401*fcf3ce44SJohn Forte 2402*fcf3ce44SJohn Forte /* 2403*fcf3ce44SJohn Forte * Assure we are loading a clean table, with do duplicates 2404*fcf3ce44SJohn Forte * based on our File Descriptor 2405*fcf3ce44SJohn Forte */ 2406*fcf3ce44SJohn Forte if (chead_loaded && (chead_loaded != cfp->cf_fd)) { 2407*fcf3ce44SJohn Forte if (size <= 0) 2408*fcf3ce44SJohn Forte return (-1); 2409*fcf3ce44SJohn Forte } else { 2410*fcf3ce44SJohn Forte if (size > 0) 2411*fcf3ce44SJohn Forte return (-1); 2412*fcf3ce44SJohn Forte } 2413*fcf3ce44SJohn Forte fld = strtok(NULL, "."); 2414*fcf3ce44SJohn Forte } 2415*fcf3ce44SJohn Forte size = strlen(key) + 2; 2416*fcf3ce44SJohn Forte strncat(buf, key, size); 2417*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 2418*fcf3ce44SJohn Forte (void) fprintf(stderr, "update parser config %s size %d\n", buf, size); 2419*fcf3ce44SJohn Forte #endif 2420*fcf3ce44SJohn Forte if ((size + cfp->cf_head->h_parseoff) > CFG_DEFAULT_PARSE_SIZE) { 2421*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 2422*fcf3ce44SJohn Forte "cfg_update_parser_config: header overrun"); 2423*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2424*fcf3ce44SJohn Forte #ifdef DEBUG_LIB 2425*fcf3ce44SJohn Forte (void) fprintf(stderr, "update parser config: " 2426*fcf3ce44SJohn Forte "overrun siz %d poff %d parsesize %d\n", 2427*fcf3ce44SJohn Forte size, cfp->cf_head->h_parseoff, cfp->cf_head->h_parsesize); 2428*fcf3ce44SJohn Forte #endif 2429*fcf3ce44SJohn Forte errno = E2BIG; 2430*fcf3ce44SJohn Forte return (-1); 2431*fcf3ce44SJohn Forte } 2432*fcf3ce44SJohn Forte bcopy(buf, (cfp->cf_mapped + cfp->cf_head->h_parseoff), size); 2433*fcf3ce44SJohn Forte cfp->cf_head->h_parseoff += size; 2434*fcf3ce44SJohn Forte cfp->cf_head->h_state |= CFG_HDR_INVALID; 2435*fcf3ce44SJohn Forte if (cfp->cf_mapped[cfp->cf_head->h_parseoff - 1] != '\n') { 2436*fcf3ce44SJohn Forte cfp->cf_mapped[cfp->cf_head->h_parseoff] = '\n'; 2437*fcf3ce44SJohn Forte cfp->cf_head->h_parseoff++; 2438*fcf3ce44SJohn Forte } 2439*fcf3ce44SJohn Forte cfp->cf_head->h_parsesize = cfp->cf_head->h_parseoff; 2440*fcf3ce44SJohn Forte cfg_read_parser_config(cfp); 2441*fcf3ce44SJohn Forte return (TRUE); 2442*fcf3ce44SJohn Forte } 2443*fcf3ce44SJohn Forte /* 2444*fcf3ce44SJohn Forte * cfg_read_parser_config 2445*fcf3ce44SJohn Forte * reads parser config from file 2446*fcf3ce44SJohn Forte * converts it to internal tree for parsing 2447*fcf3ce44SJohn Forte * chead for configuration parser entries 2448*fcf3ce44SJohn Forte * 2449*fcf3ce44SJohn Forte */ 2450*fcf3ce44SJohn Forte static 2451*fcf3ce44SJohn Forte void 2452*fcf3ce44SJohn Forte cfg_read_parser_config(cfp_t *cfp) 2453*fcf3ce44SJohn Forte { 2454*fcf3ce44SJohn Forte struct lookup *p, *q; 2455*fcf3ce44SJohn Forte struct parser *thead; 2456*fcf3ce44SJohn Forte int off, foff; 2457*fcf3ce44SJohn Forte char *part; 2458*fcf3ce44SJohn Forte char *key; 2459*fcf3ce44SJohn Forte char *fld; 2460*fcf3ce44SJohn Forte int fldnum; 2461*fcf3ce44SJohn Forte char c; 2462*fcf3ce44SJohn Forte char buf[CFG_MAX_BUF]; 2463*fcf3ce44SJohn Forte int i = 0; 2464*fcf3ce44SJohn Forte int n = 0; 2465*fcf3ce44SJohn Forte 2466*fcf3ce44SJohn Forte off = foff = 0; 2467*fcf3ce44SJohn Forte /*CONSTCOND*/ 2468*fcf3ce44SJohn Forte while (TRUE) { 2469*fcf3ce44SJohn Forte off = 0; 2470*fcf3ce44SJohn Forte bzero(buf, CFG_MAX_BUF); 2471*fcf3ce44SJohn Forte /* LINTED it assigns value to c */ 2472*fcf3ce44SJohn Forte while (c = cfp->cf_mapped[foff++]) { 2473*fcf3ce44SJohn Forte if (c == '\n') 2474*fcf3ce44SJohn Forte break; 2475*fcf3ce44SJohn Forte buf[off++] = c; 2476*fcf3ce44SJohn Forte } 2477*fcf3ce44SJohn Forte part = strtok(buf, ":"); 2478*fcf3ce44SJohn Forte if (!part) 2479*fcf3ce44SJohn Forte break; 2480*fcf3ce44SJohn Forte if (*part == 'C') { 2481*fcf3ce44SJohn Forte thead = chead; 2482*fcf3ce44SJohn Forte n = i; 2483*fcf3ce44SJohn Forte } 2484*fcf3ce44SJohn Forte key = strtok(NULL, "."); 2485*fcf3ce44SJohn Forte if (!key) 2486*fcf3ce44SJohn Forte break; 2487*fcf3ce44SJohn Forte strcpy(thead[n].tag.l_word, key); 2488*fcf3ce44SJohn Forte thead[n].tag.l_value = 0; 2489*fcf3ce44SJohn Forte thead[n].fld = NULL; 2490*fcf3ce44SJohn Forte fldnum = 1; 2491*fcf3ce44SJohn Forte while ((fld = strtok(NULL, ".")) != NULL) { 2492*fcf3ce44SJohn Forte p = thead[n].fld; 2493*fcf3ce44SJohn Forte if (p == NULL) { 2494*fcf3ce44SJohn Forte q = thead[n].fld = calloc(1, 2495*fcf3ce44SJohn Forte sizeof (struct lookup)); 2496*fcf3ce44SJohn Forte } else { 2497*fcf3ce44SJohn Forte for (q = thead[n].fld; q; q = q->l_next) 2498*fcf3ce44SJohn Forte p = q; 2499*fcf3ce44SJohn Forte q = calloc(1, sizeof (struct lookup)); 2500*fcf3ce44SJohn Forte p->l_next = q; 2501*fcf3ce44SJohn Forte } 2502*fcf3ce44SJohn Forte strcpy(q->l_word, fld); 2503*fcf3ce44SJohn Forte q->l_value = fldnum; 2504*fcf3ce44SJohn Forte q->l_next = NULL; 2505*fcf3ce44SJohn Forte #ifdef DEBUG_EXTRA 2506*fcf3ce44SJohn Forte (void) fprintf(stderr, 2507*fcf3ce44SJohn Forte "read parser: q: word %s value %d\n", 2508*fcf3ce44SJohn Forte q->l_word, q->l_value); 2509*fcf3ce44SJohn Forte #endif 2510*fcf3ce44SJohn Forte fldnum++; 2511*fcf3ce44SJohn Forte } 2512*fcf3ce44SJohn Forte if (*part == 'C') 2513*fcf3ce44SJohn Forte i++; 2514*fcf3ce44SJohn Forte } 2515*fcf3ce44SJohn Forte 2516*fcf3ce44SJohn Forte /* All done, indicate parser table is loaded */ 2517*fcf3ce44SJohn Forte if (i && (chead_loaded == 0)) 2518*fcf3ce44SJohn Forte chead_loaded = cfp->cf_fd; 2519*fcf3ce44SJohn Forte 2520*fcf3ce44SJohn Forte /* 2521*fcf3ce44SJohn Forte * before I go and alloc, why am I here? 2522*fcf3ce44SJohn Forte * do I need a bunch of cfglists, or do I just 2523*fcf3ce44SJohn Forte * need to accommodate a just added parser entry 2524*fcf3ce44SJohn Forte * if the latter, we already have a base, just set 2525*fcf3ce44SJohn Forte * i to the index of the cfg which members need allocing 2526*fcf3ce44SJohn Forte */ 2527*fcf3ce44SJohn Forte if ((cfp->cf_head->h_cfgs == NULL) || 2528*fcf3ce44SJohn Forte (cfp->cf_head->h_cfgs[n-1].l_entry == NULL)) { 2529*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs = (cfglist_t *)calloc(MAX_CFG, 2530*fcf3ce44SJohn Forte sizeof (cfglist_t)); 2531*fcf3ce44SJohn Forte i = 0; 2532*fcf3ce44SJohn Forte } 2533*fcf3ce44SJohn Forte else 2534*fcf3ce44SJohn Forte i = n; 2535*fcf3ce44SJohn Forte 2536*fcf3ce44SJohn Forte if (cfp->cf_head->h_cfgs) { 2537*fcf3ce44SJohn Forte 2538*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 2539*fcf3ce44SJohn Forte (void) fprintf(stderr, "alloced %d cfg lists \n", n + 1); 2540*fcf3ce44SJohn Forte #endif 2541*fcf3ce44SJohn Forte for (cfp->cf_head->h_ncfgs = n + 1; 2542*fcf3ce44SJohn Forte i < min(cfp->cf_head->h_ncfgs, MAX_CFG); i++) { 2543*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[i].l_name = '\0'; 2544*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[i].l_name = 2545*fcf3ce44SJohn Forte strdup(chead[i].tag.l_word); 2546*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[i].l_index = i; 2547*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[i].l_entry = 2548*fcf3ce44SJohn Forte calloc(DEFAULT_ENTRY_SIZE, sizeof (char)); 2549*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[i].l_nentry = 0; 2550*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[i].l_esiz = 2551*fcf3ce44SJohn Forte calloc(DEFAULT_NENTRIES, sizeof (int)); 2552*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[i].l_size = 0; 2553*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[i].l_free = DEFAULT_ENTRY_SIZE; 2554*fcf3ce44SJohn Forte if ((cfp->cf_head->h_cfgs[i].l_entry == NULL) || 2555*fcf3ce44SJohn Forte (cfp->cf_head->h_cfgs[i].l_esiz == NULL)) { 2556*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "unable to" 2557*fcf3ce44SJohn Forte " allocate cfglist members"); 2558*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2559*fcf3ce44SJohn Forte } 2560*fcf3ce44SJohn Forte } 2561*fcf3ce44SJohn Forte } else { 2562*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "unable to alloc cfglist"); 2563*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2564*fcf3ce44SJohn Forte } 2565*fcf3ce44SJohn Forte } 2566*fcf3ce44SJohn Forte 2567*fcf3ce44SJohn Forte /* 2568*fcf3ce44SJohn Forte * cfg_map_cfglists() 2569*fcf3ce44SJohn Forte * go through list of list sizes in header 2570*fcf3ce44SJohn Forte * and create separate lists 2571*fcf3ce44SJohn Forte */ 2572*fcf3ce44SJohn Forte int 2573*fcf3ce44SJohn Forte cfg_map_cfglists(cfp_t *cfp) 2574*fcf3ce44SJohn Forte { 2575*fcf3ce44SJohn Forte int i; 2576*fcf3ce44SJohn Forte int offset = 0; 2577*fcf3ce44SJohn Forte int *ip; 2578*fcf3ce44SJohn Forte int list_size = 0; 2579*fcf3ce44SJohn Forte int slot_inc; 2580*fcf3ce44SJohn Forte char *p; 2581*fcf3ce44SJohn Forte cfgheader_t *ch; 2582*fcf3ce44SJohn Forte 2583*fcf3ce44SJohn Forte ch = cfp->cf_head; 2584*fcf3ce44SJohn Forte p = ch->h_cparse; 2585*fcf3ce44SJohn Forte 2586*fcf3ce44SJohn Forte /* get the first list size */ 2587*fcf3ce44SJohn Forte ip = ch->h_sizes; 2588*fcf3ce44SJohn Forte 2589*fcf3ce44SJohn Forte for (i = 0; i < min(ch->h_ncfgs, MAX_CFG); i++) { 2590*fcf3ce44SJohn Forte if (ch->h_cfgsizes[i] > 0) { 2591*fcf3ce44SJohn Forte if (ch->h_cfgsizes[i] > DEFAULT_ENTRY_SIZE) { 2592*fcf3ce44SJohn Forte 2593*fcf3ce44SJohn Forte ch->h_cfgs[i].l_entry = (char *) 2594*fcf3ce44SJohn Forte realloc(ch->h_cfgs[i].l_entry, 2595*fcf3ce44SJohn Forte ch->h_cfgsizes[i] * sizeof (char)); 2596*fcf3ce44SJohn Forte /* set free to 0, we'll get more when we add */ 2597*fcf3ce44SJohn Forte ch->h_cfgs[i].l_free = 0; 2598*fcf3ce44SJohn Forte 2599*fcf3ce44SJohn Forte } else 2600*fcf3ce44SJohn Forte ch->h_cfgs[i].l_free -= ch->h_cfgsizes[i]; 2601*fcf3ce44SJohn Forte 2602*fcf3ce44SJohn Forte /* get lists and marry up to each cfgs structure */ 2603*fcf3ce44SJohn Forte 2604*fcf3ce44SJohn Forte 2605*fcf3ce44SJohn Forte list_size = *ip; 2606*fcf3ce44SJohn Forte ip++; 2607*fcf3ce44SJohn Forte 2608*fcf3ce44SJohn Forte if (list_size > DEFAULT_NENTRIES) { 2609*fcf3ce44SJohn Forte /* 2610*fcf3ce44SJohn Forte * we're gonna need more slots 2611*fcf3ce44SJohn Forte * we want to alloc on DEFAULT_NENTRIES 2612*fcf3ce44SJohn Forte * boundry. ie. always a multiple of it 2613*fcf3ce44SJohn Forte * later on, when we add to the list 2614*fcf3ce44SJohn Forte * we can see if we need to add by mod'ding 2615*fcf3ce44SJohn Forte * l_nentry and DEFAULT_NENTRIES and check for 0 2616*fcf3ce44SJohn Forte */ 2617*fcf3ce44SJohn Forte slot_inc = DEFAULT_NENTRIES - 2618*fcf3ce44SJohn Forte (list_size % DEFAULT_NENTRIES); 2619*fcf3ce44SJohn Forte if (slot_inc == DEFAULT_NENTRIES) 2620*fcf3ce44SJohn Forte slot_inc = 0; /* addcfline reallocs */ 2621*fcf3ce44SJohn Forte 2622*fcf3ce44SJohn Forte ch->h_cfgs[i].l_esiz = (int *)realloc( 2623*fcf3ce44SJohn Forte ch->h_cfgs[i].l_esiz, 2624*fcf3ce44SJohn Forte (list_size + slot_inc) * sizeof (int)); 2625*fcf3ce44SJohn Forte } 2626*fcf3ce44SJohn Forte memcpy(ch->h_cfgs[i].l_esiz, ip, 2627*fcf3ce44SJohn Forte list_size * sizeof (int)); 2628*fcf3ce44SJohn Forte 2629*fcf3ce44SJohn Forte ch->h_cfgs[i].l_nentry = list_size; 2630*fcf3ce44SJohn Forte 2631*fcf3ce44SJohn Forte ip += list_size; 2632*fcf3ce44SJohn Forte 2633*fcf3ce44SJohn Forte } else 2634*fcf3ce44SJohn Forte 2635*fcf3ce44SJohn Forte continue; 2636*fcf3ce44SJohn Forte 2637*fcf3ce44SJohn Forte if (ch->h_cfgs[i].l_entry != NULL) { 2638*fcf3ce44SJohn Forte p = ch->h_cparse + offset; 2639*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 2640*fcf3ce44SJohn Forte (void) fprintf(stderr, "mapping list %d size %d offset %d, addr 0x%x\n", 2641*fcf3ce44SJohn Forte i, ch->h_cfgsizes[i], offset, p); 2642*fcf3ce44SJohn Forte #endif 2643*fcf3ce44SJohn Forte memcpy(ch->h_cfgs[i].l_entry, 2644*fcf3ce44SJohn Forte p, ch->h_cfgsizes[i]); 2645*fcf3ce44SJohn Forte ch->h_cfgs[i].l_size = ch->h_cfgsizes[i]; 2646*fcf3ce44SJohn Forte offset += ch->h_cfgsizes[i]; 2647*fcf3ce44SJohn Forte } else { 2648*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 2649*fcf3ce44SJohn Forte (void) fprintf(stderr, "NULL l_entry\n"); 2650*fcf3ce44SJohn Forte #endif 2651*fcf3ce44SJohn Forte return (-1); 2652*fcf3ce44SJohn Forte } 2653*fcf3ce44SJohn Forte } 2654*fcf3ce44SJohn Forte 2655*fcf3ce44SJohn Forte 2656*fcf3ce44SJohn Forte return (1); 2657*fcf3ce44SJohn Forte 2658*fcf3ce44SJohn Forte } 2659*fcf3ce44SJohn Forte 2660*fcf3ce44SJohn Forte void 2661*fcf3ce44SJohn Forte cfg_replace_lists(cfp_t *cfp) 2662*fcf3ce44SJohn Forte { 2663*fcf3ce44SJohn Forte int i; 2664*fcf3ce44SJohn Forte int offset = 0; 2665*fcf3ce44SJohn Forte int size_offset = 0; 2666*fcf3ce44SJohn Forte 2667*fcf3ce44SJohn Forte int section = 0; 2668*fcf3ce44SJohn Forte cfgheader_t *cf; 2669*fcf3ce44SJohn Forte cfglist_t *cfl; 2670*fcf3ce44SJohn Forte 2671*fcf3ce44SJohn Forte cf = cfp->cf_head; 2672*fcf3ce44SJohn Forte 2673*fcf3ce44SJohn Forte if ((cfl = cfp->cf_head->h_cfgs) == NULL) 2674*fcf3ce44SJohn Forte return; 2675*fcf3ce44SJohn Forte 2676*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 2677*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg_replace_lists\n"); 2678*fcf3ce44SJohn Forte #endif 2679*fcf3ce44SJohn Forte 2680*fcf3ce44SJohn Forte if (cf->h_cparse == cf->h_ccopy1) 2681*fcf3ce44SJohn Forte section = 1; 2682*fcf3ce44SJohn Forte 2683*fcf3ce44SJohn Forte /* 2684*fcf3ce44SJohn Forte * check to see if we are using copy1 or 2, 2685*fcf3ce44SJohn Forte * grow or shrink the size, fix h_cparse reference 2686*fcf3ce44SJohn Forte * in case realloc gave us a funky new address. 2687*fcf3ce44SJohn Forte * put stuff in it. 2688*fcf3ce44SJohn Forte */ 2689*fcf3ce44SJohn Forte cf->h_ccopy1 = (char *) 2690*fcf3ce44SJohn Forte realloc(cf->h_ccopy1, cf->h_csize * sizeof (char)); 2691*fcf3ce44SJohn Forte cf->h_ccopy2 = (char *) 2692*fcf3ce44SJohn Forte realloc(cf->h_ccopy2, cf->h_csize * sizeof (char)); 2693*fcf3ce44SJohn Forte if (section == 1) { 2694*fcf3ce44SJohn Forte /* we used copy1 */ 2695*fcf3ce44SJohn Forte cf->h_cparse = cf->h_ccopy1; 2696*fcf3ce44SJohn Forte } else 2697*fcf3ce44SJohn Forte cf->h_cparse = cf->h_ccopy2; 2698*fcf3ce44SJohn Forte 2699*fcf3ce44SJohn Forte /* 2700*fcf3ce44SJohn Forte * just because, we'll zero out h_csize and recalc 2701*fcf3ce44SJohn Forte * after all, this is the number the next guy gets 2702*fcf3ce44SJohn Forte */ 2703*fcf3ce44SJohn Forte cf->h_csize = cf->h_sizes[0] = 0; 2704*fcf3ce44SJohn Forte for (i = 0; i < MAX_CFG; i++) { 2705*fcf3ce44SJohn Forte /* only as many lists as chead has */ 2706*fcf3ce44SJohn Forte if (chead[i].tag.l_word[0] == '\0') { 2707*fcf3ce44SJohn Forte break; 2708*fcf3ce44SJohn Forte } 2709*fcf3ce44SJohn Forte if (cfl[i].l_entry && cfl[i].l_entry[0] != '\0') { 2710*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 2711*fcf3ce44SJohn Forte (void) fprintf(stderr, 2712*fcf3ce44SJohn Forte "copying list %d at %x size %d\n", 2713*fcf3ce44SJohn Forte i, cf->h_cparse + offset, 2714*fcf3ce44SJohn Forte cfl[i].l_size); 2715*fcf3ce44SJohn Forte #endif 2716*fcf3ce44SJohn Forte memcpy((cf->h_cparse + offset), 2717*fcf3ce44SJohn Forte cfl[i].l_entry, cfl[i].l_size); 2718*fcf3ce44SJohn Forte offset += cfl[i].l_size; 2719*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 2720*fcf3ce44SJohn Forte (void) fprintf(stderr, 2721*fcf3ce44SJohn Forte "cfl[%d].l_nentry %d cfl[%d].l_esiz[%d] %d" 2722*fcf3ce44SJohn Forte " size offset %d\n", 2723*fcf3ce44SJohn Forte i, cfl[i].l_nentry, i, cfl[i].l_nentry - 1, 2724*fcf3ce44SJohn Forte cfl[i].l_esiz[cfl[i].l_nentry - 1], size_offset); 2725*fcf3ce44SJohn Forte #endif 2726*fcf3ce44SJohn Forte /* 2727*fcf3ce44SJohn Forte * first write the number of entries 2728*fcf3ce44SJohn Forte * then copy over the array ie. 2729*fcf3ce44SJohn Forte * a list with 5 elements would be copied 2730*fcf3ce44SJohn Forte * as a 6 element array slot 0 being the 2731*fcf3ce44SJohn Forte * number of elements 2732*fcf3ce44SJohn Forte */ 2733*fcf3ce44SJohn Forte cf->h_sizes[size_offset++] = cfl[i].l_nentry; 2734*fcf3ce44SJohn Forte memcpy((cf->h_sizes + size_offset), cfl[i].l_esiz, 2735*fcf3ce44SJohn Forte cfl[i].l_nentry * sizeof (int)); 2736*fcf3ce44SJohn Forte size_offset += cfl[i].l_nentry; 2737*fcf3ce44SJohn Forte cf->h_sizes[size_offset] = 0; 2738*fcf3ce44SJohn Forte } 2739*fcf3ce44SJohn Forte cf->h_csize += cfl[i].l_size; 2740*fcf3ce44SJohn Forte } 2741*fcf3ce44SJohn Forte } 2742*fcf3ce44SJohn Forte 2743*fcf3ce44SJohn Forte void 2744*fcf3ce44SJohn Forte cfg_free_cfglist(cfp_t *cfp) 2745*fcf3ce44SJohn Forte { 2746*fcf3ce44SJohn Forte int i; 2747*fcf3ce44SJohn Forte 2748*fcf3ce44SJohn Forte if (!cfp->cf_head || !cfp->cf_head->h_cfgs) 2749*fcf3ce44SJohn Forte return; 2750*fcf3ce44SJohn Forte 2751*fcf3ce44SJohn Forte for (i = 0; cfp->cf_head && i < MAX_CFG; i++) { 2752*fcf3ce44SJohn Forte if (cfp->cf_head->h_cfgs[i].l_entry) { 2753*fcf3ce44SJohn Forte free(cfp->cf_head->h_cfgs[i].l_entry); 2754*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[i].l_entry = NULL; 2755*fcf3ce44SJohn Forte } 2756*fcf3ce44SJohn Forte 2757*fcf3ce44SJohn Forte if (cfp->cf_head->h_cfgs[i].l_name) { 2758*fcf3ce44SJohn Forte free(cfp->cf_head->h_cfgs[i].l_name); 2759*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[i].l_entry = NULL; 2760*fcf3ce44SJohn Forte } 2761*fcf3ce44SJohn Forte 2762*fcf3ce44SJohn Forte if (cfp->cf_head->h_cfgs[i].l_esiz) { 2763*fcf3ce44SJohn Forte free(cfp->cf_head->h_cfgs[i].l_esiz); 2764*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[i].l_esiz = NULL; 2765*fcf3ce44SJohn Forte } 2766*fcf3ce44SJohn Forte } 2767*fcf3ce44SJohn Forte 2768*fcf3ce44SJohn Forte if (cfp->cf_head) { 2769*fcf3ce44SJohn Forte free(cfp->cf_head->h_cfgs); 2770*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs = NULL; 2771*fcf3ce44SJohn Forte } 2772*fcf3ce44SJohn Forte } 2773*fcf3ce44SJohn Forte 2774*fcf3ce44SJohn Forte void 2775*fcf3ce44SJohn Forte cfg_free_parser_tree() 2776*fcf3ce44SJohn Forte { 2777*fcf3ce44SJohn Forte struct lookup *p = NULL; 2778*fcf3ce44SJohn Forte struct lookup *q = NULL; 2779*fcf3ce44SJohn Forte int i; 2780*fcf3ce44SJohn Forte 2781*fcf3ce44SJohn Forte for (i = 0; i < MAX_CFG; i++) { 2782*fcf3ce44SJohn Forte if (chead) 2783*fcf3ce44SJohn Forte p = chead[i].fld; 2784*fcf3ce44SJohn Forte while (p) { 2785*fcf3ce44SJohn Forte q = p->l_next; 2786*fcf3ce44SJohn Forte if (p) { 2787*fcf3ce44SJohn Forte free(p); 2788*fcf3ce44SJohn Forte p = NULL; 2789*fcf3ce44SJohn Forte } 2790*fcf3ce44SJohn Forte p = q; 2791*fcf3ce44SJohn Forte } 2792*fcf3ce44SJohn Forte } 2793*fcf3ce44SJohn Forte bzero(chead, MAX_CFG * sizeof (struct parser)); 2794*fcf3ce44SJohn Forte } 2795*fcf3ce44SJohn Forte 2796*fcf3ce44SJohn Forte void 2797*fcf3ce44SJohn Forte cfg_close(CFGFILE *cfg) 2798*fcf3ce44SJohn Forte { 2799*fcf3ce44SJohn Forte cfp_t *cfp; 2800*fcf3ce44SJohn Forte 2801*fcf3ce44SJohn Forte if (cfg == NULL) { 2802*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 2803*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2804*fcf3ce44SJohn Forte return; 2805*fcf3ce44SJohn Forte } 2806*fcf3ce44SJohn Forte 2807*fcf3ce44SJohn Forte /* Determine number of files open */ 2808*fcf3ce44SJohn Forte for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) { 2809*fcf3ce44SJohn Forte if (!cfp->cf_fd) continue; 2810*fcf3ce44SJohn Forte 2811*fcf3ce44SJohn Forte (*cfp->cf_pp->close)(cfp); 2812*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 2813*fcf3ce44SJohn Forte (void) fprintf(stderr, "freeing cfglists\n"); 2814*fcf3ce44SJohn Forte #endif 2815*fcf3ce44SJohn Forte cfg_free_cfglist(cfp); 2816*fcf3ce44SJohn Forte 2817*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 2818*fcf3ce44SJohn Forte (void) fprintf(stderr, "freeing cfp->cf_mapped\n"); 2819*fcf3ce44SJohn Forte #endif 2820*fcf3ce44SJohn Forte free(cfp->cf_mapped); 2821*fcf3ce44SJohn Forte cfp->cf_mapped = NULL; 2822*fcf3ce44SJohn Forte 2823*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 2824*fcf3ce44SJohn Forte (void) fprintf(stderr, 2825*fcf3ce44SJohn Forte "freeing copy1, copy2, h_sizes and cf\n"); 2826*fcf3ce44SJohn Forte #endif 2827*fcf3ce44SJohn Forte if (cfp->cf_head) { 2828*fcf3ce44SJohn Forte if (cfp->cf_head->h_ccopy1) { 2829*fcf3ce44SJohn Forte free(cfp->cf_head->h_ccopy1); 2830*fcf3ce44SJohn Forte cfp->cf_head->h_ccopy1 = NULL; 2831*fcf3ce44SJohn Forte } 2832*fcf3ce44SJohn Forte if (cfp->cf_head->h_ccopy2) { 2833*fcf3ce44SJohn Forte free(cfp->cf_head->h_ccopy2); 2834*fcf3ce44SJohn Forte cfp->cf_head->h_ccopy2 = NULL; 2835*fcf3ce44SJohn Forte } 2836*fcf3ce44SJohn Forte if (cfp->cf_head->h_sizes1) { 2837*fcf3ce44SJohn Forte free(cfp->cf_head->h_sizes1); 2838*fcf3ce44SJohn Forte cfp->cf_head->h_sizes1 = NULL; 2839*fcf3ce44SJohn Forte } 2840*fcf3ce44SJohn Forte if (cfp->cf_head->h_sizes2) { 2841*fcf3ce44SJohn Forte free(cfp->cf_head->h_sizes2); 2842*fcf3ce44SJohn Forte cfp->cf_head->h_sizes2 = NULL; 2843*fcf3ce44SJohn Forte } 2844*fcf3ce44SJohn Forte 2845*fcf3ce44SJohn Forte } 2846*fcf3ce44SJohn Forte if (cfp->cf_head) 2847*fcf3ce44SJohn Forte free(cfp->cf_head); 2848*fcf3ce44SJohn Forte } 2849*fcf3ce44SJohn Forte 2850*fcf3ce44SJohn Forte free(cfg); 2851*fcf3ce44SJohn Forte cfg = NULL; 2852*fcf3ce44SJohn Forte cfg_free_parser_tree(); 2853*fcf3ce44SJohn Forte 2854*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 2855*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg_close\n"); 2856*fcf3ce44SJohn Forte #endif 2857*fcf3ce44SJohn Forte } 2858*fcf3ce44SJohn Forte 2859*fcf3ce44SJohn Forte 2860*fcf3ce44SJohn Forte char * 2861*fcf3ce44SJohn Forte cfg_get_resource(CFGFILE *cfg) 2862*fcf3ce44SJohn Forte { 2863*fcf3ce44SJohn Forte if (cfg == NULL) { 2864*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 2865*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2866*fcf3ce44SJohn Forte return (NULL); 2867*fcf3ce44SJohn Forte } 2868*fcf3ce44SJohn Forte 2869*fcf3ce44SJohn Forte return (cfg->cf_node); 2870*fcf3ce44SJohn Forte } 2871*fcf3ce44SJohn Forte 2872*fcf3ce44SJohn Forte /* 2873*fcf3ce44SJohn Forte * cfg_resource 2874*fcf3ce44SJohn Forte * set or clear the cluster node filter for get/put 2875*fcf3ce44SJohn Forte */ 2876*fcf3ce44SJohn Forte 2877*fcf3ce44SJohn Forte void 2878*fcf3ce44SJohn Forte cfg_resource(CFGFILE *cfg, const char *node) 2879*fcf3ce44SJohn Forte { 2880*fcf3ce44SJohn Forte if (cfg == NULL) { 2881*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 2882*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2883*fcf3ce44SJohn Forte return; 2884*fcf3ce44SJohn Forte } 2885*fcf3ce44SJohn Forte 2886*fcf3ce44SJohn Forte if (cfg->cf_node) { 2887*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 2888*fcf3ce44SJohn Forte (void) fprintf(stderr, 2889*fcf3ce44SJohn Forte "cfg_resource: changing node from %s to %s\n", 2890*fcf3ce44SJohn Forte cfg->cf_node, (node?node:"NULL")); 2891*fcf3ce44SJohn Forte #endif 2892*fcf3ce44SJohn Forte free(cfg->cf_node); 2893*fcf3ce44SJohn Forte cfg->cf_node = NULL; 2894*fcf3ce44SJohn Forte } 2895*fcf3ce44SJohn Forte 2896*fcf3ce44SJohn Forte /* 2897*fcf3ce44SJohn Forte * just in case someone passes in a non-NULL 2898*fcf3ce44SJohn Forte * node, but has no valid value 2899*fcf3ce44SJohn Forte */ 2900*fcf3ce44SJohn Forte if ((node) && (node[0] != '\0')) { 2901*fcf3ce44SJohn Forte cfg->cf_node = strdup(node); 2902*fcf3ce44SJohn Forte } 2903*fcf3ce44SJohn Forte } 2904*fcf3ce44SJohn Forte 2905*fcf3ce44SJohn Forte /* 2906*fcf3ce44SJohn Forte * cfg_open 2907*fcf3ce44SJohn Forte * Open the current configuration file 2908*fcf3ce44SJohn Forte */ 2909*fcf3ce44SJohn Forte CFGFILE * 2910*fcf3ce44SJohn Forte cfg_open(char *name) 2911*fcf3ce44SJohn Forte { 2912*fcf3ce44SJohn Forte CFGFILE *cfg; 2913*fcf3ce44SJohn Forte cfp_t *cfp; 2914*fcf3ce44SJohn Forte int32_t magic; 2915*fcf3ce44SJohn Forte long needed; 2916*fcf3ce44SJohn Forte int rc; 2917*fcf3ce44SJohn Forte 2918*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 2919*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg_open\n"); 2920*fcf3ce44SJohn Forte #endif 2921*fcf3ce44SJohn Forte 2922*fcf3ce44SJohn Forte cfg_severity = 0; 2923*fcf3ce44SJohn Forte if ((cfg = (CFGFILE *)calloc(1, sizeof (*cfg))) == NULL) { 2924*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 2925*fcf3ce44SJohn Forte "cfg_open: malloc failed"); 2926*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2927*fcf3ce44SJohn Forte return (NULL); 2928*fcf3ce44SJohn Forte } 2929*fcf3ce44SJohn Forte 2930*fcf3ce44SJohn Forte cfp = &cfg->cf[0]; 2931*fcf3ce44SJohn Forte if ((name) && strlen(name)) { 2932*fcf3ce44SJohn Forte #ifdef DEBUG 2933*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg_open: Using non-standard name\n"); 2934*fcf3ce44SJohn Forte #endif 2935*fcf3ce44SJohn Forte cfp->cf_name = name; 2936*fcf3ce44SJohn Forte cfp->cf_pp = (strstr(cfp->cf_name, "/rdsk/") == NULL) 2937*fcf3ce44SJohn Forte ? cfg_block_io_provider() 2938*fcf3ce44SJohn Forte : cfg_raw_io_provider(); 2939*fcf3ce44SJohn Forte } else { 2940*fcf3ce44SJohn Forte cfp->cf_name = cfg_location(NULL, CFG_LOC_GET_LOCAL, NULL); 2941*fcf3ce44SJohn Forte cfp->cf_pp = cfg_block_io_provider(); 2942*fcf3ce44SJohn Forte 2943*fcf3ce44SJohn Forte /* Handle cfg_open(""), which is an open from boot tools */ 2944*fcf3ce44SJohn Forte if (name) 2945*fcf3ce44SJohn Forte cl_initialized = 1; 2946*fcf3ce44SJohn Forte if (cfg_iscluster() > 0) { 2947*fcf3ce44SJohn Forte cfp = &cfg->cf[1]; 2948*fcf3ce44SJohn Forte cfp->cf_name = 2949*fcf3ce44SJohn Forte cfg_location(NULL, CFG_LOC_GET_CLUSTER, NULL); 2950*fcf3ce44SJohn Forte if (cfp->cf_name) { 2951*fcf3ce44SJohn Forte cfp->cf_pp = cfg_raw_io_provider(); 2952*fcf3ce44SJohn Forte } 2953*fcf3ce44SJohn Forte } 2954*fcf3ce44SJohn Forte } 2955*fcf3ce44SJohn Forte 2956*fcf3ce44SJohn Forte /* 2957*fcf3ce44SJohn Forte * Open one or two configuration files 2958*fcf3ce44SJohn Forte */ 2959*fcf3ce44SJohn Forte for (cfp = &cfg->cf[0]; cfp->cf_name && (cfp <= &cfg->cf[1]); cfp++) { 2960*fcf3ce44SJohn Forte if ((*cfp->cf_pp->open)(cfp, cfp->cf_name) == NULL) { 2961*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 2962*fcf3ce44SJohn Forte "cfg_open: unable to open configuration location"); 2963*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2964*fcf3ce44SJohn Forte break; 2965*fcf3ce44SJohn Forte } 2966*fcf3ce44SJohn Forte 2967*fcf3ce44SJohn Forte /* block device smaller than repository? */ 2968*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->read)(cfp, &magic, sizeof (magic)); 2969*fcf3ce44SJohn Forte if (rc < sizeof (magic)) { 2970*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 2971*fcf3ce44SJohn Forte "cfg_open: unable to read configuration header"); 2972*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2973*fcf3ce44SJohn Forte break; 2974*fcf3ce44SJohn Forte } 2975*fcf3ce44SJohn Forte 2976*fcf3ce44SJohn Forte if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) { 2977*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 2978*fcf3ce44SJohn Forte "cfg_open: unable to seek configuration header"); 2979*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2980*fcf3ce44SJohn Forte break; 2981*fcf3ce44SJohn Forte } 2982*fcf3ce44SJohn Forte 2983*fcf3ce44SJohn Forte /* 2984*fcf3ce44SJohn Forte * we can't enforce size rules on an old database 2985*fcf3ce44SJohn Forte * so check the magic number before we test for size 2986*fcf3ce44SJohn Forte */ 2987*fcf3ce44SJohn Forte if (magic == CFG_NEW_MAGIC) { 2988*fcf3ce44SJohn Forte needed = FBA_NUM(FBA_SIZE(1) - 1 + 2989*fcf3ce44SJohn Forte (sizeof (struct cfgheader) + CFG_CONFIG_SIZE)); 2990*fcf3ce44SJohn Forte } else { 2991*fcf3ce44SJohn Forte needed = 0; 2992*fcf3ce44SJohn Forte } 2993*fcf3ce44SJohn Forte 2994*fcf3ce44SJohn Forte if (cfp->cf_size < needed) { 2995*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 2996*fcf3ce44SJohn Forte "cfg_open: configuration file too small"); 2997*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 2998*fcf3ce44SJohn Forte errno = ENOMEM; 2999*fcf3ce44SJohn Forte break; 3000*fcf3ce44SJohn Forte } 3001*fcf3ce44SJohn Forte 3002*fcf3ce44SJohn Forte cfp->cf_mapped = (char *)malloc(CFG_DEFAULT_PARSE_SIZE); 3003*fcf3ce44SJohn Forte if (cfp->cf_mapped == NULL) { 3004*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 3005*fcf3ce44SJohn Forte "cfg_open: malloc failed"); 3006*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 3007*fcf3ce44SJohn Forte break; 3008*fcf3ce44SJohn Forte } 3009*fcf3ce44SJohn Forte 3010*fcf3ce44SJohn Forte bzero(cfp->cf_mapped, CFG_DEFAULT_PARSE_SIZE); 3011*fcf3ce44SJohn Forte cfp->cf_lock = -1; 3012*fcf3ce44SJohn Forte } 3013*fcf3ce44SJohn Forte 3014*fcf3ce44SJohn Forte /* Processing errors, take care of one or more cfp pointers */ 3015*fcf3ce44SJohn Forte if (cfg_severity && (cfp <= &cfg->cf[1])) { 3016*fcf3ce44SJohn Forte cfp = &cfg->cf[0]; 3017*fcf3ce44SJohn Forte if (cfp->cf_fd) 3018*fcf3ce44SJohn Forte (*cfp->cf_pp->close)(cfp); 3019*fcf3ce44SJohn Forte cfp = &cfg->cf[1]; 3020*fcf3ce44SJohn Forte if (cfp->cf_fd) 3021*fcf3ce44SJohn Forte (*cfp->cf_pp->close)(cfp); 3022*fcf3ce44SJohn Forte free(cfg); 3023*fcf3ce44SJohn Forte return (NULL); 3024*fcf3ce44SJohn Forte } 3025*fcf3ce44SJohn Forte 3026*fcf3ce44SJohn Forte cfg_lockd = cfg_lockd_init(); 3027*fcf3ce44SJohn Forte 3028*fcf3ce44SJohn Forte 3029*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 3030*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg_open ok\n"); 3031*fcf3ce44SJohn Forte #endif 3032*fcf3ce44SJohn Forte return (cfg); 3033*fcf3ce44SJohn Forte } 3034*fcf3ce44SJohn Forte 3035*fcf3ce44SJohn Forte void 3036*fcf3ce44SJohn Forte cfg_invalidate_hsizes(int fd, const char *loc) { 3037*fcf3ce44SJohn Forte int offset; 3038*fcf3ce44SJohn Forte int rc = -1; 3039*fcf3ce44SJohn Forte int hdrsz; 3040*fcf3ce44SJohn Forte 3041*fcf3ce44SJohn Forte char buf[2 * CFG_DEFAULT_PSIZE]; 3042*fcf3ce44SJohn Forte 3043*fcf3ce44SJohn Forte hdrsz = sizeof (cfgheader_t) + 512 - 3044*fcf3ce44SJohn Forte (sizeof (cfgheader_t) % 512); 3045*fcf3ce44SJohn Forte 3046*fcf3ce44SJohn Forte offset = hdrsz + CFG_DEFAULT_PARSE_SIZE + 3047*fcf3ce44SJohn Forte (CFG_DEFAULT_SSIZE * 2); 3048*fcf3ce44SJohn Forte 3049*fcf3ce44SJohn Forte if (cfg_shldskip_vtoc(fd, loc) > 0) 3050*fcf3ce44SJohn Forte offset += CFG_VTOC_SKIP; 3051*fcf3ce44SJohn Forte 3052*fcf3ce44SJohn Forte bzero(buf, sizeof (buf)); 3053*fcf3ce44SJohn Forte 3054*fcf3ce44SJohn Forte if (lseek(fd, offset, SEEK_SET) > 0) 3055*fcf3ce44SJohn Forte rc = write(fd, buf, sizeof (buf)); 3056*fcf3ce44SJohn Forte if (rc < 0) 3057*fcf3ce44SJohn Forte (void) fprintf(stderr, "cfg: invalidate hsizes failed\n"); 3058*fcf3ce44SJohn Forte 3059*fcf3ce44SJohn Forte } 3060*fcf3ce44SJohn Forte 3061*fcf3ce44SJohn Forte char * 3062*fcf3ce44SJohn Forte cfg_error(int *severity) 3063*fcf3ce44SJohn Forte { 3064*fcf3ce44SJohn Forte if (severity != NULL) 3065*fcf3ce44SJohn Forte *severity = cfg_severity; 3066*fcf3ce44SJohn Forte return (cfg_perror_str ? cfg_perror_str : CFG_EGENERIC); 3067*fcf3ce44SJohn Forte } 3068*fcf3ce44SJohn Forte /* 3069*fcf3ce44SJohn Forte * cfg_cfg_isempty 3070*fcf3ce44SJohn Forte */ 3071*fcf3ce44SJohn Forte int 3072*fcf3ce44SJohn Forte cfg_cfg_isempty(CFGFILE *cfg) 3073*fcf3ce44SJohn Forte { 3074*fcf3ce44SJohn Forte cfp_t *cfp; 3075*fcf3ce44SJohn Forte 3076*fcf3ce44SJohn Forte if (cfg == NULL) { 3077*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 3078*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 3079*fcf3ce44SJohn Forte return (FALSE); 3080*fcf3ce44SJohn Forte } 3081*fcf3ce44SJohn Forte 3082*fcf3ce44SJohn Forte cfp = FP_SUN_CLUSTER(cfg); 3083*fcf3ce44SJohn Forte if (cfp->cf_head->h_csize == 0) 3084*fcf3ce44SJohn Forte return (TRUE); 3085*fcf3ce44SJohn Forte else 3086*fcf3ce44SJohn Forte return (FALSE); 3087*fcf3ce44SJohn Forte } 3088*fcf3ce44SJohn Forte 3089*fcf3ce44SJohn Forte /* 3090*fcf3ce44SJohn Forte * cfg_get_num_entries 3091*fcf3ce44SJohn Forte * return the number of entries in a given section of database 3092*fcf3ce44SJohn Forte * sndr, ii, ndr_ii... 3093*fcf3ce44SJohn Forte */ 3094*fcf3ce44SJohn Forte int 3095*fcf3ce44SJohn Forte cfg_get_num_entries(CFGFILE *cfg, char *section) 3096*fcf3ce44SJohn Forte { 3097*fcf3ce44SJohn Forte int count = 0; 3098*fcf3ce44SJohn Forte int table_offset; 3099*fcf3ce44SJohn Forte cfp_t *cfp; 3100*fcf3ce44SJohn Forte 3101*fcf3ce44SJohn Forte if (cfg == NULL) { 3102*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 3103*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 3104*fcf3ce44SJohn Forte return (-1); 3105*fcf3ce44SJohn Forte } 3106*fcf3ce44SJohn Forte 3107*fcf3ce44SJohn Forte if ((table_offset = cfg_get_parser_offset(section)) < 0) { 3108*fcf3ce44SJohn Forte errno = ESRCH; 3109*fcf3ce44SJohn Forte return (-1); 3110*fcf3ce44SJohn Forte } 3111*fcf3ce44SJohn Forte 3112*fcf3ce44SJohn Forte /* Determine number of files open */ 3113*fcf3ce44SJohn Forte for (cfp = &cfg->cf[0]; cfp->cf_fd && (cfp <= &cfg->cf[1]); cfp++) 3114*fcf3ce44SJohn Forte count += cfp->cf_head->h_cfgs[table_offset].l_nentry; 3115*fcf3ce44SJohn Forte 3116*fcf3ce44SJohn Forte return (count); 3117*fcf3ce44SJohn Forte } 3118*fcf3ce44SJohn Forte 3119*fcf3ce44SJohn Forte /* 3120*fcf3ce44SJohn Forte * cfg_get_section 3121*fcf3ce44SJohn Forte * all etries in a config file section is placed in 3122*fcf3ce44SJohn Forte * buf, allocation is done inside 3123*fcf3ce44SJohn Forte * freeing buf is responisbility of the caller 3124*fcf3ce44SJohn Forte * number of entries in section is returned 3125*fcf3ce44SJohn Forte * -1 on failure, errno is set 3126*fcf3ce44SJohn Forte */ 3127*fcf3ce44SJohn Forte int 3128*fcf3ce44SJohn Forte cfg_get_section(CFGFILE *cfg, char ***list, const char *section) 3129*fcf3ce44SJohn Forte { 3130*fcf3ce44SJohn Forte int table_offset; 3131*fcf3ce44SJohn Forte int i, count; 3132*fcf3ce44SJohn Forte cfglist_t *cfl; 3133*fcf3ce44SJohn Forte char *p = NULL; 3134*fcf3ce44SJohn Forte char **buf; 3135*fcf3ce44SJohn Forte cfp_t *cfp; 3136*fcf3ce44SJohn Forte 3137*fcf3ce44SJohn Forte if (cfg == NULL) { 3138*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 3139*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 3140*fcf3ce44SJohn Forte return (FALSE); 3141*fcf3ce44SJohn Forte } 3142*fcf3ce44SJohn Forte 3143*fcf3ce44SJohn Forte if ((table_offset = cfg_get_parser_offset(section)) < 0) { 3144*fcf3ce44SJohn Forte errno = ESRCH; 3145*fcf3ce44SJohn Forte return (-1); 3146*fcf3ce44SJohn Forte } 3147*fcf3ce44SJohn Forte 3148*fcf3ce44SJohn Forte /* Determine number of files open */ 3149*fcf3ce44SJohn Forte count = 0; 3150*fcf3ce44SJohn Forte for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) { 3151*fcf3ce44SJohn Forte if (!cfp->cf_fd) continue; 3152*fcf3ce44SJohn Forte if (cfp->cf_head->h_state & CFG_HDR_INVALID) { 3153*fcf3ce44SJohn Forte if (!cfg_read(cfp)) { 3154*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_RDFAILED); 3155*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 3156*fcf3ce44SJohn Forte return (-1); 3157*fcf3ce44SJohn Forte } 3158*fcf3ce44SJohn Forte } 3159*fcf3ce44SJohn Forte 3160*fcf3ce44SJohn Forte cfl = &cfp->cf_head->h_cfgs[table_offset]; 3161*fcf3ce44SJohn Forte if (cfl->l_nentry == 0) /* empty list */ 3162*fcf3ce44SJohn Forte continue; 3163*fcf3ce44SJohn Forte 3164*fcf3ce44SJohn Forte if (count == 0) 3165*fcf3ce44SJohn Forte buf = (char **)malloc(cfl->l_nentry * sizeof (char *)); 3166*fcf3ce44SJohn Forte else 3167*fcf3ce44SJohn Forte buf = (char **)realloc(buf, (cfl->l_nentry + count) * 3168*fcf3ce44SJohn Forte sizeof (char *)); 3169*fcf3ce44SJohn Forte if (buf == NULL) { 3170*fcf3ce44SJohn Forte errno = ENOMEM; 3171*fcf3ce44SJohn Forte return (-1); 3172*fcf3ce44SJohn Forte } else { 3173*fcf3ce44SJohn Forte bzero(&buf[count], cfl->l_nentry * sizeof (char *)); 3174*fcf3ce44SJohn Forte } 3175*fcf3ce44SJohn Forte 3176*fcf3ce44SJohn Forte p = cfl->l_entry; 3177*fcf3ce44SJohn Forte for (i = 0; i < cfl->l_nentry; i++) { 3178*fcf3ce44SJohn Forte if ((buf[i + count] = strdup(p)) == NULL) { 3179*fcf3ce44SJohn Forte errno = ENOMEM; 3180*fcf3ce44SJohn Forte return (-1); 3181*fcf3ce44SJohn Forte } 3182*fcf3ce44SJohn Forte p += cfl->l_esiz[i]; 3183*fcf3ce44SJohn Forte } 3184*fcf3ce44SJohn Forte count += cfl->l_nentry; 3185*fcf3ce44SJohn Forte } 3186*fcf3ce44SJohn Forte 3187*fcf3ce44SJohn Forte *list = buf; 3188*fcf3ce44SJohn Forte return (count); 3189*fcf3ce44SJohn Forte } 3190*fcf3ce44SJohn Forte 3191*fcf3ce44SJohn Forte /* 3192*fcf3ce44SJohn Forte * cluster upgrade helper functions. These support old database operations 3193*fcf3ce44SJohn Forte * while upgrading nodes on a cluster. 3194*fcf3ce44SJohn Forte */ 3195*fcf3ce44SJohn Forte 3196*fcf3ce44SJohn Forte /* 3197*fcf3ce44SJohn Forte * returns the list of configured tags 3198*fcf3ce44SJohn Forte * return -1 on error, else the number 3199*fcf3ce44SJohn Forte * of tags returned in taglist 3200*fcf3ce44SJohn Forte * caller frees 3201*fcf3ce44SJohn Forte */ 3202*fcf3ce44SJohn Forte int 3203*fcf3ce44SJohn Forte cfg_get_tags(CFGFILE *cfg, char ***taglist) 3204*fcf3ce44SJohn Forte { 3205*fcf3ce44SJohn Forte char **list; 3206*fcf3ce44SJohn Forte int i = 0; 3207*fcf3ce44SJohn Forte 3208*fcf3ce44SJohn Forte if (cfg == NULL) { 3209*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 3210*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 3211*fcf3ce44SJohn Forte return (-1); 3212*fcf3ce44SJohn Forte } 3213*fcf3ce44SJohn Forte 3214*fcf3ce44SJohn Forte if (!cfg_rdlock(cfg)) { 3215*fcf3ce44SJohn Forte return (-1); 3216*fcf3ce44SJohn Forte } 3217*fcf3ce44SJohn Forte list = calloc(1, MAX_CFG * sizeof (char *)); 3218*fcf3ce44SJohn Forte if (list == NULL) { 3219*fcf3ce44SJohn Forte errno = ENOMEM; 3220*fcf3ce44SJohn Forte return (-1); 3221*fcf3ce44SJohn Forte } 3222*fcf3ce44SJohn Forte 3223*fcf3ce44SJohn Forte while ((i < MAX_CFG) && (chead[i].tag.l_word[0] != '\0')) { 3224*fcf3ce44SJohn Forte list[i] = strdup(chead[i].tag.l_word); 3225*fcf3ce44SJohn Forte if (list[i] == NULL) { 3226*fcf3ce44SJohn Forte for (/* CSTYLE */; i >= 0; i--) { 3227*fcf3ce44SJohn Forte if (list[i]) 3228*fcf3ce44SJohn Forte free(list[i]); 3229*fcf3ce44SJohn Forte } 3230*fcf3ce44SJohn Forte free(list); 3231*fcf3ce44SJohn Forte errno = ENOMEM; 3232*fcf3ce44SJohn Forte return (-1); 3233*fcf3ce44SJohn Forte } 3234*fcf3ce44SJohn Forte i++; 3235*fcf3ce44SJohn Forte } 3236*fcf3ce44SJohn Forte *taglist = list; 3237*fcf3ce44SJohn Forte return (i); 3238*fcf3ce44SJohn Forte 3239*fcf3ce44SJohn Forte } 3240*fcf3ce44SJohn Forte 3241*fcf3ce44SJohn Forte /* 3242*fcf3ce44SJohn Forte * is this a database? 3243*fcf3ce44SJohn Forte * check the header for the magic number 3244*fcf3ce44SJohn Forte * 0 no match 1 match, -1 on error 3245*fcf3ce44SJohn Forte */ 3246*fcf3ce44SJohn Forte int 3247*fcf3ce44SJohn Forte cfg_is_cfg(CFGFILE *cfg) 3248*fcf3ce44SJohn Forte { 3249*fcf3ce44SJohn Forte int32_t magic; 3250*fcf3ce44SJohn Forte int rc; 3251*fcf3ce44SJohn Forte cfp_t *cfp = FP_SUN_CLUSTER(cfg); 3252*fcf3ce44SJohn Forte 3253*fcf3ce44SJohn Forte rc = (cfp->cf_pp->read)(cfp, &magic, sizeof (magic)); 3254*fcf3ce44SJohn Forte if (rc < sizeof (magic)) { 3255*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "Fail to read configuration"); 3256*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 3257*fcf3ce44SJohn Forte return (-1); 3258*fcf3ce44SJohn Forte } 3259*fcf3ce44SJohn Forte 3260*fcf3ce44SJohn Forte if (magic == CFG_NEW_MAGIC) 3261*fcf3ce44SJohn Forte return (1); 3262*fcf3ce44SJohn Forte 3263*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 3264*fcf3ce44SJohn Forte "configuration not initialized, bad magic"); 3265*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 3266*fcf3ce44SJohn Forte 3267*fcf3ce44SJohn Forte return (0); 3268*fcf3ce44SJohn Forte } 3269*fcf3ce44SJohn Forte 3270*fcf3ce44SJohn Forte int 3271*fcf3ce44SJohn Forte compare(const void* a, const void *b) 3272*fcf3ce44SJohn Forte { 3273*fcf3ce44SJohn Forte char *p; 3274*fcf3ce44SJohn Forte char *pbuf; 3275*fcf3ce44SJohn Forte char *q; 3276*fcf3ce44SJohn Forte char *qbuf; 3277*fcf3ce44SJohn Forte int needed; 3278*fcf3ce44SJohn Forte int cmp; 3279*fcf3ce44SJohn Forte int pos; 3280*fcf3ce44SJohn Forte 3281*fcf3ce44SJohn Forte pbuf = strdup(a); 3282*fcf3ce44SJohn Forte qbuf = strdup(b); 3283*fcf3ce44SJohn Forte 3284*fcf3ce44SJohn Forte if (!qbuf || !pbuf) 3285*fcf3ce44SJohn Forte return (0); 3286*fcf3ce44SJohn Forte 3287*fcf3ce44SJohn Forte pos = 1; 3288*fcf3ce44SJohn Forte needed = sortby.offset; 3289*fcf3ce44SJohn Forte 3290*fcf3ce44SJohn Forte p = strtok(pbuf, " "); 3291*fcf3ce44SJohn Forte while (p) { 3292*fcf3ce44SJohn Forte if (needed == pos) { 3293*fcf3ce44SJohn Forte break; 3294*fcf3ce44SJohn Forte } 3295*fcf3ce44SJohn Forte p = strtok(NULL, " "); 3296*fcf3ce44SJohn Forte if (!p) 3297*fcf3ce44SJohn Forte break; 3298*fcf3ce44SJohn Forte pos++; 3299*fcf3ce44SJohn Forte } 3300*fcf3ce44SJohn Forte 3301*fcf3ce44SJohn Forte pos = 1; 3302*fcf3ce44SJohn Forte q = strtok(qbuf, " "); 3303*fcf3ce44SJohn Forte while (q) { 3304*fcf3ce44SJohn Forte if (needed == pos) { 3305*fcf3ce44SJohn Forte break; 3306*fcf3ce44SJohn Forte } 3307*fcf3ce44SJohn Forte q = strtok(NULL, " "); 3308*fcf3ce44SJohn Forte if (!q) 3309*fcf3ce44SJohn Forte break; 3310*fcf3ce44SJohn Forte pos++; 3311*fcf3ce44SJohn Forte } 3312*fcf3ce44SJohn Forte if (!p || !q) { 3313*fcf3ce44SJohn Forte sortby.comperror++; 3314*fcf3ce44SJohn Forte free(pbuf); 3315*fcf3ce44SJohn Forte free(qbuf); 3316*fcf3ce44SJohn Forte return (0); 3317*fcf3ce44SJohn Forte } 3318*fcf3ce44SJohn Forte cmp = strcmp(p, q); 3319*fcf3ce44SJohn Forte free(pbuf); 3320*fcf3ce44SJohn Forte free(qbuf); 3321*fcf3ce44SJohn Forte return (cmp); 3322*fcf3ce44SJohn Forte 3323*fcf3ce44SJohn Forte 3324*fcf3ce44SJohn Forte } 3325*fcf3ce44SJohn Forte /* 3326*fcf3ce44SJohn Forte * cfg_get_srtdsec 3327*fcf3ce44SJohn Forte * returns the section, sorted by supplied field 3328*fcf3ce44SJohn Forte * caller frees mem 3329*fcf3ce44SJohn Forte */ 3330*fcf3ce44SJohn Forte int 3331*fcf3ce44SJohn Forte cfg_get_srtdsec(CFGFILE *cfg, char ***list, const char *section, 3332*fcf3ce44SJohn Forte const char *field) 3333*fcf3ce44SJohn Forte { 3334*fcf3ce44SJohn Forte cfglist_t *cfl; 3335*fcf3ce44SJohn Forte cfp_t *cfp; 3336*fcf3ce44SJohn Forte char **buf; 3337*fcf3ce44SJohn Forte char *tmplst; 3338*fcf3ce44SJohn Forte char *p, *q; 3339*fcf3ce44SJohn Forte int table_offset; 3340*fcf3ce44SJohn Forte int count, i; 3341*fcf3ce44SJohn Forte 3342*fcf3ce44SJohn Forte if (cfg == NULL) { 3343*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_EINVAL); 3344*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 3345*fcf3ce44SJohn Forte return (FALSE); 3346*fcf3ce44SJohn Forte } 3347*fcf3ce44SJohn Forte 3348*fcf3ce44SJohn Forte if ((table_offset = cfg_get_parser_offset(section)) < 0) { 3349*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_RDFAILED); 3350*fcf3ce44SJohn Forte errno = ESRCH; 3351*fcf3ce44SJohn Forte return (-1); 3352*fcf3ce44SJohn Forte } 3353*fcf3ce44SJohn Forte 3354*fcf3ce44SJohn Forte /* 3355*fcf3ce44SJohn Forte * do essentially what get_section does, 3356*fcf3ce44SJohn Forte * except stick entries in a static size 3357*fcf3ce44SJohn Forte * buf to make things easier to qsort 3358*fcf3ce44SJohn Forte */ 3359*fcf3ce44SJohn Forte count = 0; 3360*fcf3ce44SJohn Forte for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) { 3361*fcf3ce44SJohn Forte if (!cfp->cf_fd) continue; 3362*fcf3ce44SJohn Forte if (cfp->cf_head->h_state & CFG_HDR_INVALID) { 3363*fcf3ce44SJohn Forte if (!cfg_read(cfp)) { 3364*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", CFG_RDFAILED); 3365*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 3366*fcf3ce44SJohn Forte return (-1); 3367*fcf3ce44SJohn Forte } 3368*fcf3ce44SJohn Forte } 3369*fcf3ce44SJohn Forte 3370*fcf3ce44SJohn Forte cfl = &cfp->cf_head->h_cfgs[table_offset]; 3371*fcf3ce44SJohn Forte if (cfl->l_nentry == 0) /* empty list */ 3372*fcf3ce44SJohn Forte continue; 3373*fcf3ce44SJohn Forte 3374*fcf3ce44SJohn Forte if (count == 0) 3375*fcf3ce44SJohn Forte buf = (char **)malloc(cfl->l_nentry * sizeof (char *)); 3376*fcf3ce44SJohn Forte else 3377*fcf3ce44SJohn Forte buf = (char **)realloc(buf, (cfl->l_nentry + count) * 3378*fcf3ce44SJohn Forte sizeof (char *)); 3379*fcf3ce44SJohn Forte if (buf == NULL) { 3380*fcf3ce44SJohn Forte errno = ENOMEM; 3381*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "cfg_get_srtdsec: " 3382*fcf3ce44SJohn Forte "malloc failed"); 3383*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 3384*fcf3ce44SJohn Forte return (-1); 3385*fcf3ce44SJohn Forte } else { 3386*fcf3ce44SJohn Forte bzero(&buf[count], cfl->l_nentry * sizeof (char *)); 3387*fcf3ce44SJohn Forte } 3388*fcf3ce44SJohn Forte 3389*fcf3ce44SJohn Forte /* 3390*fcf3ce44SJohn Forte * allocate each line 3391*fcf3ce44SJohn Forte */ 3392*fcf3ce44SJohn Forte for (i = count; i < cfl->l_nentry + count; i++) { 3393*fcf3ce44SJohn Forte buf[i] = calloc(1, CFG_MAX_BUF); 3394*fcf3ce44SJohn Forte if (buf[i] == NULL) { 3395*fcf3ce44SJohn Forte free(buf); 3396*fcf3ce44SJohn Forte errno = ENOMEM; 3397*fcf3ce44SJohn Forte return (-1); 3398*fcf3ce44SJohn Forte } 3399*fcf3ce44SJohn Forte } 3400*fcf3ce44SJohn Forte 3401*fcf3ce44SJohn Forte if (count == 0) 3402*fcf3ce44SJohn Forte tmplst = (char *)malloc(cfl->l_nentry * CFG_MAX_BUF); 3403*fcf3ce44SJohn Forte else 3404*fcf3ce44SJohn Forte tmplst = (char *)realloc(tmplst, 3405*fcf3ce44SJohn Forte (cfl->l_nentry + count) * CFG_MAX_BUF); 3406*fcf3ce44SJohn Forte if (tmplst == NULL) { 3407*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "cfg_get_srtdsec: " 3408*fcf3ce44SJohn Forte "malloc failed"); 3409*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 3410*fcf3ce44SJohn Forte free(buf); 3411*fcf3ce44SJohn Forte return (-1); 3412*fcf3ce44SJohn Forte } else { 3413*fcf3ce44SJohn Forte bzero(&tmplst[count], cfl->l_nentry * CFG_MAX_BUF); 3414*fcf3ce44SJohn Forte } 3415*fcf3ce44SJohn Forte 3416*fcf3ce44SJohn Forte /* 3417*fcf3ce44SJohn Forte * put the section in tmplst and sort 3418*fcf3ce44SJohn Forte */ 3419*fcf3ce44SJohn Forte p = &tmplst[count]; 3420*fcf3ce44SJohn Forte q = cfl->l_entry; 3421*fcf3ce44SJohn Forte for (i = 0; i < cfl->l_nentry; i++) { 3422*fcf3ce44SJohn Forte bcopy(q, p, cfl->l_esiz[i]); 3423*fcf3ce44SJohn Forte p += CFG_MAX_BUF; 3424*fcf3ce44SJohn Forte q += cfl->l_esiz[i]; 3425*fcf3ce44SJohn Forte } 3426*fcf3ce44SJohn Forte count += cfl->l_nentry; 3427*fcf3ce44SJohn Forte } 3428*fcf3ce44SJohn Forte 3429*fcf3ce44SJohn Forte bzero(sortby.section, CFG_MAX_KEY); 3430*fcf3ce44SJohn Forte bzero(sortby.field, CFG_MAX_KEY); 3431*fcf3ce44SJohn Forte 3432*fcf3ce44SJohn Forte strcpy(sortby.section, section); 3433*fcf3ce44SJohn Forte strcpy(sortby.field, field); 3434*fcf3ce44SJohn Forte sortby.comperror = 0; 3435*fcf3ce44SJohn Forte sortby.offset = cfg_get_item(&chead[0], section, field); 3436*fcf3ce44SJohn Forte 3437*fcf3ce44SJohn Forte qsort(tmplst, count, CFG_MAX_BUF, compare); 3438*fcf3ce44SJohn Forte 3439*fcf3ce44SJohn Forte if (sortby.comperror) { 3440*fcf3ce44SJohn Forte sortby.comperror = 0; 3441*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "cfg_get_srtdsec: " 3442*fcf3ce44SJohn Forte "comparison error"); 3443*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 3444*fcf3ce44SJohn Forte cfg_free_section(&buf, cfl->l_nentry); 3445*fcf3ce44SJohn Forte free(tmplst); 3446*fcf3ce44SJohn Forte *list = NULL; 3447*fcf3ce44SJohn Forte return (-1); 3448*fcf3ce44SJohn Forte } 3449*fcf3ce44SJohn Forte 3450*fcf3ce44SJohn Forte p = tmplst; 3451*fcf3ce44SJohn Forte for (i = 0; i < count; i++) { 3452*fcf3ce44SJohn Forte bcopy(p, buf[i], CFG_MAX_BUF); 3453*fcf3ce44SJohn Forte p += CFG_MAX_BUF; 3454*fcf3ce44SJohn Forte } 3455*fcf3ce44SJohn Forte 3456*fcf3ce44SJohn Forte free(tmplst); 3457*fcf3ce44SJohn Forte *list = buf; 3458*fcf3ce44SJohn Forte return (count); 3459*fcf3ce44SJohn Forte } 3460*fcf3ce44SJohn Forte 3461*fcf3ce44SJohn Forte /* 3462*fcf3ce44SJohn Forte * free an array alloc'd by get_*section 3463*fcf3ce44SJohn Forte * or some other array of size size 3464*fcf3ce44SJohn Forte */ 3465*fcf3ce44SJohn Forte 3466*fcf3ce44SJohn Forte void 3467*fcf3ce44SJohn Forte cfg_free_section(char ***section, int size) 3468*fcf3ce44SJohn Forte { 3469*fcf3ce44SJohn Forte int i; 3470*fcf3ce44SJohn Forte char **secpp = *section; 3471*fcf3ce44SJohn Forte 3472*fcf3ce44SJohn Forte for (i = 0; i < size; i++) { 3473*fcf3ce44SJohn Forte if (secpp[i]) { 3474*fcf3ce44SJohn Forte free(secpp[i]); 3475*fcf3ce44SJohn Forte secpp[i] = NULL; 3476*fcf3ce44SJohn Forte } 3477*fcf3ce44SJohn Forte } 3478*fcf3ce44SJohn Forte if (secpp) { 3479*fcf3ce44SJohn Forte free(secpp); 3480*fcf3ce44SJohn Forte secpp = NULL; 3481*fcf3ce44SJohn Forte } 3482*fcf3ce44SJohn Forte section = NULL; 3483*fcf3ce44SJohn Forte } 3484*fcf3ce44SJohn Forte 3485*fcf3ce44SJohn Forte 3486*fcf3ce44SJohn Forte int 3487*fcf3ce44SJohn Forte cfg_shldskip_vtoc(int fd, const char *loc) 3488*fcf3ce44SJohn Forte { 3489*fcf3ce44SJohn Forte struct vtoc vtoc; 3490*fcf3ce44SJohn Forte struct stat sb; 3491*fcf3ce44SJohn Forte int slice; 3492*fcf3ce44SJohn Forte int rfd; 3493*fcf3ce44SJohn Forte char char_name[PATH_MAX]; 3494*fcf3ce44SJohn Forte char *p; 3495*fcf3ce44SJohn Forte 3496*fcf3ce44SJohn Forte if (fstat(fd, &sb) == -1) { 3497*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "unable to stat config"); 3498*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 3499*fcf3ce44SJohn Forte return (-1); 3500*fcf3ce44SJohn Forte } 3501*fcf3ce44SJohn Forte if (S_ISREG(sb.st_mode)) 3502*fcf3ce44SJohn Forte return (0); 3503*fcf3ce44SJohn Forte 3504*fcf3ce44SJohn Forte if (S_ISCHR(sb.st_mode)) { 3505*fcf3ce44SJohn Forte if ((slice = read_vtoc(fd, &vtoc)) < 0) 3506*fcf3ce44SJohn Forte return (-1); 3507*fcf3ce44SJohn Forte 3508*fcf3ce44SJohn Forte if (vtoc.v_part[slice].p_start < CFG_VTOC_SIZE) 3509*fcf3ce44SJohn Forte return (1); 3510*fcf3ce44SJohn Forte else 3511*fcf3ce44SJohn Forte return (0); 3512*fcf3ce44SJohn Forte } 3513*fcf3ce44SJohn Forte 3514*fcf3ce44SJohn Forte if (S_ISBLK(sb.st_mode)) { 3515*fcf3ce44SJohn Forte p = strstr(loc, "/dsk/"); 3516*fcf3ce44SJohn Forte if (p == NULL) 3517*fcf3ce44SJohn Forte return (-1); 3518*fcf3ce44SJohn Forte strcpy(char_name, loc); 3519*fcf3ce44SJohn Forte char_name[strlen(loc) - strlen(p)] = 0; 3520*fcf3ce44SJohn Forte strcat(char_name, "/rdsk/"); 3521*fcf3ce44SJohn Forte strcat(char_name, p + 5); 3522*fcf3ce44SJohn Forte 3523*fcf3ce44SJohn Forte if ((rfd = open(char_name, O_RDONLY)) < 0) { 3524*fcf3ce44SJohn Forte return (-1); 3525*fcf3ce44SJohn Forte } 3526*fcf3ce44SJohn Forte if ((slice = read_vtoc(rfd, &vtoc)) < 0) { 3527*fcf3ce44SJohn Forte close(rfd); 3528*fcf3ce44SJohn Forte return (-1); 3529*fcf3ce44SJohn Forte } 3530*fcf3ce44SJohn Forte close(rfd); 3531*fcf3ce44SJohn Forte if (vtoc.v_part[slice].p_start < CFG_VTOC_SIZE) 3532*fcf3ce44SJohn Forte return (1); 3533*fcf3ce44SJohn Forte else 3534*fcf3ce44SJohn Forte return (0); 3535*fcf3ce44SJohn Forte } 3536*fcf3ce44SJohn Forte 3537*fcf3ce44SJohn Forte return (-1); 3538*fcf3ce44SJohn Forte } 3539*fcf3ce44SJohn Forte 3540*fcf3ce44SJohn Forte /* 3541*fcf3ce44SJohn Forte * comapares incore header with one on disk 3542*fcf3ce44SJohn Forte * returns 0 if equal, 1 if not, -1 error 3543*fcf3ce44SJohn Forte */ 3544*fcf3ce44SJohn Forte int 3545*fcf3ce44SJohn Forte cfg_hdrcmp(cfp_t *cfp) 3546*fcf3ce44SJohn Forte { 3547*fcf3ce44SJohn Forte cfgheader_t *dskhdr, *memhdr; 3548*fcf3ce44SJohn Forte int rc; 3549*fcf3ce44SJohn Forte 3550*fcf3ce44SJohn Forte if ((dskhdr = calloc(1, sizeof (*dskhdr))) == NULL) { 3551*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "cfg_hdrcmp: No memory"); 3552*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 3553*fcf3ce44SJohn Forte } 3554*fcf3ce44SJohn Forte 3555*fcf3ce44SJohn Forte if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) { 3556*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "cfg_hdrcmp: seek failed"); 3557*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 3558*fcf3ce44SJohn Forte free(dskhdr); 3559*fcf3ce44SJohn Forte return (-1); 3560*fcf3ce44SJohn Forte } 3561*fcf3ce44SJohn Forte 3562*fcf3ce44SJohn Forte rc = (*cfp->cf_pp->read)(cfp, (char *)dskhdr, sizeof (*dskhdr)); 3563*fcf3ce44SJohn Forte if (rc < 0) { 3564*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "cfg_hdrcmp: read failed"); 3565*fcf3ce44SJohn Forte cfg_severity = CFG_ENONFATAL; 3566*fcf3ce44SJohn Forte free(dskhdr); 3567*fcf3ce44SJohn Forte return (-1); 3568*fcf3ce44SJohn Forte } 3569*fcf3ce44SJohn Forte 3570*fcf3ce44SJohn Forte memhdr = cfp->cf_head; 3571*fcf3ce44SJohn Forte 3572*fcf3ce44SJohn Forte if ((memhdr->h_seq1 == dskhdr->h_seq1) && 3573*fcf3ce44SJohn Forte (memhdr->h_seq2 == dskhdr->h_seq2)) 3574*fcf3ce44SJohn Forte rc = 0; 3575*fcf3ce44SJohn Forte else 3576*fcf3ce44SJohn Forte rc = 1; 3577*fcf3ce44SJohn Forte 3578*fcf3ce44SJohn Forte 3579*fcf3ce44SJohn Forte free(dskhdr); 3580*fcf3ce44SJohn Forte return (rc); 3581*fcf3ce44SJohn Forte } 3582