17c478bd9Sstevel@tonic-gate /* 2*159d09a2SMark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate 77c478bd9Sstevel@tonic-gate /* 87c478bd9Sstevel@tonic-gate * prof_init.c --- routines that manipulate the user-visible profile_t 97c478bd9Sstevel@tonic-gate * object. 107c478bd9Sstevel@tonic-gate */ 117c478bd9Sstevel@tonic-gate 12505d05c7Sgtb #include "prof_int.h" 13505d05c7Sgtb 147c478bd9Sstevel@tonic-gate #include <stdio.h> 157c478bd9Sstevel@tonic-gate #include <string.h> 167c478bd9Sstevel@tonic-gate #ifdef HAVE_STDLIB_H 177c478bd9Sstevel@tonic-gate #include <stdlib.h> 187c478bd9Sstevel@tonic-gate #endif 197c478bd9Sstevel@tonic-gate #include <errno.h> 207c478bd9Sstevel@tonic-gate 21*159d09a2SMark Phalan #ifdef HAVE_STDINT_H 22*159d09a2SMark Phalan # include <stdint.h> 23*159d09a2SMark Phalan #endif 24*159d09a2SMark Phalan #ifdef HAVE_INTTYPES_H 25*159d09a2SMark Phalan # include <inttypes.h> 26*159d09a2SMark Phalan #endif 27*159d09a2SMark Phalan typedef int32_t prof_int32; 287c478bd9Sstevel@tonic-gate 29505d05c7Sgtb errcode_t KRB5_CALLCONV 30505d05c7Sgtb profile_init(const_profile_filespec_t *files, profile_t *ret_profile) 317c478bd9Sstevel@tonic-gate { 327c478bd9Sstevel@tonic-gate const_profile_filespec_t *fs; 337c478bd9Sstevel@tonic-gate profile_t profile; 347c478bd9Sstevel@tonic-gate prf_file_t new_file, last = 0; 357c478bd9Sstevel@tonic-gate errcode_t retval = 0; 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate profile = malloc(sizeof(struct _profile_t)); 387c478bd9Sstevel@tonic-gate if (!profile) 397c478bd9Sstevel@tonic-gate return ENOMEM; 407c478bd9Sstevel@tonic-gate memset(profile, 0, sizeof(struct _profile_t)); 417c478bd9Sstevel@tonic-gate profile->magic = PROF_MAGIC_PROFILE; 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate /* if the filenames list is not specified return an empty profile */ 447c478bd9Sstevel@tonic-gate if ( files ) { 457c478bd9Sstevel@tonic-gate for (fs = files; !PROFILE_LAST_FILESPEC(*fs); fs++) { 467c478bd9Sstevel@tonic-gate retval = profile_open_file(*fs, &new_file); 477c478bd9Sstevel@tonic-gate /* if this file is missing, skip to the next */ 48505d05c7Sgtb if (retval == ENOENT || retval == EACCES) { 497c478bd9Sstevel@tonic-gate continue; 507c478bd9Sstevel@tonic-gate } 517c478bd9Sstevel@tonic-gate if (retval) { 527c478bd9Sstevel@tonic-gate profile_release(profile); 537c478bd9Sstevel@tonic-gate return retval; 547c478bd9Sstevel@tonic-gate } 557c478bd9Sstevel@tonic-gate if (last) 567c478bd9Sstevel@tonic-gate last->next = new_file; 577c478bd9Sstevel@tonic-gate else 587c478bd9Sstevel@tonic-gate profile->first_file = new_file; 597c478bd9Sstevel@tonic-gate last = new_file; 607c478bd9Sstevel@tonic-gate } 617c478bd9Sstevel@tonic-gate /* 627c478bd9Sstevel@tonic-gate * If last is still null after the loop, then all the files were 637c478bd9Sstevel@tonic-gate * missing, so return the appropriate error. 647c478bd9Sstevel@tonic-gate */ 657c478bd9Sstevel@tonic-gate if (!last) { 667c478bd9Sstevel@tonic-gate profile_release(profile); 677c478bd9Sstevel@tonic-gate return ENOENT; 687c478bd9Sstevel@tonic-gate } 697c478bd9Sstevel@tonic-gate } 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate *ret_profile = profile; 727c478bd9Sstevel@tonic-gate return 0; 737c478bd9Sstevel@tonic-gate } 747c478bd9Sstevel@tonic-gate 75*159d09a2SMark Phalan #define COUNT_LINKED_LIST(COUNT, PTYPE, START, FIELD) \ 76*159d09a2SMark Phalan { \ 77*159d09a2SMark Phalan int cll_counter = 0; \ 78*159d09a2SMark Phalan PTYPE cll_ptr = (START); \ 79*159d09a2SMark Phalan while (cll_ptr != NULL) { \ 80*159d09a2SMark Phalan cll_counter++; \ 81*159d09a2SMark Phalan cll_ptr = cll_ptr->FIELD; \ 82*159d09a2SMark Phalan } \ 83*159d09a2SMark Phalan (COUNT) = cll_counter; \ 84*159d09a2SMark Phalan } 85*159d09a2SMark Phalan 86*159d09a2SMark Phalan errcode_t KRB5_CALLCONV 87*159d09a2SMark Phalan profile_copy(profile_t old_profile, profile_t *new_profile) 88*159d09a2SMark Phalan { 89*159d09a2SMark Phalan size_t size, i; 90*159d09a2SMark Phalan const_profile_filespec_t *files; 91*159d09a2SMark Phalan prf_file_t file; 92*159d09a2SMark Phalan errcode_t err; 93*159d09a2SMark Phalan 94*159d09a2SMark Phalan /* The fields we care about are read-only after creation, so 95*159d09a2SMark Phalan no locking is needed. */ 96*159d09a2SMark Phalan COUNT_LINKED_LIST (size, prf_file_t, old_profile->first_file, next); 97*159d09a2SMark Phalan files = malloc ((size+1) * sizeof(*files)); 98*159d09a2SMark Phalan if (files == NULL) 99*159d09a2SMark Phalan return errno; 100*159d09a2SMark Phalan for (i = 0, file = old_profile->first_file; i < size; i++, file = file->next) 101*159d09a2SMark Phalan files[i] = file->data->filespec; 102*159d09a2SMark Phalan files[size] = NULL; 103*159d09a2SMark Phalan err = profile_init (files, new_profile); 104*159d09a2SMark Phalan free (files); 105*159d09a2SMark Phalan return err; 106*159d09a2SMark Phalan } 107*159d09a2SMark Phalan 108505d05c7Sgtb errcode_t KRB5_CALLCONV 109505d05c7Sgtb profile_init_path(const_profile_filespec_list_t filepath, 110505d05c7Sgtb profile_t *ret_profile) 1117c478bd9Sstevel@tonic-gate { 1127c478bd9Sstevel@tonic-gate int n_entries, i; 113505d05c7Sgtb unsigned int ent_len; 1147c478bd9Sstevel@tonic-gate const char *s, *t; 115505d05c7Sgtb profile_filespec_t *filenames; 1167c478bd9Sstevel@tonic-gate errcode_t retval; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate /* count the distinct filename components */ 1197c478bd9Sstevel@tonic-gate for(s = filepath, n_entries = 1; *s; s++) { 1207c478bd9Sstevel@tonic-gate if (*s == ':') 1217c478bd9Sstevel@tonic-gate n_entries++; 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate /* the array is NULL terminated */ 125505d05c7Sgtb filenames = (profile_filespec_t*) malloc((n_entries+1) * sizeof(char*)); 1267c478bd9Sstevel@tonic-gate if (filenames == 0) 1277c478bd9Sstevel@tonic-gate return ENOMEM; 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate /* measure, copy, and skip each one */ 130*159d09a2SMark Phalan /* Solaris Kerberos */ 1317c478bd9Sstevel@tonic-gate for(s = filepath, i=0; ((t = strchr(s, ':')) != NULL) || 132505d05c7Sgtb ((t=s+strlen(s)) != NULL); s=t+1, i++) { 1337c478bd9Sstevel@tonic-gate ent_len = t-s; 1347c478bd9Sstevel@tonic-gate filenames[i] = (char*) malloc(ent_len + 1); 1357c478bd9Sstevel@tonic-gate if (filenames[i] == 0) { 1367c478bd9Sstevel@tonic-gate /* if malloc fails, free the ones that worked */ 1377c478bd9Sstevel@tonic-gate while(--i >= 0) free(filenames[i]); 1387c478bd9Sstevel@tonic-gate free(filenames); 1397c478bd9Sstevel@tonic-gate return ENOMEM; 1407c478bd9Sstevel@tonic-gate } 1417c478bd9Sstevel@tonic-gate strncpy(filenames[i], s, ent_len); 1427c478bd9Sstevel@tonic-gate filenames[i][ent_len] = 0; 1437c478bd9Sstevel@tonic-gate if (*t == 0) { 1447c478bd9Sstevel@tonic-gate i++; 1457c478bd9Sstevel@tonic-gate break; 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate /* cap the array */ 1497c478bd9Sstevel@tonic-gate filenames[i] = 0; 1507c478bd9Sstevel@tonic-gate 151505d05c7Sgtb retval = profile_init((const_profile_filespec_t *) filenames, 152505d05c7Sgtb ret_profile); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate /* count back down and free the entries */ 1557c478bd9Sstevel@tonic-gate while(--i >= 0) free(filenames[i]); 1567c478bd9Sstevel@tonic-gate free(filenames); 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate return retval; 1597c478bd9Sstevel@tonic-gate } 160505d05c7Sgtb 161505d05c7Sgtb errcode_t KRB5_CALLCONV 162505d05c7Sgtb profile_is_writable(profile_t profile, int *writable) 1637c478bd9Sstevel@tonic-gate { 164*159d09a2SMark Phalan if (!profile || profile->magic != PROF_MAGIC_PROFILE) 165*159d09a2SMark Phalan return PROF_MAGIC_PROFILE; 166*159d09a2SMark Phalan 167*159d09a2SMark Phalan if (!writable) 168*159d09a2SMark Phalan return EINVAL; 169*159d09a2SMark Phalan 170*159d09a2SMark Phalan if (profile->first_file) 171*159d09a2SMark Phalan *writable = (profile->first_file->data->flags & PROFILE_FILE_RW); 172*159d09a2SMark Phalan 173*159d09a2SMark Phalan return 0; 174505d05c7Sgtb } 175505d05c7Sgtb 176505d05c7Sgtb errcode_t KRB5_CALLCONV 177505d05c7Sgtb profile_is_modified(profile_t profile, int *modified) 178505d05c7Sgtb { 179*159d09a2SMark Phalan if (!profile || profile->magic != PROF_MAGIC_PROFILE) 180*159d09a2SMark Phalan return PROF_MAGIC_PROFILE; 181*159d09a2SMark Phalan 182*159d09a2SMark Phalan if (!modified) 183*159d09a2SMark Phalan return EINVAL; 184*159d09a2SMark Phalan 185*159d09a2SMark Phalan if (profile->first_file) 186*159d09a2SMark Phalan *modified = (profile->first_file->data->flags & PROFILE_FILE_DIRTY); 187*159d09a2SMark Phalan 188*159d09a2SMark Phalan return 0; 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate 191505d05c7Sgtb errcode_t KRB5_CALLCONV 192505d05c7Sgtb profile_flush(profile_t profile) 1937c478bd9Sstevel@tonic-gate { 1947c478bd9Sstevel@tonic-gate if (!profile || profile->magic != PROF_MAGIC_PROFILE) 1957c478bd9Sstevel@tonic-gate return PROF_MAGIC_PROFILE; 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate if (profile->first_file) 1987c478bd9Sstevel@tonic-gate return profile_flush_file(profile->first_file); 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate return 0; 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate 203505d05c7Sgtb errcode_t KRB5_CALLCONV 204505d05c7Sgtb profile_flush_to_file(profile_t profile, const_profile_filespec_t outfile) 205505d05c7Sgtb { 206505d05c7Sgtb if (!profile || profile->magic != PROF_MAGIC_PROFILE) 207505d05c7Sgtb return PROF_MAGIC_PROFILE; 208505d05c7Sgtb 209505d05c7Sgtb if (profile->first_file) 210505d05c7Sgtb return profile_flush_file_to_file(profile->first_file, 211505d05c7Sgtb outfile); 212505d05c7Sgtb 213505d05c7Sgtb return 0; 214505d05c7Sgtb } 215505d05c7Sgtb 216505d05c7Sgtb errcode_t KRB5_CALLCONV 217505d05c7Sgtb profile_flush_to_buffer(profile_t profile, char **buf) 218505d05c7Sgtb { 219505d05c7Sgtb return profile_flush_file_data_to_buffer(profile->first_file->data, buf); 220505d05c7Sgtb } 221505d05c7Sgtb 222505d05c7Sgtb void KRB5_CALLCONV 223505d05c7Sgtb profile_free_buffer(profile_t profile, char *buf) 224505d05c7Sgtb { 225505d05c7Sgtb free(buf); 226505d05c7Sgtb } 227505d05c7Sgtb 228505d05c7Sgtb void KRB5_CALLCONV 229505d05c7Sgtb profile_abandon(profile_t profile) 2307c478bd9Sstevel@tonic-gate { 2317c478bd9Sstevel@tonic-gate prf_file_t p, next; 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate if (!profile || profile->magic != PROF_MAGIC_PROFILE) 2347c478bd9Sstevel@tonic-gate return; 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate for (p = profile->first_file; p; p = next) { 2377c478bd9Sstevel@tonic-gate next = p->next; 2387c478bd9Sstevel@tonic-gate profile_free_file(p); 2397c478bd9Sstevel@tonic-gate } 2407c478bd9Sstevel@tonic-gate profile->magic = 0; 2417c478bd9Sstevel@tonic-gate free(profile); 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate 244505d05c7Sgtb void KRB5_CALLCONV 245505d05c7Sgtb profile_release(profile_t profile) 2467c478bd9Sstevel@tonic-gate { 2477c478bd9Sstevel@tonic-gate prf_file_t p, next; 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate if (!profile || profile->magic != PROF_MAGIC_PROFILE) 2507c478bd9Sstevel@tonic-gate return; 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate for (p = profile->first_file; p; p = next) { 2537c478bd9Sstevel@tonic-gate next = p->next; 2547c478bd9Sstevel@tonic-gate profile_close_file(p); 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate profile->magic = 0; 2577c478bd9Sstevel@tonic-gate free(profile); 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate /* 2617c478bd9Sstevel@tonic-gate * Here begins the profile serialization functions. 2627c478bd9Sstevel@tonic-gate */ 2637c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 264505d05c7Sgtb errcode_t profile_ser_size(const char *unused, profile_t profile, 265505d05c7Sgtb size_t *sizep) 2667c478bd9Sstevel@tonic-gate { 2677c478bd9Sstevel@tonic-gate size_t required; 2687c478bd9Sstevel@tonic-gate prf_file_t pfp; 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate required = 3*sizeof(prof_int32); 2717c478bd9Sstevel@tonic-gate for (pfp = profile->first_file; pfp; pfp = pfp->next) { 2727c478bd9Sstevel@tonic-gate required += sizeof(prof_int32); 273505d05c7Sgtb required += strlen(pfp->data->filespec); 2747c478bd9Sstevel@tonic-gate } 2757c478bd9Sstevel@tonic-gate *sizep += required; 2767c478bd9Sstevel@tonic-gate return 0; 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate 279505d05c7Sgtb static void pack_int32(prof_int32 oval, unsigned char **bufpp, size_t *remainp) 2807c478bd9Sstevel@tonic-gate { 2817c478bd9Sstevel@tonic-gate (*bufpp)[0] = (unsigned char) ((oval >> 24) & 0xff); 2827c478bd9Sstevel@tonic-gate (*bufpp)[1] = (unsigned char) ((oval >> 16) & 0xff); 2837c478bd9Sstevel@tonic-gate (*bufpp)[2] = (unsigned char) ((oval >> 8) & 0xff); 2847c478bd9Sstevel@tonic-gate (*bufpp)[3] = (unsigned char) (oval & 0xff); 2857c478bd9Sstevel@tonic-gate *bufpp += sizeof(prof_int32); 2867c478bd9Sstevel@tonic-gate *remainp -= sizeof(prof_int32); 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 289505d05c7Sgtb errcode_t profile_ser_externalize(const char *unused, profile_t profile, 290505d05c7Sgtb unsigned char **bufpp, size_t *remainp) 2917c478bd9Sstevel@tonic-gate { 2927c478bd9Sstevel@tonic-gate errcode_t retval; 2937c478bd9Sstevel@tonic-gate size_t required; 2947c478bd9Sstevel@tonic-gate unsigned char *bp; 2957c478bd9Sstevel@tonic-gate size_t remain; 2967c478bd9Sstevel@tonic-gate prf_file_t pfp; 2977c478bd9Sstevel@tonic-gate prof_int32 fcount, slen; 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate required = 0; 3007c478bd9Sstevel@tonic-gate bp = *bufpp; 3017c478bd9Sstevel@tonic-gate remain = *remainp; 3027c478bd9Sstevel@tonic-gate retval = EINVAL; 3037c478bd9Sstevel@tonic-gate if (profile) { 3047c478bd9Sstevel@tonic-gate retval = ENOMEM; 3057c478bd9Sstevel@tonic-gate (void) profile_ser_size(unused, profile, &required); 3067c478bd9Sstevel@tonic-gate if (required <= remain) { 3077c478bd9Sstevel@tonic-gate fcount = 0; 3087c478bd9Sstevel@tonic-gate for (pfp = profile->first_file; pfp; pfp = pfp->next) 3097c478bd9Sstevel@tonic-gate fcount++; 310*159d09a2SMark Phalan pack_int32(PROF_MAGIC_PROFILE, &bp, &remain); 3117c478bd9Sstevel@tonic-gate pack_int32(fcount, &bp, &remain); 3127c478bd9Sstevel@tonic-gate for (pfp = profile->first_file; pfp; pfp = pfp->next) { 313505d05c7Sgtb slen = (prof_int32) strlen(pfp->data->filespec); 3147c478bd9Sstevel@tonic-gate pack_int32(slen, &bp, &remain); 3157c478bd9Sstevel@tonic-gate if (slen) { 316505d05c7Sgtb memcpy(bp, pfp->data->filespec, (size_t) slen); 3177c478bd9Sstevel@tonic-gate bp += slen; 3187c478bd9Sstevel@tonic-gate remain -= (size_t) slen; 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate } 321*159d09a2SMark Phalan pack_int32(PROF_MAGIC_PROFILE, &bp, &remain); 3227c478bd9Sstevel@tonic-gate retval = 0; 3237c478bd9Sstevel@tonic-gate *bufpp = bp; 3247c478bd9Sstevel@tonic-gate *remainp = remain; 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate return(retval); 3287c478bd9Sstevel@tonic-gate } 3297c478bd9Sstevel@tonic-gate 330505d05c7Sgtb static int unpack_int32(prof_int32 *intp, unsigned char **bufpp, 331505d05c7Sgtb size_t *remainp) 3327c478bd9Sstevel@tonic-gate { 3337c478bd9Sstevel@tonic-gate if (*remainp >= sizeof(prof_int32)) { 3347c478bd9Sstevel@tonic-gate *intp = (((prof_int32) (*bufpp)[0] << 24) | 3357c478bd9Sstevel@tonic-gate ((prof_int32) (*bufpp)[1] << 16) | 3367c478bd9Sstevel@tonic-gate ((prof_int32) (*bufpp)[2] << 8) | 3377c478bd9Sstevel@tonic-gate ((prof_int32) (*bufpp)[3])); 3387c478bd9Sstevel@tonic-gate *bufpp += sizeof(prof_int32); 3397c478bd9Sstevel@tonic-gate *remainp -= sizeof(prof_int32); 3407c478bd9Sstevel@tonic-gate return 0; 3417c478bd9Sstevel@tonic-gate } 3427c478bd9Sstevel@tonic-gate else 3437c478bd9Sstevel@tonic-gate return 1; 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 347505d05c7Sgtb errcode_t profile_ser_internalize(const char *unused, profile_t *profilep, 348505d05c7Sgtb unsigned char **bufpp, size_t *remainp) 3497c478bd9Sstevel@tonic-gate { 3507c478bd9Sstevel@tonic-gate errcode_t retval; 3517c478bd9Sstevel@tonic-gate unsigned char *bp; 3527c478bd9Sstevel@tonic-gate size_t remain; 3537c478bd9Sstevel@tonic-gate int i; 3547c478bd9Sstevel@tonic-gate prof_int32 fcount, tmp; 3557c478bd9Sstevel@tonic-gate profile_filespec_t *flist = 0; 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate bp = *bufpp; 3587c478bd9Sstevel@tonic-gate remain = *remainp; 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate if (remain >= 12) 3617c478bd9Sstevel@tonic-gate (void) unpack_int32(&tmp, &bp, &remain); 3627c478bd9Sstevel@tonic-gate else 3637c478bd9Sstevel@tonic-gate tmp = 0; 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate if (tmp != PROF_MAGIC_PROFILE) { 3667c478bd9Sstevel@tonic-gate retval = EINVAL; 3677c478bd9Sstevel@tonic-gate goto cleanup; 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate (void) unpack_int32(&fcount, &bp, &remain); 3717c478bd9Sstevel@tonic-gate retval = ENOMEM; 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate flist = (profile_filespec_t *) malloc(sizeof(profile_filespec_t) * (fcount + 1)); 3747c478bd9Sstevel@tonic-gate if (!flist) 3757c478bd9Sstevel@tonic-gate goto cleanup; 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate memset(flist, 0, sizeof(char *) * (fcount+1)); 3787c478bd9Sstevel@tonic-gate for (i=0; i<fcount; i++) { 3797c478bd9Sstevel@tonic-gate if (!unpack_int32(&tmp, &bp, &remain)) { 3807c478bd9Sstevel@tonic-gate flist[i] = (char *) malloc((size_t) (tmp+1)); 3817c478bd9Sstevel@tonic-gate if (!flist[i]) 3827c478bd9Sstevel@tonic-gate goto cleanup; 3837c478bd9Sstevel@tonic-gate memcpy(flist[i], bp, (size_t) tmp); 3847c478bd9Sstevel@tonic-gate flist[i][tmp] = '\0'; 3857c478bd9Sstevel@tonic-gate bp += tmp; 3867c478bd9Sstevel@tonic-gate remain -= (size_t) tmp; 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate } 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate if (unpack_int32(&tmp, &bp, &remain) || 3917c478bd9Sstevel@tonic-gate (tmp != PROF_MAGIC_PROFILE)) { 3927c478bd9Sstevel@tonic-gate retval = EINVAL; 3937c478bd9Sstevel@tonic-gate goto cleanup; 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate 396505d05c7Sgtb if ((retval = profile_init((const_profile_filespec_t *) flist, 397505d05c7Sgtb profilep))) 3987c478bd9Sstevel@tonic-gate goto cleanup; 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate *bufpp = bp; 4017c478bd9Sstevel@tonic-gate *remainp = remain; 402505d05c7Sgtb 4037c478bd9Sstevel@tonic-gate cleanup: 4047c478bd9Sstevel@tonic-gate if (flist) { 4057c478bd9Sstevel@tonic-gate for (i=0; i<fcount; i++) { 4067c478bd9Sstevel@tonic-gate if (flist[i]) 4077c478bd9Sstevel@tonic-gate free(flist[i]); 4087c478bd9Sstevel@tonic-gate } 4097c478bd9Sstevel@tonic-gate free(flist); 4107c478bd9Sstevel@tonic-gate } 4117c478bd9Sstevel@tonic-gate return(retval); 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate errcode_t 4167c478bd9Sstevel@tonic-gate profile_get_options_boolean(profile, section, options) 4177c478bd9Sstevel@tonic-gate profile_t profile; 4187c478bd9Sstevel@tonic-gate char ** section; 4197c478bd9Sstevel@tonic-gate profile_options_boolean *options; 4207c478bd9Sstevel@tonic-gate { 4217c478bd9Sstevel@tonic-gate char ** actual_section; 4227c478bd9Sstevel@tonic-gate char * value = NULL; 4237c478bd9Sstevel@tonic-gate errcode_t retval = 0; 4247c478bd9Sstevel@tonic-gate int i, max_i; 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate for (max_i = 0; section[max_i]; max_i++); 4277c478bd9Sstevel@tonic-gate if (actual_section = (char **)malloc((max_i + 2) * sizeof(char *))) { 4287c478bd9Sstevel@tonic-gate for (actual_section[max_i + 1] = NULL, i = 0; section[i]; i++) 4297c478bd9Sstevel@tonic-gate actual_section[i] = section[i]; 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate for (i = 0; options[i].name; i++) { 4327c478bd9Sstevel@tonic-gate if (options[i].found) continue; 4337c478bd9Sstevel@tonic-gate actual_section[max_i] = options[i].name; 4347c478bd9Sstevel@tonic-gate retval = profile_get_value(profile, (const char **) actual_section, 4357c478bd9Sstevel@tonic-gate (const char **)&value); 4367c478bd9Sstevel@tonic-gate if (retval && (retval != PROF_NO_RELATION) && 4377c478bd9Sstevel@tonic-gate (retval != PROF_NO_SECTION)) { 4387c478bd9Sstevel@tonic-gate free(actual_section); 4397c478bd9Sstevel@tonic-gate return(retval); 4407c478bd9Sstevel@tonic-gate } 4417c478bd9Sstevel@tonic-gate if ((retval == 0) && value) { 4427c478bd9Sstevel@tonic-gate /* 4437c478bd9Sstevel@tonic-gate * Any string other than true will turn off the 4447c478bd9Sstevel@tonic-gate *option 4457c478bd9Sstevel@tonic-gate */ 4467c478bd9Sstevel@tonic-gate if (strncmp(value,"true",4) == 0) 4477c478bd9Sstevel@tonic-gate *(options[i].value) = 1; 4487c478bd9Sstevel@tonic-gate else 4497c478bd9Sstevel@tonic-gate *(options[i].value) = 0; 4507c478bd9Sstevel@tonic-gate options[i].found = 1; 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate } 4537c478bd9Sstevel@tonic-gate } 4547c478bd9Sstevel@tonic-gate free(actual_section); 4557c478bd9Sstevel@tonic-gate } else { 4567c478bd9Sstevel@tonic-gate retval = ENOMEM; 4577c478bd9Sstevel@tonic-gate } 4587c478bd9Sstevel@tonic-gate return(retval); 4597c478bd9Sstevel@tonic-gate } 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate errcode_t 4627c478bd9Sstevel@tonic-gate profile_get_options_string(profile, section, options) 4637c478bd9Sstevel@tonic-gate profile_t profile; 4647c478bd9Sstevel@tonic-gate char ** section; 4657c478bd9Sstevel@tonic-gate profile_option_strings *options; 4667c478bd9Sstevel@tonic-gate { 4677c478bd9Sstevel@tonic-gate char ** actual_section; 4687c478bd9Sstevel@tonic-gate char * value = NULL; 4697c478bd9Sstevel@tonic-gate errcode_t retval = 0; 4707c478bd9Sstevel@tonic-gate int i, max_i; 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate for (max_i = 0; section[max_i]; max_i++); 4737c478bd9Sstevel@tonic-gate if (actual_section = (char **)malloc((max_i + 2) * sizeof(char *))) { 4747c478bd9Sstevel@tonic-gate for (actual_section[max_i + 1] = NULL, i = 0; section[i]; i++) 4757c478bd9Sstevel@tonic-gate actual_section[i] = section[i]; 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate for (i = 0; options[i].name; i++) { 4787c478bd9Sstevel@tonic-gate if (options[i].found) continue; 4797c478bd9Sstevel@tonic-gate actual_section[max_i] = options[i].name; 4807c478bd9Sstevel@tonic-gate retval = profile_get_value(profile, (const char **) actual_section, 4817c478bd9Sstevel@tonic-gate (const char **)&value); 4827c478bd9Sstevel@tonic-gate if (retval && (retval != PROF_NO_RELATION) && 4837c478bd9Sstevel@tonic-gate (retval != PROF_NO_SECTION)) { 4847c478bd9Sstevel@tonic-gate free(actual_section); 4857c478bd9Sstevel@tonic-gate return(retval); 4867c478bd9Sstevel@tonic-gate } 4877c478bd9Sstevel@tonic-gate if ((retval == 0) && value) { 4887c478bd9Sstevel@tonic-gate *options[i].value = malloc(strlen(value)+1); 4897c478bd9Sstevel@tonic-gate if (*options[i].value == 0) 4907c478bd9Sstevel@tonic-gate retval = ENOMEM; 4917c478bd9Sstevel@tonic-gate strcpy(*options[i].value, value); 4927c478bd9Sstevel@tonic-gate options[i].found = 1; 4937c478bd9Sstevel@tonic-gate } else 4947c478bd9Sstevel@tonic-gate *options[i].value = 0; 4957c478bd9Sstevel@tonic-gate } 4967c478bd9Sstevel@tonic-gate free(actual_section); 4977c478bd9Sstevel@tonic-gate } else { 4987c478bd9Sstevel@tonic-gate retval = ENOMEM; 4997c478bd9Sstevel@tonic-gate } 5007c478bd9Sstevel@tonic-gate return(retval); 5017c478bd9Sstevel@tonic-gate } 502