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/vtoc.h> 30*fcf3ce44SJohn Forte #include <sys/wait.h> 31*fcf3ce44SJohn Forte #include <stdio.h> 32*fcf3ce44SJohn Forte #include <sys/mnttab.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 <strings.h> 38*fcf3ce44SJohn Forte #include <stdlib.h> 39*fcf3ce44SJohn Forte #include <unistd.h> 40*fcf3ce44SJohn Forte #include <sys/mman.h> 41*fcf3ce44SJohn Forte 42*fcf3ce44SJohn Forte #include <locale.h> 43*fcf3ce44SJohn Forte #include <langinfo.h> 44*fcf3ce44SJohn Forte #include <libintl.h> 45*fcf3ce44SJohn Forte #include <stdarg.h> 46*fcf3ce44SJohn Forte #include <netdb.h> 47*fcf3ce44SJohn Forte #include <ctype.h> 48*fcf3ce44SJohn Forte #include <sys/stat.h> 49*fcf3ce44SJohn Forte #include <sys/utsname.h> 50*fcf3ce44SJohn Forte 51*fcf3ce44SJohn Forte #include "cfg_impl.h" 52*fcf3ce44SJohn Forte #include "cfg.h" 53*fcf3ce44SJohn Forte #include "cfg_local.h" 54*fcf3ce44SJohn Forte 55*fcf3ce44SJohn Forte #if 0 56*fcf3ce44SJohn Forte #define DEBUG_CFGLIST 57*fcf3ce44SJohn Forte #define DEBUG_CFGLISTRM 58*fcf3ce44SJohn Forte #endif 59*fcf3ce44SJohn Forte 60*fcf3ce44SJohn Forte extern int cfg_severity; 61*fcf3ce44SJohn Forte extern char *cfg_perror_str; 62*fcf3ce44SJohn Forte 63*fcf3ce44SJohn Forte long 64*fcf3ce44SJohn Forte get_bsize(cfp_t *cfp, char *name) 65*fcf3ce44SJohn Forte { 66*fcf3ce44SJohn Forte char char_name[PATH_MAX]; 67*fcf3ce44SJohn Forte char *rest; 68*fcf3ce44SJohn Forte struct vtoc vtoc; 69*fcf3ce44SJohn Forte int slice; 70*fcf3ce44SJohn Forte int fd; 71*fcf3ce44SJohn Forte 72*fcf3ce44SJohn Forte if (strlen(name) >= PATH_MAX - 1) 73*fcf3ce44SJohn Forte return (0); 74*fcf3ce44SJohn Forte 75*fcf3ce44SJohn Forte rest = strstr(name, "/dsk/"); 76*fcf3ce44SJohn Forte if (rest == NULL) { 77*fcf3ce44SJohn Forte if ((rest = strstr(name, "/rdsk/")) == NULL) 78*fcf3ce44SJohn Forte return (0); 79*fcf3ce44SJohn Forte strcpy(char_name, name); 80*fcf3ce44SJohn Forte goto do_open; 81*fcf3ce44SJohn Forte 82*fcf3ce44SJohn Forte } 83*fcf3ce44SJohn Forte strcpy(char_name, name); 84*fcf3ce44SJohn Forte char_name[strlen(name) - strlen(rest)] = 0; 85*fcf3ce44SJohn Forte strcat(char_name, "/rdsk/"); 86*fcf3ce44SJohn Forte strcat(char_name, rest + 5); 87*fcf3ce44SJohn Forte 88*fcf3ce44SJohn Forte do_open: 89*fcf3ce44SJohn Forte fd = open(char_name, O_RDONLY); 90*fcf3ce44SJohn Forte if (fd < 0) 91*fcf3ce44SJohn Forte return (0); 92*fcf3ce44SJohn Forte 93*fcf3ce44SJohn Forte slice = read_vtoc(fd, &vtoc); 94*fcf3ce44SJohn Forte if (slice < 0) { 95*fcf3ce44SJohn Forte (void) close(fd); 96*fcf3ce44SJohn Forte return (0); 97*fcf3ce44SJohn Forte } 98*fcf3ce44SJohn Forte 99*fcf3ce44SJohn Forte (void) close(fd); 100*fcf3ce44SJohn Forte if (vtoc.v_part[slice].p_start < CFG_VTOC_SIZE) 101*fcf3ce44SJohn Forte cfp->cf_flag |= CFG_NOWRVTOC; 102*fcf3ce44SJohn Forte 103*fcf3ce44SJohn Forte return (vtoc.v_part[slice].p_size); 104*fcf3ce44SJohn Forte } 105*fcf3ce44SJohn Forte 106*fcf3ce44SJohn Forte /* 107*fcf3ce44SJohn Forte * round up to the next block size 108*fcf3ce44SJohn Forte */ 109*fcf3ce44SJohn Forte int 110*fcf3ce44SJohn Forte get_block_size(int size) 111*fcf3ce44SJohn Forte { 112*fcf3ce44SJohn Forte int ret; 113*fcf3ce44SJohn Forte 114*fcf3ce44SJohn Forte if (size % CFG_BLOCK_SIZE != 0) 115*fcf3ce44SJohn Forte ret = size + CFG_BLOCK_SIZE - (size % CFG_BLOCK_SIZE); 116*fcf3ce44SJohn Forte else 117*fcf3ce44SJohn Forte ret = size; 118*fcf3ce44SJohn Forte return (ret); 119*fcf3ce44SJohn Forte } 120*fcf3ce44SJohn Forte 121*fcf3ce44SJohn Forte /* 122*fcf3ce44SJohn Forte * get a chunk of mem rounded up to next block size 123*fcf3ce44SJohn Forte */ 124*fcf3ce44SJohn Forte char * 125*fcf3ce44SJohn Forte get_block_buf(int size) 126*fcf3ce44SJohn Forte { 127*fcf3ce44SJohn Forte int blk_size; 128*fcf3ce44SJohn Forte char *blk_buf; 129*fcf3ce44SJohn Forte 130*fcf3ce44SJohn Forte blk_size = get_block_size(size); 131*fcf3ce44SJohn Forte 132*fcf3ce44SJohn Forte if ((blk_buf = (char *)calloc(blk_size, sizeof (char))) == NULL) { 133*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 134*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", strerror(errno)); 135*fcf3ce44SJohn Forte return (NULL); 136*fcf3ce44SJohn Forte } 137*fcf3ce44SJohn Forte return (blk_buf); 138*fcf3ce44SJohn Forte } 139*fcf3ce44SJohn Forte 140*fcf3ce44SJohn Forte void 141*fcf3ce44SJohn Forte free_block_buf(char *buf) 142*fcf3ce44SJohn Forte { 143*fcf3ce44SJohn Forte if (buf) 144*fcf3ce44SJohn Forte free(buf); 145*fcf3ce44SJohn Forte } 146*fcf3ce44SJohn Forte 147*fcf3ce44SJohn Forte void 148*fcf3ce44SJohn Forte localcf_close(cfp_t *cfp) 149*fcf3ce44SJohn Forte { 150*fcf3ce44SJohn Forte fsync(cfp->cf_fd); 151*fcf3ce44SJohn Forte cfp_unlock(cfp); 152*fcf3ce44SJohn Forte close(cfp->cf_fd); 153*fcf3ce44SJohn Forte } 154*fcf3ce44SJohn Forte 155*fcf3ce44SJohn Forte 156*fcf3ce44SJohn Forte /* 157*fcf3ce44SJohn Forte * cfg_open 158*fcf3ce44SJohn Forte * Open the current configuration file 159*fcf3ce44SJohn Forte * Sets file descriptor in cfp->cf_fd for use by other routines 160*fcf3ce44SJohn Forte */ 161*fcf3ce44SJohn Forte cfp_t * 162*fcf3ce44SJohn Forte localcf_open(cfp_t *cfp, char *name) 163*fcf3ce44SJohn Forte { 164*fcf3ce44SJohn Forte struct stat sb; 165*fcf3ce44SJohn Forte int rc; 166*fcf3ce44SJohn Forte 167*fcf3ce44SJohn Forte 168*fcf3ce44SJohn Forte if (name == NULL) { 169*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 170*fcf3ce44SJohn Forte "cfg_open: unable to open configuration location"); 171*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 172*fcf3ce44SJohn Forte return (NULL); 173*fcf3ce44SJohn Forte } 174*fcf3ce44SJohn Forte 175*fcf3ce44SJohn Forte cfp->cf_fd = open(name, O_RDWR|O_CREAT|O_DSYNC|O_RSYNC, 0640); 176*fcf3ce44SJohn Forte if (cfp->cf_fd == -1) { 177*fcf3ce44SJohn Forte if ((cfp->cf_fd = open(name, O_RDONLY, 0640)) == -1) { 178*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 179*fcf3ce44SJohn Forte "cfg_open: unable to open configuration location"); 180*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 181*fcf3ce44SJohn Forte return (NULL); 182*fcf3ce44SJohn Forte } 183*fcf3ce44SJohn Forte cfp->cf_flag |= CFG_RDONLY; 184*fcf3ce44SJohn Forte } 185*fcf3ce44SJohn Forte 186*fcf3ce44SJohn Forte if (fstat(cfp->cf_fd, &sb) == -1) { 187*fcf3ce44SJohn Forte close(cfp->cf_fd); 188*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 189*fcf3ce44SJohn Forte "cfg_open: unable to stat configuration location"); 190*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 191*fcf3ce44SJohn Forte return (NULL); 192*fcf3ce44SJohn Forte } 193*fcf3ce44SJohn Forte 194*fcf3ce44SJohn Forte 195*fcf3ce44SJohn Forte if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { 196*fcf3ce44SJohn Forte cfp->cf_size = get_bsize(cfp, name); 197*fcf3ce44SJohn Forte 198*fcf3ce44SJohn Forte /* skip the vtoc if necessary */ 199*fcf3ce44SJohn Forte if (cfp->cf_flag & CFG_NOWRVTOC) { 200*fcf3ce44SJohn Forte do { 201*fcf3ce44SJohn Forte rc = lseek(cfp->cf_fd, CFG_VTOC_SKIP, SEEK_SET); 202*fcf3ce44SJohn Forte } while (rc == -1 && errno == EINTR); 203*fcf3ce44SJohn Forte 204*fcf3ce44SJohn Forte if (rc == -1) { 205*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", 206*fcf3ce44SJohn Forte strerror(errno)); 207*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 208*fcf3ce44SJohn Forte close(cfp->cf_fd); 209*fcf3ce44SJohn Forte return (NULL); 210*fcf3ce44SJohn Forte } 211*fcf3ce44SJohn Forte } 212*fcf3ce44SJohn Forte 213*fcf3ce44SJohn Forte } else if (S_ISREG(sb.st_mode)) { 214*fcf3ce44SJohn Forte cfp->cf_flag |= CFG_FILE; 215*fcf3ce44SJohn Forte cfp->cf_size = FBA_NUM(FBA_SIZE(1) - 1 + sb.st_size); 216*fcf3ce44SJohn Forte } else { 217*fcf3ce44SJohn Forte cfg_perror_str = dgettext("cfg", "cfg_open: unknown file type"); 218*fcf3ce44SJohn Forte cfg_severity = CFG_EFATAL; 219*fcf3ce44SJohn Forte close(cfp->cf_fd); 220*fcf3ce44SJohn Forte cfp->cf_fd = NULL; 221*fcf3ce44SJohn Forte return (NULL); 222*fcf3ce44SJohn Forte } 223*fcf3ce44SJohn Forte return (cfp); 224*fcf3ce44SJohn Forte } 225*fcf3ce44SJohn Forte 226*fcf3ce44SJohn Forte int 227*fcf3ce44SJohn Forte localcf_seekblk(cfp_t *cfp, int off, int mode) 228*fcf3ce44SJohn Forte { 229*fcf3ce44SJohn Forte int rc; 230*fcf3ce44SJohn Forte 231*fcf3ce44SJohn Forte do { 232*fcf3ce44SJohn Forte rc = lseek(cfp->cf_fd, off, mode); 233*fcf3ce44SJohn Forte } while (rc == -1 && errno == EINTR); 234*fcf3ce44SJohn Forte 235*fcf3ce44SJohn Forte return (rc); 236*fcf3ce44SJohn Forte } 237*fcf3ce44SJohn Forte 238*fcf3ce44SJohn Forte int 239*fcf3ce44SJohn Forte localcf_readblk(cfp_t *cfp, void *buf, int size) 240*fcf3ce44SJohn Forte { 241*fcf3ce44SJohn Forte int rc; 242*fcf3ce44SJohn Forte 243*fcf3ce44SJohn Forte do { 244*fcf3ce44SJohn Forte rc = read(cfp->cf_fd, buf, size); 245*fcf3ce44SJohn Forte } while (rc == -1 && errno == EINTR); 246*fcf3ce44SJohn Forte 247*fcf3ce44SJohn Forte return (rc); 248*fcf3ce44SJohn Forte } 249*fcf3ce44SJohn Forte 250*fcf3ce44SJohn Forte int 251*fcf3ce44SJohn Forte localcf_writeblk(cfp_t *cfp, void *buf, int size) 252*fcf3ce44SJohn Forte { 253*fcf3ce44SJohn Forte int rc; 254*fcf3ce44SJohn Forte 255*fcf3ce44SJohn Forte do { 256*fcf3ce44SJohn Forte rc = write(cfp->cf_fd, buf, size); 257*fcf3ce44SJohn Forte } while (rc == -1 && errno == EINTR); 258*fcf3ce44SJohn Forte 259*fcf3ce44SJohn Forte return (rc); 260*fcf3ce44SJohn Forte } 261*fcf3ce44SJohn Forte 262*fcf3ce44SJohn Forte int 263*fcf3ce44SJohn Forte localcf_seek(cfp_t *cfp, int off, int mode) 264*fcf3ce44SJohn Forte { 265*fcf3ce44SJohn Forte int rc; 266*fcf3ce44SJohn Forte int offset; 267*fcf3ce44SJohn Forte 268*fcf3ce44SJohn Forte offset = get_block_size(off); 269*fcf3ce44SJohn Forte 270*fcf3ce44SJohn Forte if ((mode == SEEK_SET) && (cfp->cf_flag & CFG_NOWRVTOC)) { 271*fcf3ce44SJohn Forte offset += CFG_VTOC_SKIP; 272*fcf3ce44SJohn Forte } 273*fcf3ce44SJohn Forte 274*fcf3ce44SJohn Forte do { 275*fcf3ce44SJohn Forte rc = lseek(cfp->cf_fd, offset, mode); 276*fcf3ce44SJohn Forte } while (rc == -1 && errno == EINTR); 277*fcf3ce44SJohn Forte 278*fcf3ce44SJohn Forte return (rc); 279*fcf3ce44SJohn Forte } 280*fcf3ce44SJohn Forte 281*fcf3ce44SJohn Forte int 282*fcf3ce44SJohn Forte localcf_read(cfp_t *cfp, void *buf, int size) 283*fcf3ce44SJohn Forte { 284*fcf3ce44SJohn Forte int rc; 285*fcf3ce44SJohn Forte int blk_size; 286*fcf3ce44SJohn Forte char *blk_buf; 287*fcf3ce44SJohn Forte 288*fcf3ce44SJohn Forte blk_size = get_block_size(size); 289*fcf3ce44SJohn Forte if ((blk_buf = get_block_buf(size)) == NULL) 290*fcf3ce44SJohn Forte return (-1); 291*fcf3ce44SJohn Forte 292*fcf3ce44SJohn Forte do { 293*fcf3ce44SJohn Forte rc = read(cfp->cf_fd, blk_buf, blk_size); 294*fcf3ce44SJohn Forte } while (rc == -1 && errno == EINTR); 295*fcf3ce44SJohn Forte 296*fcf3ce44SJohn Forte bcopy(blk_buf, buf, size); 297*fcf3ce44SJohn Forte free_block_buf(blk_buf); 298*fcf3ce44SJohn Forte 299*fcf3ce44SJohn Forte return (rc); 300*fcf3ce44SJohn Forte } 301*fcf3ce44SJohn Forte 302*fcf3ce44SJohn Forte int 303*fcf3ce44SJohn Forte localcf_write(cfp_t *cfp, void *buf, int size) 304*fcf3ce44SJohn Forte { 305*fcf3ce44SJohn Forte int rc; 306*fcf3ce44SJohn Forte int blk_size; 307*fcf3ce44SJohn Forte char *blk_buf; 308*fcf3ce44SJohn Forte 309*fcf3ce44SJohn Forte blk_size = get_block_size(size); 310*fcf3ce44SJohn Forte if ((blk_buf = get_block_buf(size)) == NULL) 311*fcf3ce44SJohn Forte return (-1); 312*fcf3ce44SJohn Forte 313*fcf3ce44SJohn Forte bcopy(buf, blk_buf, size); 314*fcf3ce44SJohn Forte 315*fcf3ce44SJohn Forte do { 316*fcf3ce44SJohn Forte rc = write(cfp->cf_fd, blk_buf, blk_size); 317*fcf3ce44SJohn Forte } while (rc == -1 && errno == EINTR); 318*fcf3ce44SJohn Forte 319*fcf3ce44SJohn Forte free_block_buf(blk_buf); 320*fcf3ce44SJohn Forte 321*fcf3ce44SJohn Forte return (rc); 322*fcf3ce44SJohn Forte } 323*fcf3ce44SJohn Forte /* 324*fcf3ce44SJohn Forte * Routines which operate on internal version of configuration 325*fcf3ce44SJohn Forte */ 326*fcf3ce44SJohn Forte 327*fcf3ce44SJohn Forte /* 328*fcf3ce44SJohn Forte * Add entry to end of configuration section 329*fcf3ce44SJohn Forte */ 330*fcf3ce44SJohn Forte 331*fcf3ce44SJohn Forte int 332*fcf3ce44SJohn Forte addcfline(cfp_t *cfp, char *line, int table_index) 333*fcf3ce44SJohn Forte { 334*fcf3ce44SJohn Forte int len = strlen(line)+1; 335*fcf3ce44SJohn Forte int newsize = DEFAULT_ENTRY_SIZE / 2; 336*fcf3ce44SJohn Forte cfgheader_t *hd; 337*fcf3ce44SJohn Forte cfglist_t *cfl; 338*fcf3ce44SJohn Forte char *q; 339*fcf3ce44SJohn Forte 340*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 341*fcf3ce44SJohn Forte fprintf(stderr, "addcfline: pre l_size %d h_cfgsizes[%d]" 342*fcf3ce44SJohn Forte " %d l_free %u adding len %d\n", 343*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[table_index].l_size, table_index, 344*fcf3ce44SJohn Forte cfp->cf_head->h_cfgsizes[table_index], 345*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[table_index].l_free, len); 346*fcf3ce44SJohn Forte #endif 347*fcf3ce44SJohn Forte 348*fcf3ce44SJohn Forte hd = cfp->cf_head; 349*fcf3ce44SJohn Forte cfl = &cfp->cf_head->h_cfgs[table_index]; 350*fcf3ce44SJohn Forte if (cfl->l_free < len) { 351*fcf3ce44SJohn Forte 352*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 353*fcf3ce44SJohn Forte fprintf(stderr, "resizing l_entry from %d to %d\n", 354*fcf3ce44SJohn Forte cfl->l_size + cfl->l_free, cfl->l_size + 355*fcf3ce44SJohn Forte cfl->l_free + newsize); 356*fcf3ce44SJohn Forte #endif 357*fcf3ce44SJohn Forte cfl->l_entry = (char *)realloc(cfl->l_entry, (cfl->l_size + 358*fcf3ce44SJohn Forte cfl->l_free + newsize) * sizeof (char)); 359*fcf3ce44SJohn Forte if (cfl->l_entry == NULL) { 360*fcf3ce44SJohn Forte errno = ENOMEM; 361*fcf3ce44SJohn Forte return (-1); 362*fcf3ce44SJohn Forte } 363*fcf3ce44SJohn Forte cfl->l_free += newsize; 364*fcf3ce44SJohn Forte 365*fcf3ce44SJohn Forte } 366*fcf3ce44SJohn Forte cfl->l_free -= len; 367*fcf3ce44SJohn Forte 368*fcf3ce44SJohn Forte /* out of list slots, get some more */ 369*fcf3ce44SJohn Forte if (cfl->l_nentry % DEFAULT_NENTRIES == 0) { 370*fcf3ce44SJohn Forte /* 371*fcf3ce44SJohn Forte * first, figure out how much bigger, than realloc 372*fcf3ce44SJohn Forte */ 373*fcf3ce44SJohn Forte 374*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 375*fcf3ce44SJohn Forte fprintf(stderr, 376*fcf3ce44SJohn Forte "list %d getting more nentries, I have %d\n", 377*fcf3ce44SJohn Forte table_index, cfl->l_nentry); 378*fcf3ce44SJohn Forte #endif 379*fcf3ce44SJohn Forte cfl->l_esiz = (int *) 380*fcf3ce44SJohn Forte realloc(cfl->l_esiz, (cfl->l_nentry + DEFAULT_NENTRIES) * 381*fcf3ce44SJohn Forte sizeof (int)); 382*fcf3ce44SJohn Forte if (cfl->l_esiz == NULL) { 383*fcf3ce44SJohn Forte errno = ENOMEM; 384*fcf3ce44SJohn Forte return (-1); 385*fcf3ce44SJohn Forte } 386*fcf3ce44SJohn Forte } 387*fcf3ce44SJohn Forte 388*fcf3ce44SJohn Forte 389*fcf3ce44SJohn Forte cfl->l_esiz[cfl->l_nentry] = len; 390*fcf3ce44SJohn Forte cfl->l_nentry++; 391*fcf3ce44SJohn Forte 392*fcf3ce44SJohn Forte /* add line to end of list */ 393*fcf3ce44SJohn Forte q = cfl->l_entry + cfl->l_size; 394*fcf3ce44SJohn Forte 395*fcf3ce44SJohn Forte strcpy(q, line); 396*fcf3ce44SJohn Forte q += len; 397*fcf3ce44SJohn Forte 398*fcf3ce44SJohn Forte /* set sizes */ 399*fcf3ce44SJohn Forte hd->h_cfgs[table_index].l_size += len; 400*fcf3ce44SJohn Forte hd->h_cfgsizes[table_index] = cfl->l_size; 401*fcf3ce44SJohn Forte cfp->cf_head->h_csize += len; 402*fcf3ce44SJohn Forte 403*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 404*fcf3ce44SJohn Forte fprintf(stderr, "addcfline: post l_size %d h_cfgsizes[%d]" 405*fcf3ce44SJohn Forte " %d l_free %u\n h_csize %d\n", 406*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[table_index].l_size, 407*fcf3ce44SJohn Forte table_index, cfp->cf_head->h_cfgsizes[table_index], 408*fcf3ce44SJohn Forte cfp->cf_head->h_cfgs[table_index].l_free, cfp->cf_head->h_csize); 409*fcf3ce44SJohn Forte #endif 410*fcf3ce44SJohn Forte 411*fcf3ce44SJohn Forte return (1); 412*fcf3ce44SJohn Forte } 413*fcf3ce44SJohn Forte 414*fcf3ce44SJohn Forte /* 415*fcf3ce44SJohn Forte * remove entry from configuration section 416*fcf3ce44SJohn Forte */ 417*fcf3ce44SJohn Forte int 418*fcf3ce44SJohn Forte remcfline(cfp_t *cfp, int table_offset, int setnum) 419*fcf3ce44SJohn Forte { 420*fcf3ce44SJohn Forte cfgheader_t *ch; 421*fcf3ce44SJohn Forte char *p, *q; 422*fcf3ce44SJohn Forte int len; 423*fcf3ce44SJohn Forte int copylen; 424*fcf3ce44SJohn Forte int i; 425*fcf3ce44SJohn Forte cfglist_t *cfl; 426*fcf3ce44SJohn Forte ch = cfp->cf_head; 427*fcf3ce44SJohn Forte 428*fcf3ce44SJohn Forte cfl = &cfp->cf_head->h_cfgs[table_offset]; 429*fcf3ce44SJohn Forte 430*fcf3ce44SJohn Forte q = cfl->l_entry; 431*fcf3ce44SJohn Forte 432*fcf3ce44SJohn Forte if (cfl->l_size == 0) { 433*fcf3ce44SJohn Forte /* list is empty */ 434*fcf3ce44SJohn Forte return (-1); 435*fcf3ce44SJohn Forte } 436*fcf3ce44SJohn Forte 437*fcf3ce44SJohn Forte if (!q) { /* somethings wrong here */ 438*fcf3ce44SJohn Forte return (-1); 439*fcf3ce44SJohn Forte } 440*fcf3ce44SJohn Forte 441*fcf3ce44SJohn Forte 442*fcf3ce44SJohn Forte for (i = 1; i < setnum; i++) { 443*fcf3ce44SJohn Forte q += cfl->l_esiz[i - 1]; 444*fcf3ce44SJohn Forte if (i >= cfl->l_nentry) { /* end of list */ 445*fcf3ce44SJohn Forte return (-1); 446*fcf3ce44SJohn Forte } 447*fcf3ce44SJohn Forte } 448*fcf3ce44SJohn Forte 449*fcf3ce44SJohn Forte if (q >= cfl->l_entry + cfl->l_size) 450*fcf3ce44SJohn Forte return (-1); 451*fcf3ce44SJohn Forte 452*fcf3ce44SJohn Forte len = cfl->l_esiz[i - 1]; 453*fcf3ce44SJohn Forte 454*fcf3ce44SJohn Forte 455*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLISTRM 456*fcf3ce44SJohn Forte fprintf(stderr, "remcfline: pre: l_size %d h_cfgsizes[%d] %d free %d" 457*fcf3ce44SJohn Forte " removing len %d\n", 458*fcf3ce44SJohn Forte ch->h_cfgs[table_offset].l_size, table_offset, 459*fcf3ce44SJohn Forte ch->h_cfgsizes[table_offset], 460*fcf3ce44SJohn Forte ch->h_cfgs[table_offset].l_free, len); 461*fcf3ce44SJohn Forte #endif 462*fcf3ce44SJohn Forte 463*fcf3ce44SJohn Forte p = q + len; /* next string */ 464*fcf3ce44SJohn Forte 465*fcf3ce44SJohn Forte if (!(p >= cfl->l_entry + cfl->l_size)) { 466*fcf3ce44SJohn Forte /* if we didn't delete the last string in list */ 467*fcf3ce44SJohn Forte /* LINTED possible overflow */ 468*fcf3ce44SJohn Forte copylen = cfl->l_entry + cfl->l_size - p; 469*fcf3ce44SJohn Forte bcopy(p, q, copylen); 470*fcf3ce44SJohn Forte copylen = (cfl->l_nentry - i) * sizeof (int); 471*fcf3ce44SJohn Forte bcopy(&cfl->l_esiz[i], &cfl->l_esiz[i - 1], copylen); 472*fcf3ce44SJohn Forte } 473*fcf3ce44SJohn Forte 474*fcf3ce44SJohn Forte /* decrement the number of sets in this list */ 475*fcf3ce44SJohn Forte cfl->l_nentry--; 476*fcf3ce44SJohn Forte /* not really necessary, but.. */ 477*fcf3ce44SJohn Forte cfl->l_esiz[cfl->l_nentry] = 0; 478*fcf3ce44SJohn Forte 479*fcf3ce44SJohn Forte cfl->l_size -= len; 480*fcf3ce44SJohn Forte cfl->l_free += len; 481*fcf3ce44SJohn Forte 482*fcf3ce44SJohn Forte p = cfl->l_entry + cfl->l_size; 483*fcf3ce44SJohn Forte bzero(p, cfl->l_free); 484*fcf3ce44SJohn Forte 485*fcf3ce44SJohn Forte ch->h_cfgsizes[table_offset] = cfl->l_size; 486*fcf3ce44SJohn Forte ch->h_csize -= len; 487*fcf3ce44SJohn Forte 488*fcf3ce44SJohn Forte 489*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 490*fcf3ce44SJohn Forte fprintf(stderr, 491*fcf3ce44SJohn Forte "remcfline: post: l_size %d h_cfgsizes[%d] %d free %d\n ", 492*fcf3ce44SJohn Forte ch->h_cfgs[table_offset].l_size, table_offset, 493*fcf3ce44SJohn Forte ch->h_cfgsizes[table_offset], ch->h_cfgs[table_offset].l_free); 494*fcf3ce44SJohn Forte #endif 495*fcf3ce44SJohn Forte 496*fcf3ce44SJohn Forte return (0); 497*fcf3ce44SJohn Forte 498*fcf3ce44SJohn Forte } 499*fcf3ce44SJohn Forte /* 500*fcf3ce44SJohn Forte * Read entry from configuration section 501*fcf3ce44SJohn Forte */ 502*fcf3ce44SJohn Forte char * 503*fcf3ce44SJohn Forte readcfline(cfp_t *cfp, char *buf, int table_offset, int num) 504*fcf3ce44SJohn Forte { 505*fcf3ce44SJohn Forte 506*fcf3ce44SJohn Forte char *q; 507*fcf3ce44SJohn Forte int i; 508*fcf3ce44SJohn Forte cfgheader_t *ch; 509*fcf3ce44SJohn Forte cfglist_t *cfl; 510*fcf3ce44SJohn Forte 511*fcf3ce44SJohn Forte /* this means they couldn't even find it in the parser tree */ 512*fcf3ce44SJohn Forte if (table_offset < 0) 513*fcf3ce44SJohn Forte return (NULL); 514*fcf3ce44SJohn Forte 515*fcf3ce44SJohn Forte ch = cfp->cf_head; 516*fcf3ce44SJohn Forte cfl = &ch->h_cfgs[table_offset]; 517*fcf3ce44SJohn Forte 518*fcf3ce44SJohn Forte q = cfl->l_entry; 519*fcf3ce44SJohn Forte 520*fcf3ce44SJohn Forte for (i = 1; i < num; i++) { 521*fcf3ce44SJohn Forte q += cfl->l_esiz[i - 1]; 522*fcf3ce44SJohn Forte if (i >= cfl->l_nentry) /* end of list */ 523*fcf3ce44SJohn Forte return (NULL); 524*fcf3ce44SJohn Forte } 525*fcf3ce44SJohn Forte 526*fcf3ce44SJohn Forte if (q >= cfl->l_entry + cfl->l_size) 527*fcf3ce44SJohn Forte return (NULL); 528*fcf3ce44SJohn Forte strcpy(buf, q); 529*fcf3ce44SJohn Forte return (q); 530*fcf3ce44SJohn Forte } 531*fcf3ce44SJohn Forte 532*fcf3ce44SJohn Forte 533*fcf3ce44SJohn Forte /* 534*fcf3ce44SJohn Forte * overwrite from current position with new value 535*fcf3ce44SJohn Forte */ 536*fcf3ce44SJohn Forte int 537*fcf3ce44SJohn Forte replacecfline(cfp_t *cfp, char *line, int table_offset, int num) 538*fcf3ce44SJohn Forte { 539*fcf3ce44SJohn Forte /* 540*fcf3ce44SJohn Forte * take a table offset and a num to replace 541*fcf3ce44SJohn Forte * index in, bump the list up, leaving a hole big 542*fcf3ce44SJohn Forte * enough for the new string, or bcopying the rest of the list 543*fcf3ce44SJohn Forte * down only leaving a hole big enough. 544*fcf3ce44SJohn Forte * make sure not to overflow the 545*fcf3ce44SJohn Forte * allocated list size. 546*fcf3ce44SJohn Forte */ 547*fcf3ce44SJohn Forte cfgheader_t *ch; 548*fcf3ce44SJohn Forte cfglist_t *cfl; 549*fcf3ce44SJohn Forte char *p, *q; 550*fcf3ce44SJohn Forte int len = strlen(line) + 1; 551*fcf3ce44SJohn Forte int diff = 0; 552*fcf3ce44SJohn Forte int i; 553*fcf3ce44SJohn Forte int newsize = DEFAULT_ENTRY_SIZE / 2; 554*fcf3ce44SJohn Forte 555*fcf3ce44SJohn Forte 556*fcf3ce44SJohn Forte ch = cfp->cf_head; 557*fcf3ce44SJohn Forte cfl = &ch->h_cfgs[table_offset]; 558*fcf3ce44SJohn Forte 559*fcf3ce44SJohn Forte q = cfl->l_entry; 560*fcf3ce44SJohn Forte for (i = 1; i < num; i++) { 561*fcf3ce44SJohn Forte q += cfl->l_esiz[i - 1]; 562*fcf3ce44SJohn Forte if (i >= cfl->l_nentry) /* end of list */ 563*fcf3ce44SJohn Forte return (-1); 564*fcf3ce44SJohn Forte } 565*fcf3ce44SJohn Forte diff = len - cfl->l_esiz[i - 1]; 566*fcf3ce44SJohn Forte /* check for > 0, comparing uint to int */ 567*fcf3ce44SJohn Forte if ((diff > 0) && (diff > cfl->l_free)) { 568*fcf3ce44SJohn Forte /* 569*fcf3ce44SJohn Forte * we are going to overflow, get more mem, but only 570*fcf3ce44SJohn Forte * 1/2 as much as initial calloc, we don't need to be greedy 571*fcf3ce44SJohn Forte */ 572*fcf3ce44SJohn Forte #ifdef DEBUG_CFGLIST 573*fcf3ce44SJohn Forte fprintf(stderr, 574*fcf3ce44SJohn Forte "resizing at replacecfline from %d to %d \n", 575*fcf3ce44SJohn Forte cfl->l_size + cfl->l_free, cfl->l_size + 576*fcf3ce44SJohn Forte cfl->l_free + newsize); 577*fcf3ce44SJohn Forte #endif 578*fcf3ce44SJohn Forte cfl->l_entry = (char *)realloc(cfl->l_entry, 579*fcf3ce44SJohn Forte (cfl->l_size + cfl->l_free + newsize) * sizeof (char)); 580*fcf3ce44SJohn Forte if (cfl->l_entry == NULL) { 581*fcf3ce44SJohn Forte errno = ENOMEM; 582*fcf3ce44SJohn Forte return (-1); 583*fcf3ce44SJohn Forte } 584*fcf3ce44SJohn Forte cfl->l_free += (DEFAULT_ENTRY_SIZE / 2); 585*fcf3ce44SJohn Forte 586*fcf3ce44SJohn Forte /* re-find q, we could have a whole new chunk of memory here */ 587*fcf3ce44SJohn Forte q = cfl->l_entry; 588*fcf3ce44SJohn Forte for (i = 1; i < num; i++) { 589*fcf3ce44SJohn Forte q += cfl->l_esiz[i - 1]; 590*fcf3ce44SJohn Forte if (i >= cfl->l_nentry) /* end of list */ 591*fcf3ce44SJohn Forte return (-1); 592*fcf3ce44SJohn Forte } 593*fcf3ce44SJohn Forte } 594*fcf3ce44SJohn Forte 595*fcf3ce44SJohn Forte p = q + cfl->l_esiz[i - 1]; /* next string */ 596*fcf3ce44SJohn Forte cfl->l_esiz[i - 1] += diff; /* the new entry size */ 597*fcf3ce44SJohn Forte if (diff != 0) { /* move stuff over/back for correct fit */ 598*fcf3ce44SJohn Forte /* LINTED possible overflow */ 599*fcf3ce44SJohn Forte bcopy(p, p + diff, (cfl->l_entry + cfl->l_size - p)); 600*fcf3ce44SJohn Forte cfl->l_free -= diff; /* 0 - (-1) = 1 */ 601*fcf3ce44SJohn Forte cfl->l_size += diff; 602*fcf3ce44SJohn Forte 603*fcf3ce44SJohn Forte /* total of all h_cfgs[n].l_entry */ 604*fcf3ce44SJohn Forte cfp->cf_head->h_csize += diff; 605*fcf3ce44SJohn Forte cfp->cf_head->h_cfgsizes[table_offset] = cfl->l_size; /* disk */ 606*fcf3ce44SJohn Forte bzero((cfl->l_entry + cfl->l_size), cfl->l_free); 607*fcf3ce44SJohn Forte } 608*fcf3ce44SJohn Forte 609*fcf3ce44SJohn Forte strcpy(q, line); 610*fcf3ce44SJohn Forte return (1); 611*fcf3ce44SJohn Forte 612*fcf3ce44SJohn Forte } 613*fcf3ce44SJohn Forte 614*fcf3ce44SJohn Forte static cfg_io_t _cfg_raw_io_def = { 615*fcf3ce44SJohn Forte NULL, 616*fcf3ce44SJohn Forte "Local", 617*fcf3ce44SJohn Forte localcf_open, 618*fcf3ce44SJohn Forte localcf_close, 619*fcf3ce44SJohn Forte localcf_seek, 620*fcf3ce44SJohn Forte localcf_read, 621*fcf3ce44SJohn Forte localcf_write, 622*fcf3ce44SJohn Forte readcfline, 623*fcf3ce44SJohn Forte addcfline, 624*fcf3ce44SJohn Forte remcfline, 625*fcf3ce44SJohn Forte replacecfline, 626*fcf3ce44SJohn Forte 627*fcf3ce44SJohn Forte }; 628*fcf3ce44SJohn Forte 629*fcf3ce44SJohn Forte static cfg_io_t _cfg_block_io_def = { 630*fcf3ce44SJohn Forte NULL, 631*fcf3ce44SJohn Forte "Local", 632*fcf3ce44SJohn Forte localcf_open, 633*fcf3ce44SJohn Forte localcf_close, 634*fcf3ce44SJohn Forte localcf_seekblk, 635*fcf3ce44SJohn Forte localcf_readblk, 636*fcf3ce44SJohn Forte localcf_writeblk, 637*fcf3ce44SJohn Forte readcfline, 638*fcf3ce44SJohn Forte addcfline, 639*fcf3ce44SJohn Forte remcfline, 640*fcf3ce44SJohn Forte replacecfline, 641*fcf3ce44SJohn Forte }; 642*fcf3ce44SJohn Forte 643*fcf3ce44SJohn Forte cfg_io_t * 644*fcf3ce44SJohn Forte cfg_raw_io_provider(void) 645*fcf3ce44SJohn Forte { 646*fcf3ce44SJohn Forte return (&_cfg_raw_io_def); 647*fcf3ce44SJohn Forte } 648*fcf3ce44SJohn Forte 649*fcf3ce44SJohn Forte cfg_io_t * 650*fcf3ce44SJohn Forte cfg_block_io_provider(void) 651*fcf3ce44SJohn Forte { 652*fcf3ce44SJohn Forte return (&_cfg_block_io_def); 653*fcf3ce44SJohn Forte } 654