1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate #include <sys/mman.h> 29*0Sstevel@tonic-gate #include <sys/types.h> 30*0Sstevel@tonic-gate #include <fcntl.h> 31*0Sstevel@tonic-gate #include <unistd.h> 32*0Sstevel@tonic-gate #include <errno.h> 33*0Sstevel@tonic-gate #include <stdio.h> 34*0Sstevel@tonic-gate #include <string.h> 35*0Sstevel@tonic-gate #include "rtc.h" 36*0Sstevel@tonic-gate #include "_crle.h" 37*0Sstevel@tonic-gate #include "msg.h" 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate #define MAXNBKTS 10007 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gate static const int hashsize[] = { 44*0Sstevel@tonic-gate 3, 7, 13, 31, 53, 67, 83, 97, 45*0Sstevel@tonic-gate 101, 151, 211, 251, 307, 353, 401, 457, 503, 46*0Sstevel@tonic-gate 557, 601, 653, 701, 751, 809, 859, 907, 953, 47*0Sstevel@tonic-gate 1009, 1103, 1201, 1301, 1409, 1511, 1601, 1709, 1801, 48*0Sstevel@tonic-gate 1901, 2003, 2111, 2203, 2309, 2411, 2503, 2609, 2707, 49*0Sstevel@tonic-gate 2801, 2903, 3001, 3109, 3203, 3301, 3407, 3511, 3607, 50*0Sstevel@tonic-gate 3701, 3803, 3907, 4001, 5003, 6101, 7001, 8101, 9001, 51*0Sstevel@tonic-gate MAXNBKTS 52*0Sstevel@tonic-gate }; 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate /* 55*0Sstevel@tonic-gate * Generate a configuration file from the internal configuration information. 56*0Sstevel@tonic-gate * (very link-editor like). 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate genconfig(Crle_desc * crle) 59*0Sstevel@tonic-gate { 60*0Sstevel@tonic-gate int ndx, bkt; 61*0Sstevel@tonic-gate size_t size, hashoff = 0, stroff = 0, objoff = 0; 62*0Sstevel@tonic-gate size_t diroff = 0, fileoff = 0, envoff = 0; 63*0Sstevel@tonic-gate size_t fltroff = 0, flteoff = 0; 64*0Sstevel@tonic-gate Addr addr; 65*0Sstevel@tonic-gate Rtc_head *head; 66*0Sstevel@tonic-gate Word *hashtbl, * hashbkt, * hashchn, hashbkts = 0; 67*0Sstevel@tonic-gate char *strtbl, *_strtbl; 68*0Sstevel@tonic-gate Rtc_obj *objtbl; 69*0Sstevel@tonic-gate Rtc_dir *dirtbl; 70*0Sstevel@tonic-gate Rtc_file *filetbl; 71*0Sstevel@tonic-gate Rtc_env *envtbl; 72*0Sstevel@tonic-gate Rtc_fltr *fltrtbl; 73*0Sstevel@tonic-gate Rtc_flte *fltetbl, * _fltetbl; 74*0Sstevel@tonic-gate Hash_tbl *stbl = crle->c_strtbl; 75*0Sstevel@tonic-gate Hash_ent *ent; 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate /* 78*0Sstevel@tonic-gate * Establish the size of the configuration file. 79*0Sstevel@tonic-gate */ 80*0Sstevel@tonic-gate size = S_ROUND(sizeof (Rtc_head), sizeof (Word)); 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate if (crle->c_hashstrnum) { 83*0Sstevel@tonic-gate hashoff = size; 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate /* 86*0Sstevel@tonic-gate * Increment the hash string number to account for an initial 87*0Sstevel@tonic-gate * null entry. Indexes start at 1 to simplify hash lookup. 88*0Sstevel@tonic-gate */ 89*0Sstevel@tonic-gate crle->c_hashstrnum++; 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate /* 92*0Sstevel@tonic-gate * Determine the hash table size. Establish the number of 93*0Sstevel@tonic-gate * buckets from the number of strings, the number of chains is 94*0Sstevel@tonic-gate * equivalent to the number of objects, and two entries for the 95*0Sstevel@tonic-gate * nbucket and nchain entries. 96*0Sstevel@tonic-gate */ 97*0Sstevel@tonic-gate for (ndx = 0; ndx < (sizeof (hashsize) / sizeof (int)); ndx++) { 98*0Sstevel@tonic-gate if (crle->c_hashstrnum > hashsize[ndx]) 99*0Sstevel@tonic-gate continue; 100*0Sstevel@tonic-gate hashbkts = hashsize[ndx]; 101*0Sstevel@tonic-gate break; 102*0Sstevel@tonic-gate } 103*0Sstevel@tonic-gate if (hashbkts == 0) 104*0Sstevel@tonic-gate hashbkts = MAXNBKTS; 105*0Sstevel@tonic-gate size += ((2 + hashbkts + crle->c_hashstrnum) * sizeof (Word)); 106*0Sstevel@tonic-gate size = S_ROUND(size, sizeof (Lword)); 107*0Sstevel@tonic-gate objoff = size; 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate /* 110*0Sstevel@tonic-gate * Add the object table size (account for an 8-byte alignment 111*0Sstevel@tonic-gate * requirement for each object). 112*0Sstevel@tonic-gate */ 113*0Sstevel@tonic-gate size += (crle->c_hashstrnum * 114*0Sstevel@tonic-gate S_ROUND(sizeof (Rtc_obj), sizeof (Lword))); 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate /* 117*0Sstevel@tonic-gate * Add the file descriptor arrays. 118*0Sstevel@tonic-gate */ 119*0Sstevel@tonic-gate fileoff = size; 120*0Sstevel@tonic-gate size += S_ROUND((crle->c_filenum * sizeof (Rtc_file)), 121*0Sstevel@tonic-gate sizeof (Word)); 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate /* 124*0Sstevel@tonic-gate * Add the directory descriptor array. 125*0Sstevel@tonic-gate */ 126*0Sstevel@tonic-gate diroff = size; 127*0Sstevel@tonic-gate size += S_ROUND((crle->c_dirnum * sizeof (Rtc_dir)), 128*0Sstevel@tonic-gate sizeof (Word)); 129*0Sstevel@tonic-gate } 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate /* 132*0Sstevel@tonic-gate * Add any environment string array (insure zero last entry). 133*0Sstevel@tonic-gate */ 134*0Sstevel@tonic-gate if (crle->c_envnum) { 135*0Sstevel@tonic-gate envoff = size; 136*0Sstevel@tonic-gate size += S_ROUND(((crle->c_envnum + 1) * sizeof (Rtc_env)), 137*0Sstevel@tonic-gate sizeof (Word)); 138*0Sstevel@tonic-gate } 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate /* 141*0Sstevel@tonic-gate * Add any filter/filtee association arrays (insure zero last entry for 142*0Sstevel@tonic-gate * the filter array, the filtee arrays are already accounted for). 143*0Sstevel@tonic-gate */ 144*0Sstevel@tonic-gate if (crle->c_fltrnum) { 145*0Sstevel@tonic-gate fltroff = size; 146*0Sstevel@tonic-gate size += S_ROUND(((crle->c_fltrnum + 1) * sizeof (Rtc_fltr)), 147*0Sstevel@tonic-gate sizeof (Word)); 148*0Sstevel@tonic-gate flteoff = size; 149*0Sstevel@tonic-gate size += S_ROUND((crle->c_fltenum * sizeof (Rtc_flte)), 150*0Sstevel@tonic-gate sizeof (Word)); 151*0Sstevel@tonic-gate } 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gate /* 154*0Sstevel@tonic-gate * Add the string table size (this may contain library and/or secure 155*0Sstevel@tonic-gate * path strings, in addition to any directory/file strings). 156*0Sstevel@tonic-gate */ 157*0Sstevel@tonic-gate if (crle->c_strsize) { 158*0Sstevel@tonic-gate stroff = size; 159*0Sstevel@tonic-gate size += S_ROUND(crle->c_strsize, sizeof (Word)); 160*0Sstevel@tonic-gate } 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gate /* 163*0Sstevel@tonic-gate * Truncate our temporary file now that we know its size and map it. 164*0Sstevel@tonic-gate */ 165*0Sstevel@tonic-gate if (ftruncate(crle->c_tempfd, size) == -1) { 166*0Sstevel@tonic-gate int err = errno; 167*0Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_TRUNC), 168*0Sstevel@tonic-gate crle->c_name, crle->c_tempname, strerror(err)); 169*0Sstevel@tonic-gate (void) close(crle->c_tempfd); 170*0Sstevel@tonic-gate return (1); 171*0Sstevel@tonic-gate } 172*0Sstevel@tonic-gate if ((addr = (Addr)mmap(0, size, (PROT_READ | PROT_WRITE), MAP_SHARED, 173*0Sstevel@tonic-gate crle->c_tempfd, 0)) == (Addr)-1) { 174*0Sstevel@tonic-gate int err = errno; 175*0Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_MMAP), 176*0Sstevel@tonic-gate crle->c_name, crle->c_tempname, strerror(err)); 177*0Sstevel@tonic-gate (void) close(crle->c_tempfd); 178*0Sstevel@tonic-gate return (1); 179*0Sstevel@tonic-gate } 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate /* 182*0Sstevel@tonic-gate * Save the mapped files info for possible dldump(3dl) updates. 183*0Sstevel@tonic-gate */ 184*0Sstevel@tonic-gate crle->c_tempaddr = addr; 185*0Sstevel@tonic-gate crle->c_tempsize = size; 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate /* 188*0Sstevel@tonic-gate * Establish the real address of each of the structures within the file. 189*0Sstevel@tonic-gate */ 190*0Sstevel@tonic-gate head = (Rtc_head *)addr; 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate head->ch_hash = hashoff; 193*0Sstevel@tonic-gate /* LINTED */ 194*0Sstevel@tonic-gate hashtbl = (Word *)((char *)head->ch_hash + addr); 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gate head->ch_obj = objoff; 197*0Sstevel@tonic-gate /* LINTED */ 198*0Sstevel@tonic-gate objtbl = (Rtc_obj *)((char *)head->ch_obj + addr); 199*0Sstevel@tonic-gate objtbl = (Rtc_obj *)S_ROUND((int)(objtbl + 1), sizeof (Lword)); 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate head->ch_file = fileoff; 202*0Sstevel@tonic-gate /* LINTED */ 203*0Sstevel@tonic-gate filetbl = (Rtc_file *)((char *)head->ch_file + addr); 204*0Sstevel@tonic-gate 205*0Sstevel@tonic-gate head->ch_dir = diroff; 206*0Sstevel@tonic-gate /* LINTED */ 207*0Sstevel@tonic-gate dirtbl = (Rtc_dir *)((char *)head->ch_dir + addr); 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate head->ch_env = envoff; 210*0Sstevel@tonic-gate /* LINTED */ 211*0Sstevel@tonic-gate envtbl = (Rtc_env *)((char *)head->ch_env + addr); 212*0Sstevel@tonic-gate 213*0Sstevel@tonic-gate head->ch_fltr = fltroff; 214*0Sstevel@tonic-gate /* LINTED */ 215*0Sstevel@tonic-gate fltrtbl = (Rtc_fltr *)((char *)head->ch_fltr + addr); 216*0Sstevel@tonic-gate head->ch_flte = flteoff; 217*0Sstevel@tonic-gate /* LINTED */ 218*0Sstevel@tonic-gate fltetbl = _fltetbl = (Rtc_flte *)((char *)head->ch_flte + addr); 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate head->ch_str = stroff; 221*0Sstevel@tonic-gate strtbl = _strtbl = (char *)((char *)head->ch_str + addr); 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate /* 224*0Sstevel@tonic-gate * Fill in additional basic header information. 225*0Sstevel@tonic-gate */ 226*0Sstevel@tonic-gate head->ch_version = RTC_VER_CURRENT; 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate if (crle->c_flags & CRLE_ALTER) 229*0Sstevel@tonic-gate head->ch_cnflags |= RTC_HDR_ALTER; 230*0Sstevel@tonic-gate if (crle->c_flags & CRLE_DUMP) { 231*0Sstevel@tonic-gate head->ch_cnflags |= RTC_HDR_IGNORE; 232*0Sstevel@tonic-gate head->ch_dlflags = crle->c_dlflags; 233*0Sstevel@tonic-gate } 234*0Sstevel@tonic-gate if (crle->c_class == ELFCLASS64) 235*0Sstevel@tonic-gate head->ch_cnflags |= RTC_HDR_64; 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS 238*0Sstevel@tonic-gate head->ch_cnflags |= RTC_HDR_UPM; 239*0Sstevel@tonic-gate #endif 240*0Sstevel@tonic-gate /* 241*0Sstevel@tonic-gate * If we have a hash table then there are directory and file entries 242*0Sstevel@tonic-gate * to process. 243*0Sstevel@tonic-gate */ 244*0Sstevel@tonic-gate if (crle->c_hashstrnum) { 245*0Sstevel@tonic-gate hashtbl[0] = hashbkts; 246*0Sstevel@tonic-gate hashtbl[1] = crle->c_hashstrnum; 247*0Sstevel@tonic-gate hashbkt = &hashtbl[2]; 248*0Sstevel@tonic-gate hashchn = &hashtbl[2 + hashbkts]; 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate /* 251*0Sstevel@tonic-gate * Insure all hash chain and directory/filename table entries 252*0Sstevel@tonic-gate * are cleared. 253*0Sstevel@tonic-gate */ 254*0Sstevel@tonic-gate (void) memset(hashchn, 0, (crle->c_hashstrnum * sizeof (Word))); 255*0Sstevel@tonic-gate (void) memset(dirtbl, 0, (strtbl - (char *)dirtbl)); 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gate /* 258*0Sstevel@tonic-gate * Loop through the current string table list inspecting only 259*0Sstevel@tonic-gate * directories. 260*0Sstevel@tonic-gate */ 261*0Sstevel@tonic-gate for (ndx = 1, bkt = 0; bkt < stbl->t_size; bkt++) { 262*0Sstevel@tonic-gate for (ent = stbl->t_entry[bkt]; ent; ent = ent->e_next) { 263*0Sstevel@tonic-gate Word hashval; 264*0Sstevel@tonic-gate Hash_obj *obj = ent->e_obj; 265*0Sstevel@tonic-gate char *dir = (char *)ent->e_key; 266*0Sstevel@tonic-gate Rtc_dir *_dirtbl; 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate /* 269*0Sstevel@tonic-gate * Skip any empty and non-directory entries. 270*0Sstevel@tonic-gate */ 271*0Sstevel@tonic-gate if ((obj == 0) || 272*0Sstevel@tonic-gate ((obj->o_flags & RTC_OBJ_DIRENT) == 0)) 273*0Sstevel@tonic-gate continue; 274*0Sstevel@tonic-gate 275*0Sstevel@tonic-gate /* 276*0Sstevel@tonic-gate * Assign basic object attributes. 277*0Sstevel@tonic-gate */ 278*0Sstevel@tonic-gate objtbl->co_hash = ent->e_hash; 279*0Sstevel@tonic-gate objtbl->co_id = ent->e_id; 280*0Sstevel@tonic-gate objtbl->co_flags = obj->o_flags | ent->e_flags; 281*0Sstevel@tonic-gate objtbl->co_info = obj->o_info; 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate ent->e_cobj = objtbl; 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate /* 286*0Sstevel@tonic-gate * Assign the directory name (from its key), 287*0Sstevel@tonic-gate * and copy its name to the string table. 288*0Sstevel@tonic-gate */ 289*0Sstevel@tonic-gate objtbl->co_name = (Addr)(_strtbl - strtbl); 290*0Sstevel@tonic-gate (void) strcpy(_strtbl, dir); 291*0Sstevel@tonic-gate _strtbl += strlen(dir) + 1; 292*0Sstevel@tonic-gate 293*0Sstevel@tonic-gate /* 294*0Sstevel@tonic-gate * Establish an entry in the directory table and 295*0Sstevel@tonic-gate * reserve space for its associated filename 296*0Sstevel@tonic-gate * entries (note, we add a trailing null file 297*0Sstevel@tonic-gate * entry to simplify later inspection of the 298*0Sstevel@tonic-gate * final configuration file. 299*0Sstevel@tonic-gate */ 300*0Sstevel@tonic-gate _dirtbl = &dirtbl[ent->e_id - 1]; 301*0Sstevel@tonic-gate _dirtbl->cd_file = 302*0Sstevel@tonic-gate (Word)((char *)filetbl - addr); 303*0Sstevel@tonic-gate _dirtbl->cd_obj = 304*0Sstevel@tonic-gate (Word)((char *)objtbl - addr); 305*0Sstevel@tonic-gate 306*0Sstevel@tonic-gate /* LINTED */ 307*0Sstevel@tonic-gate filetbl = (Rtc_file *)((char *)filetbl + 308*0Sstevel@tonic-gate ((ent->e_cnt + 1) * sizeof (Rtc_file))); 309*0Sstevel@tonic-gate 310*0Sstevel@tonic-gate /* 311*0Sstevel@tonic-gate * Add this object to the hash table. 312*0Sstevel@tonic-gate */ 313*0Sstevel@tonic-gate hashval = ent->e_hash % hashbkts; 314*0Sstevel@tonic-gate hashchn[ndx] = hashbkt[hashval]; 315*0Sstevel@tonic-gate hashbkt[hashval] = ndx++; 316*0Sstevel@tonic-gate 317*0Sstevel@tonic-gate /* 318*0Sstevel@tonic-gate * Increment Rt_obj pointer (make sure pointer 319*0Sstevel@tonic-gate * falls on an 8-byte boundary). 320*0Sstevel@tonic-gate */ 321*0Sstevel@tonic-gate objtbl = (Rtc_obj *)S_ROUND((int)(objtbl + 1), 322*0Sstevel@tonic-gate sizeof (Lword)); 323*0Sstevel@tonic-gate } 324*0Sstevel@tonic-gate } 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate /* 327*0Sstevel@tonic-gate * Now collect all pathnames. These are typically full 328*0Sstevel@tonic-gate * pathnames, but may also be relative. Simple filenames are 329*0Sstevel@tonic-gate * recorded as offsets into these pathnames, thus we need to 330*0Sstevel@tonic-gate * establish the new pathname first. 331*0Sstevel@tonic-gate */ 332*0Sstevel@tonic-gate for (bkt = 0; bkt < stbl->t_size; bkt++) { 333*0Sstevel@tonic-gate for (ent = stbl->t_entry[bkt]; ent; ent = ent->e_next) { 334*0Sstevel@tonic-gate Word hashval; 335*0Sstevel@tonic-gate Hash_obj *obj = ent->e_obj; 336*0Sstevel@tonic-gate char *file = (char *)ent->e_key; 337*0Sstevel@tonic-gate char *_str; 338*0Sstevel@tonic-gate Rtc_dir *_dirtbl; 339*0Sstevel@tonic-gate Rtc_file *_filetbl; 340*0Sstevel@tonic-gate int _id; 341*0Sstevel@tonic-gate 342*0Sstevel@tonic-gate /* 343*0Sstevel@tonic-gate * Skip empty and directory entries, and any 344*0Sstevel@tonic-gate * simple filename entries. 345*0Sstevel@tonic-gate */ 346*0Sstevel@tonic-gate if ((obj == 0) || 347*0Sstevel@tonic-gate (obj->o_flags & RTC_OBJ_DIRENT) || 348*0Sstevel@tonic-gate (ent->e_off)) 349*0Sstevel@tonic-gate continue; 350*0Sstevel@tonic-gate 351*0Sstevel@tonic-gate /* 352*0Sstevel@tonic-gate * Assign basic object attributes. 353*0Sstevel@tonic-gate */ 354*0Sstevel@tonic-gate objtbl->co_hash = ent->e_hash; 355*0Sstevel@tonic-gate objtbl->co_id = ent->e_id; 356*0Sstevel@tonic-gate objtbl->co_flags = obj->o_flags | ent->e_flags; 357*0Sstevel@tonic-gate objtbl->co_info = obj->o_info; 358*0Sstevel@tonic-gate 359*0Sstevel@tonic-gate ent->e_cobj = objtbl; 360*0Sstevel@tonic-gate 361*0Sstevel@tonic-gate /* 362*0Sstevel@tonic-gate * Assign the file name (from its key), 363*0Sstevel@tonic-gate * and copy its name to the string table. 364*0Sstevel@tonic-gate */ 365*0Sstevel@tonic-gate objtbl->co_name = (Addr)(_strtbl - strtbl); 366*0Sstevel@tonic-gate (void) strcpy(_strtbl, file); 367*0Sstevel@tonic-gate _strtbl += strlen(file) + 1; 368*0Sstevel@tonic-gate 369*0Sstevel@tonic-gate /* 370*0Sstevel@tonic-gate * Add this file to its associated directory. 371*0Sstevel@tonic-gate */ 372*0Sstevel@tonic-gate _dirtbl = &dirtbl[ent->e_id - 1]; 373*0Sstevel@tonic-gate /* LINTED */ 374*0Sstevel@tonic-gate _filetbl = (Rtc_file *) 375*0Sstevel@tonic-gate ((char *)_dirtbl->cd_file + addr); 376*0Sstevel@tonic-gate 377*0Sstevel@tonic-gate _id = --ent->e_dir->e_cnt; 378*0Sstevel@tonic-gate _filetbl[_id].cf_obj = 379*0Sstevel@tonic-gate (Word)((char *)objtbl - addr); 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gate /* 382*0Sstevel@tonic-gate * If object has an alternative, record it in 383*0Sstevel@tonic-gate * the string table and assign the alternate 384*0Sstevel@tonic-gate * pointer. The new alternative offset is 385*0Sstevel@tonic-gate * retained for reuse in other filename entries. 386*0Sstevel@tonic-gate */ 387*0Sstevel@tonic-gate if ((objtbl->co_flags & RTC_OBJ_ALTER) && 388*0Sstevel@tonic-gate (obj->o_calter == 0)) { 389*0Sstevel@tonic-gate _str = obj->o_alter; 390*0Sstevel@tonic-gate objtbl->co_alter = obj->o_calter = 391*0Sstevel@tonic-gate (Addr)(_strtbl - strtbl); 392*0Sstevel@tonic-gate (void) strcpy(_strtbl, _str); 393*0Sstevel@tonic-gate _strtbl += strlen(_str) + 1; 394*0Sstevel@tonic-gate } else 395*0Sstevel@tonic-gate objtbl->co_alter = obj->o_calter; 396*0Sstevel@tonic-gate 397*0Sstevel@tonic-gate /* 398*0Sstevel@tonic-gate * If object identifies the specific application 399*0Sstevel@tonic-gate * for which this cache is relevant, record it 400*0Sstevel@tonic-gate * in the header. 401*0Sstevel@tonic-gate */ 402*0Sstevel@tonic-gate if ((objtbl->co_flags & 403*0Sstevel@tonic-gate (RTC_OBJ_APP | RTC_OBJ_REALPTH)) == 404*0Sstevel@tonic-gate (RTC_OBJ_APP | RTC_OBJ_REALPTH)) 405*0Sstevel@tonic-gate head->ch_app = _filetbl[_id].cf_obj; 406*0Sstevel@tonic-gate 407*0Sstevel@tonic-gate /* 408*0Sstevel@tonic-gate * Add this object to the hash table. 409*0Sstevel@tonic-gate */ 410*0Sstevel@tonic-gate hashval = ent->e_hash % hashbkts; 411*0Sstevel@tonic-gate hashchn[ndx] = hashbkt[hashval]; 412*0Sstevel@tonic-gate hashbkt[hashval] = ndx++; 413*0Sstevel@tonic-gate 414*0Sstevel@tonic-gate /* 415*0Sstevel@tonic-gate * Increment Rt_obj pointer (make sure pointer 416*0Sstevel@tonic-gate * falls on an 8-byte boundary). 417*0Sstevel@tonic-gate */ 418*0Sstevel@tonic-gate objtbl = (Rtc_obj *)S_ROUND((int)(objtbl + 1), 419*0Sstevel@tonic-gate sizeof (Lword)); 420*0Sstevel@tonic-gate } 421*0Sstevel@tonic-gate } 422*0Sstevel@tonic-gate 423*0Sstevel@tonic-gate /* 424*0Sstevel@tonic-gate * Finally pick off any simple filenames. 425*0Sstevel@tonic-gate */ 426*0Sstevel@tonic-gate for (bkt = 0; bkt < stbl->t_size; bkt++) { 427*0Sstevel@tonic-gate for (ent = stbl->t_entry[bkt]; ent; ent = ent->e_next) { 428*0Sstevel@tonic-gate Word hashval; 429*0Sstevel@tonic-gate Hash_obj * obj = ent->e_obj; 430*0Sstevel@tonic-gate Rtc_dir * _dirtbl; 431*0Sstevel@tonic-gate Rtc_file * _filetbl; 432*0Sstevel@tonic-gate int _id; 433*0Sstevel@tonic-gate 434*0Sstevel@tonic-gate /* 435*0Sstevel@tonic-gate * Skip everything except simple filenames. 436*0Sstevel@tonic-gate */ 437*0Sstevel@tonic-gate if (ent->e_off == 0) 438*0Sstevel@tonic-gate continue; 439*0Sstevel@tonic-gate 440*0Sstevel@tonic-gate /* 441*0Sstevel@tonic-gate * Assign basic object attributes. 442*0Sstevel@tonic-gate */ 443*0Sstevel@tonic-gate objtbl->co_hash = ent->e_hash; 444*0Sstevel@tonic-gate objtbl->co_id = ent->e_id; 445*0Sstevel@tonic-gate objtbl->co_flags = obj->o_flags | ent->e_flags; 446*0Sstevel@tonic-gate objtbl->co_info = obj->o_info; 447*0Sstevel@tonic-gate objtbl->co_alter = obj->o_calter; 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gate ent->e_cobj = objtbl; 450*0Sstevel@tonic-gate 451*0Sstevel@tonic-gate /* 452*0Sstevel@tonic-gate * Assign the file name from its full name. 453*0Sstevel@tonic-gate */ 454*0Sstevel@tonic-gate objtbl->co_name = (Addr)((char *) 455*0Sstevel@tonic-gate ent->e_path->e_cobj->co_name + ent->e_off); 456*0Sstevel@tonic-gate 457*0Sstevel@tonic-gate /* 458*0Sstevel@tonic-gate * Add this file to its associated directory. 459*0Sstevel@tonic-gate */ 460*0Sstevel@tonic-gate _dirtbl = &dirtbl[ent->e_id - 1]; 461*0Sstevel@tonic-gate /* LINTED */ 462*0Sstevel@tonic-gate _filetbl = (Rtc_file *) 463*0Sstevel@tonic-gate ((char *)_dirtbl->cd_file + addr); 464*0Sstevel@tonic-gate 465*0Sstevel@tonic-gate _id = --ent->e_dir->e_cnt; 466*0Sstevel@tonic-gate _filetbl[_id].cf_obj = 467*0Sstevel@tonic-gate (Word)((char *)objtbl - addr); 468*0Sstevel@tonic-gate 469*0Sstevel@tonic-gate /* 470*0Sstevel@tonic-gate * Add this object to the hash table. 471*0Sstevel@tonic-gate */ 472*0Sstevel@tonic-gate hashval = ent->e_hash % hashbkts; 473*0Sstevel@tonic-gate hashchn[ndx] = hashbkt[hashval]; 474*0Sstevel@tonic-gate hashbkt[hashval] = ndx++; 475*0Sstevel@tonic-gate 476*0Sstevel@tonic-gate /* 477*0Sstevel@tonic-gate * Increment Rt_obj pointer (make sure pointer 478*0Sstevel@tonic-gate * falls on an 8-byte boundary). 479*0Sstevel@tonic-gate */ 480*0Sstevel@tonic-gate objtbl = (Rtc_obj *)S_ROUND((int)(objtbl + 1), 481*0Sstevel@tonic-gate sizeof (Lword)); 482*0Sstevel@tonic-gate } 483*0Sstevel@tonic-gate } 484*0Sstevel@tonic-gate } 485*0Sstevel@tonic-gate 486*0Sstevel@tonic-gate /* 487*0Sstevel@tonic-gate * Add any library, or secure path definitions. 488*0Sstevel@tonic-gate */ 489*0Sstevel@tonic-gate if (crle->c_edlibpath) { 490*0Sstevel@tonic-gate head->ch_edlibpath = head->ch_str + (_strtbl - strtbl); 491*0Sstevel@tonic-gate 492*0Sstevel@tonic-gate (void) strcpy(_strtbl, crle->c_edlibpath); 493*0Sstevel@tonic-gate _strtbl += strlen((char *)crle->c_edlibpath) + 1; 494*0Sstevel@tonic-gate } else 495*0Sstevel@tonic-gate head->ch_edlibpath = 0; 496*0Sstevel@tonic-gate 497*0Sstevel@tonic-gate if (crle->c_adlibpath) { 498*0Sstevel@tonic-gate head->ch_adlibpath = head->ch_str + (_strtbl - strtbl); 499*0Sstevel@tonic-gate 500*0Sstevel@tonic-gate (void) strcpy(_strtbl, crle->c_adlibpath); 501*0Sstevel@tonic-gate _strtbl += strlen((char *)crle->c_adlibpath) + 1; 502*0Sstevel@tonic-gate } else 503*0Sstevel@tonic-gate head->ch_adlibpath = 0; 504*0Sstevel@tonic-gate 505*0Sstevel@tonic-gate if (crle->c_eslibpath) { 506*0Sstevel@tonic-gate head->ch_eslibpath = head->ch_str + (_strtbl - strtbl); 507*0Sstevel@tonic-gate 508*0Sstevel@tonic-gate (void) strcpy(_strtbl, crle->c_eslibpath); 509*0Sstevel@tonic-gate _strtbl += strlen((char *)crle->c_eslibpath) + 1; 510*0Sstevel@tonic-gate } else 511*0Sstevel@tonic-gate head->ch_eslibpath = 0; 512*0Sstevel@tonic-gate 513*0Sstevel@tonic-gate if (crle->c_aslibpath) { 514*0Sstevel@tonic-gate head->ch_aslibpath = head->ch_str + (_strtbl - strtbl); 515*0Sstevel@tonic-gate 516*0Sstevel@tonic-gate (void) strcpy(_strtbl, crle->c_aslibpath); 517*0Sstevel@tonic-gate _strtbl += strlen((char *)crle->c_aslibpath) + 1; 518*0Sstevel@tonic-gate } else 519*0Sstevel@tonic-gate head->ch_aslibpath = 0; 520*0Sstevel@tonic-gate 521*0Sstevel@tonic-gate /* 522*0Sstevel@tonic-gate * Add any environment variable entries. 523*0Sstevel@tonic-gate */ 524*0Sstevel@tonic-gate if (crle->c_envnum) { 525*0Sstevel@tonic-gate Env_desc * env; 526*0Sstevel@tonic-gate Listnode * lnp; 527*0Sstevel@tonic-gate 528*0Sstevel@tonic-gate for (LIST_TRAVERSE(&(crle->c_env), lnp, env)) { 529*0Sstevel@tonic-gate envtbl->env_str = head->ch_str + (_strtbl - strtbl); 530*0Sstevel@tonic-gate envtbl->env_flags = env->e_flags; 531*0Sstevel@tonic-gate 532*0Sstevel@tonic-gate (void) strcpy(_strtbl, env->e_str); 533*0Sstevel@tonic-gate _strtbl += env->e_totsz; 534*0Sstevel@tonic-gate 535*0Sstevel@tonic-gate envtbl++; 536*0Sstevel@tonic-gate } 537*0Sstevel@tonic-gate envtbl->env_str = 0; 538*0Sstevel@tonic-gate envtbl->env_flags = 0; 539*0Sstevel@tonic-gate } 540*0Sstevel@tonic-gate 541*0Sstevel@tonic-gate /* 542*0Sstevel@tonic-gate * Add any filter/filtee association entries. 543*0Sstevel@tonic-gate */ 544*0Sstevel@tonic-gate if (crle->c_fltrnum) { 545*0Sstevel@tonic-gate Flt_desc * flt; 546*0Sstevel@tonic-gate Listnode * lnp1; 547*0Sstevel@tonic-gate 548*0Sstevel@tonic-gate for (LIST_TRAVERSE(&(crle->c_flt), lnp1, flt)) { 549*0Sstevel@tonic-gate Hash_ent * flte; 550*0Sstevel@tonic-gate Listnode * lnp2; 551*0Sstevel@tonic-gate 552*0Sstevel@tonic-gate /* 553*0Sstevel@tonic-gate * Establish the filter name, and filtee string, as 554*0Sstevel@tonic-gate * offsets into the configuration files string table. 555*0Sstevel@tonic-gate * Establish the filtee as the offset into the filtee 556*0Sstevel@tonic-gate * table. 557*0Sstevel@tonic-gate */ 558*0Sstevel@tonic-gate fltrtbl->fr_filter = flt->f_fent->e_cobj->co_name; 559*0Sstevel@tonic-gate fltrtbl->fr_string = _strtbl - strtbl; 560*0Sstevel@tonic-gate (void) strcpy(_strtbl, flt->f_str); 561*0Sstevel@tonic-gate _strtbl += flt->f_strsz; 562*0Sstevel@tonic-gate fltrtbl->fr_filtee = ((Word)_fltetbl - (Word)fltetbl); 563*0Sstevel@tonic-gate 564*0Sstevel@tonic-gate for (LIST_TRAVERSE(&(flt->f_filtee), lnp2, flte)) { 565*0Sstevel@tonic-gate /* 566*0Sstevel@tonic-gate * Establish the filtee name as the offset into 567*0Sstevel@tonic-gate * the configuration files string table. 568*0Sstevel@tonic-gate */ 569*0Sstevel@tonic-gate _fltetbl->fe_filtee = flte->e_cobj->co_name; 570*0Sstevel@tonic-gate _fltetbl++; 571*0Sstevel@tonic-gate } 572*0Sstevel@tonic-gate _fltetbl->fe_filtee = 0; 573*0Sstevel@tonic-gate _fltetbl++, fltrtbl++; 574*0Sstevel@tonic-gate } 575*0Sstevel@tonic-gate fltrtbl->fr_filter = 0; 576*0Sstevel@tonic-gate fltrtbl->fr_filtee = 0; 577*0Sstevel@tonic-gate } 578*0Sstevel@tonic-gate 579*0Sstevel@tonic-gate /* 580*0Sstevel@tonic-gate * Flush everything out. 581*0Sstevel@tonic-gate */ 582*0Sstevel@tonic-gate (void) close(crle->c_tempfd); 583*0Sstevel@tonic-gate if (msync((void *)addr, size, MS_ASYNC) == -1) { 584*0Sstevel@tonic-gate int err = errno; 585*0Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_TRUNC), 586*0Sstevel@tonic-gate crle->c_name, crle->c_tempname, strerror(err)); 587*0Sstevel@tonic-gate return (1); 588*0Sstevel@tonic-gate } 589*0Sstevel@tonic-gate 590*0Sstevel@tonic-gate return (0); 591*0Sstevel@tonic-gate } 592*0Sstevel@tonic-gate 593*0Sstevel@tonic-gate /* 594*0Sstevel@tonic-gate * Update a configuration file. If dldump()'ed images have been created then 595*0Sstevel@tonic-gate * the memory reservation of those images is added to the configuration file. 596*0Sstevel@tonic-gate * The temporary file is then moved into its final resting place. 597*0Sstevel@tonic-gate */ 598*0Sstevel@tonic-gate updateconfig(Crle_desc * crle) 599*0Sstevel@tonic-gate { 600*0Sstevel@tonic-gate Rtc_head * head = (Rtc_head *)crle->c_tempaddr; 601*0Sstevel@tonic-gate 602*0Sstevel@tonic-gate if (crle->c_flags & CRLE_DUMP) { 603*0Sstevel@tonic-gate head->ch_cnflags &= ~RTC_HDR_IGNORE; 604*0Sstevel@tonic-gate 605*0Sstevel@tonic-gate if (msync((void *)crle->c_tempaddr, crle->c_tempsize, 606*0Sstevel@tonic-gate MS_ASYNC) == -1) { 607*0Sstevel@tonic-gate int err = errno; 608*0Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_TRUNC), 609*0Sstevel@tonic-gate crle->c_name, crle->c_tempname, strerror(err)); 610*0Sstevel@tonic-gate return (1); 611*0Sstevel@tonic-gate } 612*0Sstevel@tonic-gate } 613*0Sstevel@tonic-gate 614*0Sstevel@tonic-gate /* 615*0Sstevel@tonic-gate * If an original configuration file exists, remove it. 616*0Sstevel@tonic-gate */ 617*0Sstevel@tonic-gate if (crle->c_flags & CRLE_EXISTS) 618*0Sstevel@tonic-gate (void) unlink(crle->c_confil); 619*0Sstevel@tonic-gate 620*0Sstevel@tonic-gate /* 621*0Sstevel@tonic-gate * Move the config file to its final resting place. If the two files 622*0Sstevel@tonic-gate * exist on the same filesystem a rename is sufficient. 623*0Sstevel@tonic-gate */ 624*0Sstevel@tonic-gate if (crle->c_flags & CRLE_DIFFDEV) { 625*0Sstevel@tonic-gate int fd; 626*0Sstevel@tonic-gate 627*0Sstevel@tonic-gate if ((fd = open(crle->c_confil, (O_RDWR | O_CREAT | O_TRUNC), 628*0Sstevel@tonic-gate 0666)) == -1) { 629*0Sstevel@tonic-gate int err = errno; 630*0Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN), 631*0Sstevel@tonic-gate crle->c_name, crle->c_confil, strerror(err)); 632*0Sstevel@tonic-gate return (1); 633*0Sstevel@tonic-gate } 634*0Sstevel@tonic-gate if (write(fd, (void *)crle->c_tempaddr, crle->c_tempsize) != 635*0Sstevel@tonic-gate crle->c_tempsize) { 636*0Sstevel@tonic-gate int err = errno; 637*0Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_WRITE), 638*0Sstevel@tonic-gate crle->c_name, crle->c_confil, strerror(err)); 639*0Sstevel@tonic-gate return (1); 640*0Sstevel@tonic-gate } 641*0Sstevel@tonic-gate (void) close(fd); 642*0Sstevel@tonic-gate (void) unlink(crle->c_tempname); 643*0Sstevel@tonic-gate } else 644*0Sstevel@tonic-gate (void) rename(crle->c_tempname, crle->c_confil); 645*0Sstevel@tonic-gate 646*0Sstevel@tonic-gate return (0); 647*0Sstevel@tonic-gate } 648